说到重,Ember 其实比 Angular 重多了。Angular 比较好拆分或组装,Ember 则不然(当然也可以,但是相较于 Angular,Ember 更是一个有机的整体)。至于你的 MEEN,我反而觉得没有 MEAN 更加必要,MEAN 的主要意义就在于 Angular 比之 Ember 更加灵活。好比说 Data Store 这一层,你可以很容易实现一套自己的,基于 ngResource,甚至是 $httpProvider,在加上 Cache 层就基本上等同于 Ember Data 了;就算你懒得或不会,也有很多第三方的实现拿来就用。而 Ember 呢?虽然也有第三方的实现,但都不如 Ember Data(or eventually)。再比如说 Router,ngRouter 不够好,但是没关系不用就是了(ngRouter 是独立的组件可以直接替换掉),换成——比如说 ui-router 或其他的什么。但是 Ember 呢?你能很轻易的把 Router 从中间扣掉换成别的吗?
当然,这只是举例说明 Angular 作为 Toolset 而不是 Framework 的灵活性,倒不是说 Angular 就一定比 Ember 强。拿 Router 层来说,Ember Router 比 Angular 及其第三方的 ui-router 都要好得多;Component 也比 Directive 更加友好(至少个人认为如此,用 WebComponent 做参照物的话,明显 Ember 的实现更胜一筹)灵活的双向绑定(也就是说双向/单向/复杂依赖等等的灵活性和 API 友好性),我也更偏爱 Ember。Angular 直到最近 1.3 才实现了“补丁版”的单向绑定,扩充的语法让人蛋疼……而对于 ES6 的友好性,目前 Ember 也领先于 Angular(Angular 2.0 之后再看)更不用说杀手级的 Ember CLI(Yeoman 比之简直是小儿科)。另外,两者都有皆不如意的地方,比如 View 这一层就难以匹敌风头正劲的 React,然而 Angular 整合 React 却比 Ember 要更简单更方便。
以上,我不觉得非要把 Ember 安排进一个“套路”(比如 MEEN)有什么特别的好处或便利性。Ember 的一体化有机化的系统设计使得它可以很好的,很“均等”的适应各种 Stacks,它本身就有相当完备的“生态系统”。MEEN 比其他的——比如说 Ember + EmberCli + Any Backend API + Any DB——没有任何明显的优势。唯一可说的就是 ALL JavaScript?对于 FullStack Developer 来说,这个重要吗?
如果方案前后分离,那么我觉得 ember 是目前最好的选择。 Ember CLI 我觉得吸引力不大,broccoli,gulp 都能自己写个够用的,也不麻烦
一直听到 React 好,好在哪里呢?麻烦能简单解释一下吗? 我一直对这种 component 似的 view 层理解不了,感觉不能好好写 html 了。。
#3 楼 @serco 只谈前后分离,这是一种架构上的选择,Ember 是最好的选择?那要看情况,具体什么情况很难三言两语讲清楚。就好像 Angular vs Ember,我也喜欢后者更多,但是我不一定会每次都选择 Ember。具体的因素可能会有很多,比如“重量级”会是其中之一。
这个问题应该这样总结:
我选择前后分离,是出于架构上的选择,而不是出于我要使用 Ember 或其他的框架。出于架构选择即意味着我将受益于前后分离给我带来的好处:比如说项目管理上的透明性/灵活性;比如说实现一套 API 可以适用于多个客户端;比如说平衡 C/S 两端的负载等等……但绝不是因为我要使用 Ember 或其他的什么。
因此,如果选择前后分离,和 Ember 是否为最佳方案,这两者是没有必然的因果关系的。
举例来说,我要搞一个个人网站,类似博客。我决定采用前后分离是出于可能的两个原因(这里是举例):一、我有一个小伙伴帮我写 Backend API,他完全不懂前端,我也搞不明白他用的后端技术,所以我们决定在项目结构上让前后完全解耦,互不干涉;二、除了 Web 端,我还想在移动端的几个平台上尝试一下,所以一套 API 满足我几个应用端的需求是一个很好地选择。
然而,尽管我喜欢 Ember,但是 Web 这边一定要用它吗?未必。首先,一个博客类的 Web 应用没有必要非得 SPA;其次,对于这种类型的应用 Ember 明显太重了,值得吗?我很怀疑。
关于 Ember CLI,我觉得你不够了解它,如果它只是像 Yeoman 那样梳理出一套自动构建体系我就不会过多提它了。Yeoman 选择了 Grunt,Ember CLI 则用了 Broccoli(技术上说,Grunt/Gulp 是 Task Runner 而 Broccoli 是 Build Tool,它们是有区别的。好比 Ruby 世界里 Rake 和 Assets Pipeline 的区别),但是若仅仅如此也没有必要说 Yeoman 太小儿科了。我觉得你还是好好地研究一下 Ember CLI 再说吧,至少通读一遍官网的文档(目前还不算多,正在不断补充)再下定论,总而言之并非你现在说的那么简单。
React,如果只说一件事情关于它的优势,那就捡 Virtual DOM 来说吧。简单地说,无论 DOM 的变化多么复杂,React 的机制是把所有繁复的操作“封装”在一个看起来很像真实 DOM 的 Virtual DOM 里(当然,给你提供的 API 还是很简单的,所以实际写代码也很简单),当产生变化的时候,React 使用类似于 Git 的 diff 算法来比较前后的差异,于是可以很高效的只更新变化的部分,最后一次性的把 Virtual DOM 替换成真正的 DOM。我们都知道最影响性能的就是操作 DOM,React 则把操作 DOM 这件事情进化成理论上的最优方案,所以才可以在性能上产生令人惊叹的结果。这一点是目前的 Angular 也好,Ember 也罢,任何一个涉及到操作 DOM 的 JS 工具都无法媲美的。
但是这不是 React 的全部,鉴于我自己也还在学习于摸索阶段就不继续献丑了。
WebComponent 是一种若干先进技术和概念性技术的结合产物,无论是 Angular 的 Directive,还是 Ember 的 Component,甚至是 React 自己,或多或少都是在某种程度上对于 WebComponent 的一种实现。它解决的不是一个问题(比如说 View 层),而是许许多多问题的综合解决方案。比如说高度可定制化的自定义标签;对于复杂结构的良好封装(基于 Shadow DOM)从而实现非常灵活的可重用性;具备分离作用域的样式封装(想想 Sass/Less/Stylus……主要做的事情);提供具备完整生命周期和交互接口的脚本封装;灵活的模板系统,原生支持的模板导入。
可以设想若是 WebComponent 实现良好,浏览器支持也完备,那么我们可以丢弃很多现存的第三方解决方案,比如说支持数据绑定的模板系统;比如说 CSS 的预处理器等等。我们也可以获得很多更先进更方便的模块化组件,它们可以纯视觉化的设计和实现,它们可以拿来就用,直接提供各种对外的编程接口(相比通过 DOM 编程实在是繁琐 + 低效),也可以在不用考虑耦合/继承等带来的副作用的前提下去修改结构、样式、行为。对于高度模块化和可重用化的 web 开发提供了浏览器级别的原生支持。
太多的东西很难用语言去描述它的优点和前景,我建议你还是多多 Google 一下看看一些完整的资料和例子,比如说 Youtube 上 Google Developer 频道有很多关于 WebComponent 的视频,好好看看。
我说前后分离时选择 ember 较好,是假设前端会是非常重的 SPA 的情况,并非选定 Ember 才考虑要实施前后分离。 Ember CLI 之前很粗略的浏览了下,以为只是提供了构建、ES6 模块代码封装和 generator 而已,哲学上又是类似 rails 的约定大于配置,而我本身的需求没有那么复杂就没有细看。
关于 component,先前看到 google 的 polymer 出来时就已经很好奇了,确实应该花些时间研究一下。
@serco @nightire 说的已经挺好了,补充一点关于 Ember CLI 的。
前端开发用一些工具去自动化流程已经很常见了,Grunt, Gulp, Brunch, Broccoli, Yeoman, Lineman... 用这些工具去写点脚本自动化流程是很方便,但每个项目都会有自己的一套流程,gruntfile.js 这种配置也已经成了项目代码的一部分。时间长了就会有几个问题:
Ember CLI 的目的是做一个平台,既然大多数 Ember 项目都需要这些流程,并且都差不多,那就没必要在项目中去重复。你不需要操心这些琐碎的东西,也不用关心细节是怎么实现的。不管你是需要加入 CoffeeScript, SASS,设置 proxy 或者 mock API,或者装一个 library,部署到 Heroku,你只需要记住:
npm install --save-dev ember-cli-xxx-addon
和定期升级 Ember CLI:
npm install --save-dev [email protected]
就行了。就像 Ruby 世界扩展功能很多时候只需要 gem install
一样,不管功能是什么方面的。
BTW Ember CLI 是我唯一一个碰到的在开发中,不管添加,修改,删除文件,甚至 bower install 都不需要重启 development server 的工具。这应该得感谢 Broccoli。
#6 楼 @darkbaby123 嗯,顺着你的例子说一点。之前还有一个痛点,那就是组件化的过程。像 Angular/Ember 这样的东西提供了很多机制帮助我们封装可重用的组件,问题是封装完了之后如何分发?如何管理?如何升级?
虽然 npm 包括 bower 等在内都可以在一定程度上解决这个问题,但归根结底它们都是通用化的平台,在很多具体的开发中它们并不能彻底帮助开发者消除痛苦。比如说你使用 Angular 封装一个插件,你通过 npm/bower 去分发它,别人或许找到或许没找到,找到的或许知道如何下载如何使用也或许完全没有概念,如果他们有能力改善它但由于组件化本身缺乏标准,每个人都有自己的一套,所以也不见得很容易……等等等等,总之问题多多。
Ember CLI 定义了一套 Addon 的规范和机制,你可以很轻松的开发出可重用的各种组件——不仅仅是插件,任何组件都可以,甚至包括命令行的命令扩展都没有问题。所有的这些组件都遵循统一的代码结构,统一的文件组织,统一的分发与管理机制,统一的使用方式。对于其他人来说,重用组件几乎就是一个没有代价的事情。当 Ember 的整个生态圈大到一定规模的时候,你就能体会到今天定义一套统一的 Addon 机制是多么有远见的事情!
@nightire 谢谢 nightire 写了这么多。 angular 学了个 guide, 没真正用过,不过我觉得 ember 已经够好了,用起来很爽,之前的坑其实主要在 ember-data 这块,非 restful 的方法要自己写请求,处理数据,处理 hasMany 及 多态等,现在搞清楚了 sideload 和 json api, 以及 store 的机制,已经没有啥问题。
前端这么多 js, ember-cli 也是 js, 大量依赖于 json 以及 回调,异步,很自然而然的,后台也想用 node 和 mongo 了,个人觉得这才是一个自洽的,哲学统一的体系,如果说 LAMP 是一代,ROR 是二代的话,MEEN 或者 MEAN 等引入前端 mvc 的应该是三代了。
借助 ember-cli, ember 可以做到举重若轻,无论布局,css, 还是路由,事件处理等,前端写起来比 lamp 或 ror 都顺手和快; 很多统计表面,即使 ror 的项目,js 的代码量也会占到 30% - 50%, 这已经是一个 重前端 的时代。而我个人本来 rails 就是半吊子,所以我就不犹豫,拥抱 MEEN 啦~
看了大家的分享,真的很受用,俺的小项目,前端就是基于 ember-cli,后台基于 padrino(grape),开发体验就叫一个爽,去 rails 化已经是趋势。项目地址 https://github.com/onecoinim 其中 api.onecoin.im 是后台 padrino 管理系统,website.onecoin.im 是前端 ember-cli 项目,欢迎批评。。。