<audio id="audio" title="第184讲 | 狼叔：2019年前端和Node的未来—大前端篇（上）" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/c0/f0/c03556c1ce930dafba4a37f28930c7f0.mp3"></audio>

你好，我是阿里巴巴前端技术专家狼叔，今天想跟你分享2019年我对前端和Node现状及未来发展趋势的理解。

我其实特别反感很多人说“前端娱乐圈”这种话，诚然，爆发式增长必然会带来焦点，但也不必过度解读，2018年的几件大事儿我都了解，真的不是大家看到的那样的。学会辩证的看问题，用心去体味背后的趋势，我想这比所谓的“正直”更有价值，我更希望大家能够坚持学习，保持思辨和平和。

## 大前端

2018年的事儿特别多，从React v16普及，到jQuery被GitHub下掉完成阶段性历史使命，在唏嘘之外，版本帝Angular又发布了v6和v7两个版本。这些其实都不算啥大新闻，反观三大框架，写法越来越像，越来越贴近WebComponents标准，而周边应用层面的封装已经开始指数级增长。小程序是今年最火的技术，接连出现，快应用也想分一杯羹。PWA进入稳定期，尤其是PWA桌面版，可以让我们更好的看清楚PC桌面版开发的全貌。移动端还是以强运营为主，各大公司都开始不再all in移动，开始重视多端并进，到了开始拼细节的阶段了。TypeScript全面开花，GraphQL蠢蠢欲动，WebAssembly更是打开了浏览器上多语言的大门。所有的这一切都在暗示，浏览器即操作系统，你能想象到未来前端的样子么？下面跟着我一一进行解读吧。

### 三大框架标准化

有朋友吐槽：“Vue的特点就是上手快，初期相当好用，但如果接手一个别人写的 Vue 项目，再和 React 对比一下，你会感谢 React 的”。但当Vue 3.0发布之后，估计他就不会这样说了。因为Vue 3的Class API 和 React 的写法几乎是一模一样的，这个改动不是 Proxy 和 TypeScript，而是支持原生 Class 的写法。你用 Class 来写，那代码和 React 写法几乎是一模一样的！

```
import Vue from 'vue'

class App extends Vue.Component {
  count = 0

  up() {
    this.count++
  }

  down() {
    this.count--
  }

  render() {
    return (
      &lt;div&gt;
        &lt;h1&gt;{this.count}&lt;/h1&gt;
        &lt;button onClick={() =&gt; this.up()}&gt;+&lt;/button&gt;
        &lt;button onClick={() =&gt; this.down()}&gt;-&lt;/button&gt;
      &lt;/div&gt;
    )
  }
}

Vue.render(&lt;App /&gt;, document.body as HTMLElement)

```

从上面的讨论可以看出，前端三大框架已经趋于平稳化、标准化，在我看来未来是WebComponents的。

WebComponents是规范，最早最知名的一个是 Google 主推的JavaScript 库Polymer，它可帮助我们创建自定义的可重用 HTML 元素，并使用它们来构建高性能、可维护的 App。在 I/O 大会上，Google 推出了 Polymer 3.0，Polymer 3.0 致力于将 Web 组件的生态系统从 HUML Imports 转移到 ES Modules，包管理系统将支持 npm，这使你更容易将基于 Polymer 的 Web 组件和你喜欢的工具、框架协同使用。

```
 &lt;script src="node_modules/@webcomponents/webcomponents-loader.js"&gt;&lt;/script&gt;
  &lt;script type="module"&gt;
    import {PolymerElement, html} from '@polymer/polymer';

    class MyElement extends PolymerElement {
      static get properties() { return { mood: String }}
      static get template() {
        return html`
          &lt;style&gt; .mood { color: green; } &lt;/style&gt;
          Web Components are &lt;span class="mood"&gt;[[mood]]&lt;/span&gt;!
        `;
      }
    }

    customElements.define('my-element', MyElement);
  &lt;/script&gt;

  &lt;my-element mood="happy"&gt;&lt;/my-element&gt;

```

另外还有2个项目具有一定的参考价值：

1.Rax也提供了一个名为[atag](https://github.com/alibaba/rax/tree/master/packages/atag)的UI WebComponents库。<br>
2.LitElement是一个简单的轻量级的快速创建WebComponents的基类，可以理解成是Polymer最小的实现版本。

LitElement主要的特性包括WebComponent生命周期模型支持和单向的数据绑定模型。它遵守 WebComponents 标准，使用lit-html模块这个快速的HTML渲染引擎定义和渲染HTML模板。最重要的是它对浏览器兼容性非常好，对主流浏览器都能有非常好的支持。由于LitHtml基于tagged template，结合ES6中的template，使得它无需预编译、预处理，就能获得浏览器原生支持，并且扩展能力更强，性能更好。

```
import { LitElement, html } from '@polymer/lit-element'; 

// Create your custom component
class CustomGreeting extends LitElement {
  // Declare properties
  static get properties() {
    return {
      name: { type: String }
    };
  }
  // Initialize properties
  constructor() {
    super();
    this.name = 'World';
  }
  // Define a template
  render() {
    return html`&lt;p&gt;Hello, ${this.name}!&lt;/p&gt;`;
  }
}

// Register the element with the browser
customElements.define('custom-greeting', CustomGreeting);

```

是不是看着更眼熟了？

《三国演义》里有这样一句：“话说天下大势，分久必合，合久必分。周末七国分争，并入于秦。及秦灭之后，楚、汉分争，又并入于汉。汉朝自高祖斩白蛇而起义，一统天下，后来光武中兴，传至献帝，遂分为三国。”

前端从2014年到2017年是混战期，得益于Node.js的辅助加成，外加各种前端优秀的创意和实践，使得React/Vue/Angular三足鼎立。无论React发布v16，增加Fiber和Hooks，还是Vue 3.0发布，其实最终都是朝着W3C WebComponents标准走。一言以蔽之，Follow标准是趋势，如果能够引领标准，那将是框架的无上荣耀。

我们可以参考一下技术成熟度曲线（Hype Cycle -Wikipedia），这个曲线把技术发展分成五个步骤：【科技诞生的促动期】-&gt;【过高期望的峰值】-&gt; 【泡沫化的底谷期】 -&gt; 【稳步爬升的光明期】 -&gt; 【实质生产的高原期】。从前端现在的热度来看，应该是处于从第三阶段【泡沫化的底谷期】到第四阶段【稳步爬升的光明期】的爬坡过程，创新不会那么多，更多的是偏于应用层的内容。

<img src="https://static001.geekbang.org/resource/image/e6/0b/e62c58b2f80d2c079ea0bd373fe91b0b.jpg" alt="">

对于当下的前端发展情况，我其实是有隐忧的。当年Java世界曾经搞各种GUI，创造了MVC模式，结果没火，没想到到了Web开发领域，MVC成了基本约定。之后Model 1和Model 2等企业开发模型渐渐成熟，出现了Struts、Spring、Hibernate三大框架。在之后很长的一段时间里，Java程序员都是言必称“SSH”。再之后Spring一家独大，一统江湖，恐怕今天还记得 EJB 的人已经不多了。框架一旦稳定，就会有大量培训跟进，导致规模化开发。这是把双刃剑，能满足企业开发和招人的问题，但也给创新探索领域上了枷锁。

### 应用层封装进入爆发期

框架和工程化基本探索稳定后，大家就开始思考如何更好的用，更简单的用。目前，各家大厂都在前端技术栈思考如何选型和降低成本，统一技术栈。

举个例子Umi，如下图所示。

> 
Umi 就是一套零配置（约定高于配制），按最佳实践进行开发的，开箱即用的前端框架: React 全家桶 + dva + jest + antd (mobile) + less + eslint。


<img src="https://static001.geekbang.org/resource/image/02/f9/02a6db1e0ba7d775bba72cab356ffaf9.jpg" alt="">

从上图中可以看出，Umi已经思考的相对全面，从技术选型、构建到多端输出、性能优化、发布等方面进行了拆分，使得Umi的边界更为清晰，是前端最佳实践，目前大多数前端组都是类似的实现方式。说白了，Umi和 create-react-app（cra）类似，就是现有技术栈的组合，封装细节，让开发者用起来更简单，只写业务代码就可以了。

- 零配置就是默认选型都给你做好了。
- 开箱即用就是技术栈都固化了。
- 约定大于配置，开发模式也固化好了。

Umi的核心是 af-webpack模块，它封装了Webpack和各种插件，把 webpack-dev-server 等Node.js模块直接打包进去，同时对配置做了更好的处理以及插件化。af-webpack核心是webpack-chain模块，通过链式写法来修改Webpack配置，使得af-webpack极为灵活。其实以React全家桶为例，开发者最大的负担就是Webpack工程化构建。关于 Webpack 的封装实践有很多，比如知名的还有YKit、EasyWebpack等。

- YKit 是去哪儿开源的Webpack，内置 Connect 作为Web server，结合dev和hot中间件，对于多项目构建提效明显，对版本文件发布有不错的实践。
- EasyWebpack 也是插件化，但对解决方案、boilerplate 等做了非常多的集成，比如Egg的SSR是有深入思考的，尽管不赞同这种做法。

另外，在 create-react-app（cra）项目里使用的是 react-scripts 作为启动脚本，它和 egg-scripts 类似，也是通过约定，隐藏具体实现细节，让开发者不需要关注构建。在未来，类似的封装还会有更多的封装，并且更偏于应用层面。

### PWA进入稳定期

PWA和native app（移动应用）的核心区别在于以下几点：

1.安装：PWA是一个不需要下载安装即可使用的应用。<br>
2.缓存使用：native  app主要是对sqlite缓存，以及文件读写操作，而PWA对缓存数据库操作支持的非常好，足以应对各种场景。<br>
3.基本能力补齐，比如推送。

现在PWA已经支持的很好了，唯一麻烦的是缓存策略和发版比较麻烦，应用轻量化的趋势已经很明朗了。下面讲一下PWA的一些关键点。

**1.通用本地存储的解决方案Workbox**

Workbox 是 GoogleChrome 团队推出的一套 Web App 静态资源和请求结果本地存储的解决方案，该解决方案包含一些 JS 库和构建工具，Workbox 背后则是 Service Worker 和 Cache API 等技术和标准在驱动。在 Workbox 之前，GoogleChrome 团队较早时间推出过 sw-precache 和 sw-toolbox 库，但骂声很多，直到 Workbox 才真正诞生了能方便统一的处理离线能力的更完美的方案。

Workbox 现在已经发布到了 3.0 版本，不管你的站点是用何种方式构建的，它都可以为你的站点提供离线访问能力，几乎不用考虑太多的具体实现，只用做一些配置就可以。就算你不考虑离线能力，它也能让你的站点访问速度更快。

<img src="https://static001.geekbang.org/resource/image/d8/a6/d8cb688bfa3a753adb8c594157a4aca6.jpg" alt="">

比如星巴克的PWA应用，对缓存的应用高达41.3mb。这是浏览器端非常大的突破，尽管没啥新技术。

**2.PWA桌面版**

纵观PC桌面端的发展过程，早期Delphi/VB/VF/VC等构建起的c/s时代，即使到今天依然有很大的量。最近两年，随着Atom/VSCode的火爆，带动了node webkit相关模块的爆发，比如NW.js和Electron等。通过Web技术来构建pc client，确实是省时省力，用户体验也非常好，比如钉钉客户端、石墨文档客户端等，最主要的是可以统一技术栈，比如某些算法，用JS写一次，之后可以到前端、node、pc client等多处复用。当然更好的是使用Web技术进行开发，不需要加壳打包，PWA桌面版就是这样的技术。

接下来就具体聊一下桌面端的3个发展阶段。

<img src="https://static001.geekbang.org/resource/image/7e/8b/7ec25448c5fd505b10db05e80ebec28b.jpg" alt="">

第一阶段：原生开发Native

早年的VB/VF/VC/Delphi等原生开发方式，到后来出现QT类的跨平台软件，但依然可以理解成是原生开发。

第二阶段：混搭开发Hybrid

谷歌于2008年9月2日首次发布了Chrome浏览器，Node.js是Ryan Dahl于2009年发布的，他把V8引擎（Chrome核心JavaScript引擎）搬到了后端，使用js编写服务器程序变为现实。随后 npm 发展极为迅猛，跨平台技术也突飞猛进，出现了NW.js这样的轻量级跨平台框架，基于Chromium（Chrome开源版本） + Node.js，使得PC桌面端能够通过Web开发技术开发，最终打包编译成各个平台支持的应用格式，给PC桌面开发带来了太多的可能性。

而Atom 是 GitHub 在 2014 年发布的一款基于 Web 技术构建的文本编辑器，其中atom-shell，也就是后来的 Electron，是和NW.js类似的技术。它允许使用Node.js（作为后端）和Chromium（作为前端）来完成桌面GUI应用程序的开发。Chromium 提供了渲染页面和响应用户交互的能力，而 Node.js 提供了访问本地文件系统和网络的能力，也可以使用 NPM 上的几十万个第三方包。在此基础之上，Electron 还提供了 Mac、Windows、Linux 三个平台上的一些原生 API，例如全局快捷键、文件选择框、托盘图标和通知、剪贴板、菜单栏等。

<img src="https://static001.geekbang.org/resource/image/5d/2f/5dfae716a1c3383afc0d51ee7be40c2f.jpg" alt="">

Erich Gamma老爷子设计的 Monaco／VS Code，同样基于Electron，但性能比Atom强多了。VS Code 会先启动一个后台进程，也就是 Electron 的主进程，它负责编辑器的生命周期管理、进程间通讯、UI插件管理、升级和配置管理等。后台进程会启动一个（或多个）渲染进程，用于展示编辑器窗口，它负责编辑器的整个 UI 部分，包括组件、主题、布局管理等等。每个编辑器窗口都会启动一个 Node.JS 子进程作为插件的宿主进程，在独立进程里跑插件逻辑，然后通过事件或者回调的方式通知 Renderer 结果，避免了 Renderer 的渲染被插件中 JS 逻辑阻塞。

> 
演进过程：chrome &gt; Node.js &gt; nw.js &gt; atom(electron) &gt; vs code


在第二阶段里，我们可以看到PC桌面端以 Web 开发技术作为核心，以浏览器内核作为跨平台核心，最终将 Web 开发的代码和浏览器内核打包。这样做的好处是前端开发相对简单，相对于 C++ 等语言更为方便，另外从成本上考虑，也是极为划算的。

如今，很多应用都开始基于Electron构建，比如微信小程序ide、微信pc版本等，另外非常令人激动的是，2018年10月18日，[迅雷论坛](http://bbs.xunlei.com/forum.php?mod=viewthread&amp;tid=3188982&amp;extra=page=1)发文称新版（从迅雷X 10.1版本开始）采用Electron软件框架完全重写了迅雷主界面。使用新框架的迅雷X可以完美支持2K、4K等高清显示屏，界面中的文字渲染也更加清晰锐利。从技术层面来说，新框架的界面绘制、事件处理等方面比老框架更加灵活高效，因此界面的流畅度也显著优于老框架的迅雷。

<img src="https://static001.geekbang.org/resource/image/ed/33/edc230d91868db8f26fe9acd3d80a733.jpg" alt="">

第三阶段：PWA桌面版

王国维在《人间词话》中提出“隔与不隔”这一文学命题，这个问题在开发领域也是存在的。明明是Web开发的，为什么还要打包加壳呢？除了体积非常大以外，使用安装也极为麻烦。

Spotify的PWA桌面版应用体验是非常好的，在mac上丝般顺滑。

<img src="https://static001.geekbang.org/resource/image/37/24/377d738b4ee2bc905a217ee46e593824.jpg" alt="">

2018年Google IO大会上，微软宣布win10全力拥抱PWA，通过爬虫爬取PWA页面，并将其转换为Appx，继而在其应用商店里提供应用，体验和原生Native应用非常相近，对此我非常看好。

<img src="https://static001.geekbang.org/resource/image/5a/a2/5a95bec078cac7ee0e16fcecfdf2fea2.jpg" alt="">

浏览器有着超强的缓存能力，外加PWA其他功能，使得浏览器上的PWA应用能够取得媲美 Native 应用的性能。在浏览器里可以直接打开，无需加壳，很明显这是极为方便的。

PWA 必然会改变前端与移动端之间的格局，再加之 AOT(ahead-of-time) 与 WebAssembly 为 JS 带来的性能上的突破，JavaScript 将撼动所有领域，从移动端（PWA）到桌面应用、物联网、VR、AR、游戏乃至人工智能等等。

Google接下来会大力推进PWA的桌面版，再加上win10和Chrome加持，Web应用无需加壳就能达到近乎原生的体验，前端的领域再一次被拓宽，未来真的可以大胆的想想。

很多人问PWA在国内为什么感觉不火，原因很简单，PWA在弱网环境下表现极好，但中国的网络是全球最好的，所以PWA其实没有给我们带来那么大的收益。不过当做一个补位方案也挺好的，毕竟2G/3G还有点量，另外在服务器渲染SSR上，PWA也能够起到很好的效果。

### 小程序火爆

如果说和PWA比较像的，大概就是小程序了，小程序也可以说是今年最火的技术。

<img src="https://static001.geekbang.org/resource/image/fc/96/fc98892ccc8ed0b3d520ab1f7d611496.png" alt="">

微信小程序的下一步计划，支持NPM、小程序云、可视化编程、支持分包等，听起来很美好，但坑依然不少。小程序原生提供的 DSL 不够好用，所以就有了上层开发框架或者脚手架来优化开发效率，目前比较主流的有3个：

<img src="https://static001.geekbang.org/resource/image/24/2e/24b1ec94da1463cd3f8661de8af4912e.jpg" alt="">

今年还冒出了微信小程序之外的头条小程序、支付宝小程序、百度智能小程序等，未来还会有很多。同时，手机厂商大概是看到了小程序对其应用商店的威胁，小米、华为、OPPO、vivo 等九大国内手机厂商联手成立了“快应用联盟”，基于react-native技术栈，整体也很不错，尤其是天猫调用菜鸟裹裹的快应用，安卓下有非常好的体验。相较而言，微信是基于 Webview 的，而快应用使用的是原生渲染方案，其他家也大抵如此。

其实5G时代很快就到了，大家可以畅想一下，在网速、内存和CPU更高的情况下，5G每秒最高下载速度高达1.4G，秒下PWA或小程序应用，到底是离线，还是在线，犹未可知吧。

前端能讲的东西实在太多了，但受限于篇幅，本文只能先简单跟你分享React/Vue/Angular三大框架标准化、应用层封装进入爆发期、PWA进入稳定期、小程序火爆等方面的内容。下一篇文章中，我将继续跟你聊聊移动端局面、多端拉齐的必然性等内容，以及2019年不可忽视的TypeScript和WebAssembly这两大技术，欢迎继续关注，也欢迎留言与我多多交流。

## 作者简介

狼叔（网名i5ting），现为阿里巴巴前端技术专家，Node.js 技术布道者，Node全栈公众号运营者。曾就职于去哪儿、新浪、网秦，做过前端、后端、数据分析，是一名全栈技术的实践者，目前主要关注技术架构和团队梯队建设方向。即将出版《狼书》3卷。


