{"action":"created","issue":{"url":"https://api.github.com/repos/xufei/blog/issues/24","labels_url":"https://api.github.com/repos/xufei/blog/issues/24/labels{/name}","comments_url":"https://api.github.com/repos/xufei/blog/issues/24/comments","events_url":"https://api.github.com/repos/xufei/blog/issues/24/events","html_url":"https://github.com/xufei/blog/issues/24","id":116287598,"number":24,"title":"未来Web应用的前端技术选型畅想","user":{"login":"xufei","id":2725159,"avatar_url":"https://avatars.githubusercontent.com/u/2725159?v=3","gravatar_id":"","url":"https://api.github.com/users/xufei","html_url":"https://github.com/xufei","followers_url":"https://api.github.com/users/xufei/followers","following_url":"https://api.github.com/users/xufei/following{/other_user}","gists_url":"https://api.github.com/users/xufei/gists{/gist_id}","starred_url":"https://api.github.com/users/xufei/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xufei/subscriptions","organizations_url":"https://api.github.com/users/xufei/orgs","repos_url":"https://api.github.com/users/xufei/repos","events_url":"https://api.github.com/users/xufei/events{/privacy}","received_events_url":"https://api.github.com/users/xufei/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":20,"created_at":"2015-11-11T08:21:56Z","updated_at":"2015-11-11T14:25:52Z","closed_at":null,"body":"上半年，我写过一篇[《2015前端组件化框架之路》](https://github.com/xufei/blog/issues/19)，现在大半年过去了，这段时间一直在思考，未来的东西是怎样的。\r\n\r\n目前我主导着苏宁的云计算相关的所有前端项目，这些项目以控制台为主，几乎都广泛使用了Angular 1.x，一方面因为个人技能之前有积累，一方面因为产品的开发人员基本都是Java方向转岗，对Angular的接受度较高，上手非常快，开发效率也非常高。\r\n\r\n但2015年，前端的世界发生了很多变化，这些变化快得超出我想象。在这个巨变的时代，产品的技术选型是个麻烦的事情，具体来说，有几个方面：\r\n\r\n- 如果2-3年后新开始一个业务项目，可能会有什么样的技术方案？\r\n- 如果现在立刻开始一个新业务项目，可能会有什么样的技术方案？\r\n- 如果持续维护老的项目，后面可能会对它们有怎样的迁移方案？是逐步迁移，还是推倒重做？\r\n- 在PC端项目为主体的业务体系里，如果将来某个时机出现了移动端项目，该如何去选型，并且利用之前的业务代码？\r\n\r\n我之前没有预料到的，是ES6的普及之快。在此之前，对于新的语言特性，人们一般会等到支持的浏览器普及之后，才会大量使用，比如ES5，但由于Babel这样转译的工具出现，我们可以渐进使用，所以，开发过程中可以完全使用ES6甚至ES7的特性编写代码，然后通过构建去达到兼容的结果。\r\n\r\n有鉴于此，在未来的项目中，使用ES语言新特性进行开发，是一个必然要做的事情。但，这并不能算是整体方案。整体的方案应当包括但不限于：\r\n\r\n- 使用什么基础框架\r\n- 业务代码如何规划\r\n- UI组件如何规划\r\n- 样式和主题如何规划\r\n- 构建方案怎样\r\n- 人员如何协作\r\n- ……\r\n\r\n所以，我们面临的，还是基础框架选型这么一个重大问题。照理说，使用Angular 1.x，后续应当选择往2.0版本过渡，但现在这个阶段，乱花迷人眼，谁也不知道未来的事情怎样，在这一层上，我个人觉得还是要再看看。\r\n\r\n于是就卡在这里了，这个选不了，后面的事情都没法考虑做了吗？\r\n\r\n也不尽然，我考虑了一段时间，觉得虽然每个层面都比较麻烦，但至少可以分层隔离一下。比如说，我们选了某个UI层的组件化框架，并不意味着对下层的数据模型和业务逻辑就有很强约束，至少说，这层还是有很多可选方案。\r\n\r\n通常我们在前端，可以对一个Web应用这样分层：\r\n\r\nUI层（View） -- 业务逻辑层（ViewModel / Controller） -- 数据层（Model）\r\n\r\n比如说，数据层，有Relay，有GraphQL，有Falcor，但我们还可以继续使用原先的RESTful API啊。我们可以不使用某框架自带的请求库，比如$.get，比如$http，但我们还可以使用super agent这样独立的，框架无关的辅助请求库啊。甚至说，我们不想使用XHR了，还可以使用Fetch啊。\r\n\r\n所以，把Web应用的前端先分层一看，发现每个层里面，都有很多独立的可选方案，而这些方案是可以组合的，比如说：\r\n\r\n上层用React，下层用Falcor或者RESTful，然后把上层换成Vue，好像也没有什么不对啊？下层完全可以不动，也不需要就把每层代码都改一遍啊？\r\n\r\n这样一来，我们可以先不管UI层，直接先把下面两层全部构建出来，这个部分不对DOM产生任何依赖，所以，跟上层框架没有关系，也无需按照上层框架的约定。\r\n\r\n我们引入一个框架，对整个系统来说，最大的影响是会产生一些约定。有时候我们需要这些约定来帮我们规范代码，但在现在这种形势下，会尽可能希望框架本身不要产生约定，由我们自己，按照ES自身的一些机制来形成代码规范。\r\n\r\n比如说，我们使用module，class之类的语法特性，基于传统的OO方法论进行一些规划，利用各种设计模式。或者，我们也可以基于函数式的理念，进行另外一个方向的规划。总之，这个层面的东西是纯业务的，可测试的，可独立运行的。\r\n\r\n在构建模型层和业务逻辑层的过程中，我们可以使用ES6，也可以使用TypeScript。之前我曾经有个断言：如果ES6普及得快，TS的形势就会不太好。这主要是因为考虑到如果一个开发者已经在使用ES6，他去使用TS的可能性并不会很大，而如果他到ES6流行的时候尚未接触TS，后面接触TS的可能性就比较小，直接用ES6的可能性比较多。\r\n\r\n不过，当业务逻辑比较复杂的时候，使用TS会有一些优势。即使不使用TS，我也建议把数据模型预先定义出来，在实体类里面做一些事情，尽可能使用实体类来构建数据，而不是直接用字面量来定义。当应用规模变大的时候，“严谨性”变得更加重要。\r\n\r\n另外一个角度，如果我们要尽可能构建框架中立的业务逻辑层代码，最好是脱离上层框架的绑定监控机制，自己通过比如getter，setter这样的方式，实现数据模型的内部联动，所以从这个角度，预定义数据模型也是必要的。\r\n\r\n在这个基础上，再回到我们的现实来，在文章开头，我提出了几个要考虑的可能，现在可以逐一回答了：\r\n\r\n**1. 如果2-3年后新开始一个业务项目，可能会有什么样的技术方案？**\r\n\r\n底层如上所述，上层根据当时情况判断选择\r\n\r\n**2. 如果现在立刻开始一个新业务项目，可能会有什么样的技术方案？**\r\n\r\n底层如上所述，上层使用Angular 1.4或者Vue之类的成熟框架，同时，使用ES6开发\r\n\r\n**3. 如果持续维护老的项目，后面可能会对它们有怎样的迁移方案？是逐步迁移，还是推倒重做？**\r\n\r\n先逐步重构，维持UI层框架不变，把底层重构成上述那样，然后引入ES6，先搞成方案2这样，后续再考虑迁移上层。\r\n\r\n**4. 在PC端项目为主体的业务体系里，如果将来某个时机出现了移动端项目，该如何去选型，并且利用之前的业务代码？**\r\n\r\n先把PC端重构如方案3，然后，PC端可继续使用Angular，移动端上层选用Vue之类性能较好的轻量库，PC端与移动端共用业务逻辑层。\r\n\r\n以前有一段时间，我一直觉得Angular的all in one是一种挺好的策略，但最近考虑了很多事情之后，觉得将来这种方案的优势会逐渐削弱，所以，现在我也觉得纯粹做上层视图框架的Vue之类有不少好处。在未来，约束越强的框架很可能越不受欢迎，基于ES自身的语言特性做业务代码约束才是王道。\r\n\r\n这篇主要是比较笼统地谈一些想法，后面会写两篇具体细节策略的考虑。"},"comment":{"url":"https://api.github.com/repos/xufei/blog/issues/comments/155796522","html_url":"https://github.com/xufei/blog/issues/24#issuecomment-155796522","issue_url":"https://api.github.com/repos/xufei/blog/issues/24","id":155796522,"user":{"login":"liuhaimingcn","id":9984608,"avatar_url":"https://avatars.githubusercontent.com/u/9984608?v=3","gravatar_id":"","url":"https://api.github.com/users/liuhaimingcn","html_url":"https://github.com/liuhaimingcn","followers_url":"https://api.github.com/users/liuhaimingcn/followers","following_url":"https://api.github.com/users/liuhaimingcn/following{/other_user}","gists_url":"https://api.github.com/users/liuhaimingcn/gists{/gist_id}","starred_url":"https://api.github.com/users/liuhaimingcn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/liuhaimingcn/subscriptions","organizations_url":"https://api.github.com/users/liuhaimingcn/orgs","repos_url":"https://api.github.com/users/liuhaimingcn/repos","events_url":"https://api.github.com/users/liuhaimingcn/events{/privacy}","received_events_url":"https://api.github.com/users/liuhaimingcn/received_events","type":"User","site_admin":false},"created_at":"2015-11-11T14:25:52Z","updated_at":"2015-11-11T14:25:52Z","body":"膜拜……"}}