整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

前端命令行如何加载除js以外的配置文件?Liftof

前端命令行如何加载除js以外的配置文件?Liftoff提供了解决方案

篇文章主要向大家介绍一个全局命令行辅助开发工具liftoff,这个工具在npm托管平台上周下载量还是很大的,但是在工作中却很少看见有人使用!目前我知道在使用它的构建工具有gulp和fis3!

liftoff的作用

1、全局命令行(npm install xxx -g)调用项目目录下安装的本地包(npm install xxx)

目前很多的构建工具都把自己的功能分成了两个部分:xxx-cli和xxx,比如gulp和webpack。

拿gulp举例,在安装完gulp-cli这个包后,是不能直接使用的,还需要在项目下安装gulp这个包才行,工具作者的想法就是gulp-cli负责命令行参数的处理,本地的gulp包才负责具体构建逻辑的处理,即gulp-cli会加载本地的gulp包,然后将命令行参数传给它!

一个全局命令行调用本地项目中安装的包还是比较麻烦的,好在liftoff提供了这个能力(内部使用的是resolve这个包完成这个工作)。

2、加载配置

你会发现gulp、fis3、webpack等等一些构建工具都有一个本地的配置文件xxx.config.js,显然在构建工具运行的时候需要读取这个配置,那么liftoff也提供了这个能力,它还处理了一些特殊的情况,比如配置文件在祖先目录下或者不在工程目录下等特殊情况!

3、编译特殊语言

有时用户在写配置文件时,不一定都会用javascript这个语言,如果用了其他语言开发了配置文件,node是无法加载的,所以需要先加载编译脚本使其先被编译,而liftoff就提供了这个能力,在使用特殊语言时可以先加载编译脚本!

liftoff的主要API

var Liftoff=require('liftoff'); //调用

var cli=new Liftoff(options);//实例化

cli.prepare(options, fn); //处理参数

cli.execute(options, fn); //执行回调函数

cli.launch(options, fn); //上面两个方法的组合

liftoff的使用详解

假设我们现在提前为百度写一个fis4(目前只有fis3),配置文件叫fis4-conf.js。

现在我们创建如下这样的目录:

图1

index.js是我们命令行的逻辑,本地开发可以先不发包,

fis4-conf.js是配置文件,

fis4-local是本地需要安装的包。

图2

如图2,在index.js中先实例化liftoff,传入的对象的属性在内部会被合并到cli这个实例对象上。这个配置中processTitle代表命令行运行后的进程名,moduleName代表这个命令行需要加载的本地的包名,configName代表本地配置的文件名!

如果上面三个属性都没传,只有name属性,processTitle和moduleName都会复用name的值,name再拼接一个‘file’字符串然后赋给configName。

extensions对象的key代表本地配置文件的后缀,value代表需要加载的编译脚本,值可以是null、字符串、数组等,内部会将extensions这个字段用fined这个包来解析,所以配置规则可以参考这个包!

图3

在图3中我们调用了prepare方法,require参数可以是数组也可以是字符串(包名),代表需要提前加载运行的包;cwd默认是进程运行的目录,这里通过cwd可以自定义root目录;configPath参数可以重新定义配置文件的路径。

现在我们打印一下后面回调函数的参数env,看看输出什么?

图4

如图4,liftoff帮我们找到了本地配置文件的位置和本地需要加载的包fis4-local的位置,说到这里我想大家应该明白了,这些信息既然都拿到了后面怎么运行就看你自己了。

我们再聊聊如何用其他语言开发配置文件比如ts

我们现在建一个ts配置文件fis4-conf.ts,如图5所示:

图5

图6

如图6所示,extensions后缀修改成ts,值变成需要提前加载的编译包,最后我们调用execute方法,这个方法不仅会加载extensions中注册的包,还会加载require中注册的包!

运行结果如下:

图7

很好,符合预期。

如果大家不太清楚自己使用的语言对应的编译脚本,可以使用interpret这个包,如下:

图8

图9

如图9所示,interpret已经为我们整理好了各种后缀对应的编译脚本的包!

总结

这篇文章主要分析了liftoff解决加载本地包、加载项目配置文件以及如何加载其他语言的编译脚本,可以把它当做我们开发命令行的辅助工具!另外既然我们了解了思路,其实我们也可以手写这些逻辑,不一定要复用它,造轮子才可以更快的成长!

喜欢我的文章就关注我吧,后续会更多干货输出,让我们一起学习,共同成长!(希望收藏之前大家关注一波-_-)

注风云之声

提升思维层次

导读


坐飞机不怕晕机,最怕机晕。

撰文 七君


在获得了两项奥斯卡提名的2012年的电影《迫降航班》中,出现了超出常识的一幕:机长让飞机上下倒着飞。



飞机颠倒飞行真的科学吗?


若是按照许多教科书的理论,这是不可能的。


可是这些教科书中的理论是错的,美国国家航空航天局(NASA)还专门制作了一个网站来批判这些理论。


这种盛行的错误理论是,机翼上部比下部更长,使得空气分子在上部的移动距离更长,因此速度必须更大才能和下部的空气分子汇合。这种理论接着解释,根据伯努利定律,速度增加时气压减少,因此机翼上部的气压比下部低,机翼就被往上推了。


图片来源:wikipedia


NASA 介绍,事实上上下对称的机翼,甚至下部更弯曲更长的机翼也能产生升力;这种理论也无法解释空战和飞行特技中飞机颠倒着飞的情况。


美国空军雷鸟飞行表演队在2012年的 北极雷霆航空展上表演倒飞。图片来源:wikicommons


此外,虽然机翼上方空气的流速比下方更大,但是上部的速度快到无法和下部的空气在机翼末端汇合,因此这个理论是有问题的。


不过,机翼上部的气压确实小于下部,这一点真实不虚。


那么到底是什么让飞机飞翔呢?


NASA指出,升力的产生存在巨大的争议,许多教科书的解释是错的。图片来源:www.grc.nasa.gov/WWW/k-12/airplane/lift1.html


NASA 介绍,关于飞机如何获得升力存在许多理论,也存在很大争议,尚未达成统一,但现在能确定的是,物体获得升力的过程很复杂,迎角和机翼的形态和升力密切相关。


机翼的形态比较好理解,我们平时看到的机翼都是上鼓下平。


迎角指的是机翼迎风的倾斜角度。事实上在70多年前,人类发现了迎角和升力之间的重要关系:对于特定的机翼来说,在一定范围内,迎角越大,升力就越大。


上鼓下平的机翼(正弯度机翼)和不同的迎角。图片来源:FAA


机翼的迎角在5-6度时获得的升力远超1-2度时的情况。在起飞前的一瞬,飞行员会让飞机昂头,这就是为了增加迎角,从而增加升力的操作。即使是完全扁平的机翼在调整了迎角之后也能起飞,放风筝就是这个原理。



如果把各种机翼设计的迎角和机翼的性能——升力系数(升力系数和升力成正比,一般来说升力系数越大越好)作图,那么我们就会发现,不同机翼的数据构成了一条直线。


在一定范围内,迎角(横坐标)越大,升力系数(纵坐标)越大。图片来源:wikipedia


这个知识最初来自1945年NASA的前身美国国家航空咨询委员会 (NACA)公布的一份关于机翼的资料——NACA Technical Report 824。这份报告里面包含着许多机翼在风洞中的测试数据,它在日后成了各种机翼设计参考书的基础。


有趣的是,如果把机翼上下颠倒再测试,升力的数据和迎角之间的关系也是类似的。


正弯度(最粗的蓝线),零弯度(上下对称)和负弯度机翼(最细的蓝线)的升力系数都随着迎角的增加而增加。图片来源:Gudmundsson, Snorri. General aviation aircraft design: Applied Methods and Procedures. Butterworth-Heinemann, 2013.


实际上,把常见机翼上弯下平的设计倒转过来的翼型叫做负弯度(negative camber),只要迎角够大,负弯度的机翼也能飞起来。只不过在同样的迎角下,它们获得的升力要少一些,也就是说飞得要吃力些。


我们还可以看荷兰特文特大学用模型飞机做的演示。


如果飞机能飞起,那么飞机会带动杆子向上移动。大家可以看到,倒着飞的时候,飞机模型在风洞里也能升起,只不过效率降低了。



在飞行史上,首次让飞机倒着飞的人是法国传奇飞行员 Alphonse Pégoud。1913年,他驾驶着一架 Blériot 型号的单翼机,展示了倒着飞的特技。


Blériot 型号的单翼机。图片来源:wikipedia


1914年,一位德国勇士也学会了倒着飞的特技。这个叫做 Gustav Tweer的小伙子更野,他不但让一架Grade型号的单翼机倒着飞,还倒着落地。


1914年,经常倒着飞的德国飞行员 Gustav Tweer 让飞机倒着着陆。

图片来源:flying magazine


现代意义上的客机也曾有倒着飞的记录。


在2000年1月31日的阿拉斯加航空261号班机空难中,由于机械故障,一架MD-83型号的客机失控,头向下俯冲了一段时间。后来机组人员努力使机头保持水平,在空中上下颠倒地飞了大约1分钟。但不幸的是,此时飞机已经非常接近太平洋,最终坠落在了海中。《迫降航班》中客机倒飞的情节也来源于此。



虽然机翼上下颠倒并不会使机翼失去升力,不过现代客机倒飞时会面临其他问题。


其中一个大问题就是供油。普通飞机的油箱中为引擎供油的管子开口贴近油箱底部,而且无法移动。如果飞机倒着飞,油管的相对位置就会变成油箱顶部,那样就无法为引擎提供燃料了。



而能倒着飞的特技飞机的供油管巧妙地解决了这个问题。这类飞机常会采用能够活动的管子 flop tube,它的尾端比较重,而且能够活动。在飞机倒转时,油管也会跟着翻身,继续为引擎供油。


特技飞机的另外一种策略是使用特殊的油箱,如位于机翼下方的 header tank。一些特技飞机,比如 Super Decathlon 型号的飞机的油箱在飞机上方,飞机正飞的时候,重力使燃油向下流入燃油泵。但是在机翼下方还有一个油箱 header tank,它也和燃油泵相连。在飞机倒转时,这个油箱就到了机翼上方,可以利用重力为引擎供油。



这些技术就是特技飞机可以在空中玩蛇皮走位,但客机不行的小秘密了。


坐飞机不怕晕机,最怕机晕。


扩展阅读:

按照概率学原理,你这牌一看就胡不了 | 把科学带回家

垃圾不分类随便扔的人,是在制造“世纪之毒” |把科学带回家

不懂物理的裁判造成世界杯经典冤案,50年前物理学家就发现了球的奇特运动 | 把科学带回家

长大后吸掉了自己的脑子,这种动物曾被主流教材视为人类的原始祖先 | 把科学带回家

者|狼叔

编辑|覃云

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

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

大前端

2018 年的事儿特别多,从 React v16 普及,到 jQuery 被 GitHub 下掉完成阶段性历史使命,在唏嘘之外,版本帝 AngularJS 又发布了 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 (
 <div>
 <h1>{this.count}</h1>
 <button onClick={()=> this.up()}>+</button>
 <button onClick={()=> this.down()}>-</button>
 </div>
 )
 }
}
Vue.render(<App />, 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 组件和你喜欢的工具、框架协同使用。

 <script src="node_modules/@webcomponents/webcomponents-loader.js"></script>
 <script type="module">
 import {PolymerElement, html} from '@polymer/polymer';
 class MyElement extends PolymerElement {
 static get properties() { return { mood: String }}
 static get template() {
 return html`
 <style> .mood { color: green; } </style>
 Web Components are <span class="mood">[[mood]]</span>!
 `;
 }
 }
 customElements.define('my-element', MyElement);
 </script>
 <my-element mood="happy"></my-element>

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

1.Rax 也提供了一个名为 atag 的 UI WebComponents 库。

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`<p>Hello, ${this.name}!</p>`;
 }
}
// 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),这个曲线把技术发展分成五个步骤:【科技诞生的促动期】->【过高期望的峰值】-> 【泡沫化的底谷期】 -> 【稳步爬升的光明期】 -> 【实质生产的高原期】。从前端现在的热度来看,应该是处于从第三阶段【泡沫化的底谷期】到第四阶段【稳步爬升的光明期】的爬坡过程,创新不会那么多,更多的是偏于应用层的内容。

对于当下的前端发展情况,我其实是有隐忧的。当年 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。如下图所示:



从上图中可以看出,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 是一个不需要下载安装即可使用的应用。
  2. 缓存使用:native app 主要是对 sqlite 缓存,以及文件读写操作,而 PWA 对缓存数据库操作支持的非常好,足以应对各种场景。
  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 版本,不管你的站点是用何种方式构建的,它都可以为你的站点提供离线访问能力,几乎不用考虑太多的具体实现,只用做一些配置就可以。就算你不考虑离线能力,它也能让你的站点访问速度更快。

比如星巴克的 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 个发展阶段。

第一阶段:原生开发 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,例如全局快捷键、文件选择框、托盘图标和通知、剪贴板、菜单栏等。

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

演进过程:chrome > Node.js > nw.js > atom(electron) > vs code

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

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

第三阶段:PWA 桌面版

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

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

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

浏览器有着超强的缓存能力,外加 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 比较像的,大概就是小程序了,小程序也可以说是今年最火的技术。

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

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

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

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

多端拉齐,并重用户体验

在 AI 时代,没有“端”的支持可以么?明显是不可以的。首先感谢苹果,将用户体验提升到了前无古人的位置。移动互联网兴起后,PC Web 日渐没落。我个人非常欣赏玉伯,在当年无线 ALL IN 战略中,他还是选择留下来继续做 PC Web 的前端。不过,虽然很多公司的重点转向无线,但 PC 业务也一直没停,这是很多公司的现状,也是客观事实。那么,PC 端这样的“老古董”的出路到底在哪里呢?

  1. 我们可以利用 PC/H5 快速发版本的优势,快速验证 AI 算法,继而为移动端提供更好的模型和数据上的支撑。
  2. 多端对齐,打好组合拳。既然不能在移动端有更大的突破,大家只能在细节上血拼。

大家的战场已经不是点了,已经升级到打组合策略的阶段了。未来一定是多端拉齐,并重用户体验的。

今天的大前端,除了 Web 外,还包括各种端,比如移动端、OTT,甚至是一些新的物联网设备。我们有理由相信 Chrome OS 当年的远见:“给我一个浏览器,我就能给你一个世界。”如果说的苟且一点:“给我一个 Webview,我就能给你一个世界。”

TypeScript

我之前就非常关注 TypeScript,但迟迟未下定决心在团队内落地。今年 1 月份北京 Node Party 上组了个局,和几位嘉宾一起聊了一下,确认提效非常明显,落地难度也不大,大家一致认为 2019 年 TypeScript 将有非常大的增长。本身前端团队变大,规模化编程也必然依赖类型系统和面向对象的,从这点上看,TypeScript 也是完胜的。

这里再简单介绍一下 TypeScript,它是有类型定义的 JavaScript 的超集,包括 ES5、ES5+ 和其他一些诸如反射、泛型、类型定义、命名空间等特征的集合,为了大规模 JavaScript 应用开发而生。复杂软件需要用复杂的设计,面向对象就是一种很好的设计方式,使用 TypeScript 的一大好处就是 TypeScript 提供了业界认可的类( ES5+ 也支持)、泛型、封装、接口面向对象设计能力,以提升 JavaScript 的面向对象设计能力。市面上的框架也对 TypeScript 提供了非常好的支持。

React 对.tsx 支持非常好,比如我在 Midway controller 里支持 tsx 写法,这是非常大胆的,对于后面 react ssr 来说是一个极大便利;Vue 从 v2.5.0 之后对 ts 支持就非常好;Node.js Web 框架,尤其是 Egg.js 对 ts 支持非常好,当然还有更高级更专注的的 Midway 框架,Midway 基于 Egg 生态,同时提供 IoC 等高级玩法;

在使用 Webpack 编译前端应用式,通过 TypeScript-loader 可以很轻松地将 TypeScript 引入到 Webpack 中。有了 TypeScript-loader,就可以一边使用 TypeScript 编写新代码,一边零碎地更新老代码。毕竟 ts 是 js 超集,你有空就改,非强制,特别包容。

WebAssembly

WebAssembly 是一种新的字节码格式,目前主流浏览器都已经支持 WebAssembly。 和 JS 需要解释执行不同的是,WebAssembly 字节码和底层机器码很相似,可以快速装载运行,因此性能相对于 JS 解释执行而言有了极大的提升。 也就是说 WebAssembly 并不是一门编程语言,而是一份字节码标准,需要用高级编程语言编译出字节码放到 WebAssembly 虚拟机中才能运行, 浏览器厂商需要做的就是根据 WebAssembly 规范实现虚拟机。这很像 Java 早年的 Applet,能够让其他语言运行在浏览器里。Applet 是一种 Java 程序,它可以运行在支持 Java 的 Web 浏览器内。因为它有完整的 Java API 支持,所以 Applet 是一个全功能的 Java 应用程序。

有了 WebAssembly,在浏览器上可以跑任何语言。从 Coffee 到 TypeScript,到 Babel,这些都是需要转译为 js 才能被执行的,而 WebAssembly 是在浏览器里嵌入 vm,直接执行,不需要转译,执行效率自然高得多。

举个例子,AutoCAD 软件是由美国欧特克有限公司(Autodesk)出品的一款自动计算机辅助设计软件,可以用于绘制二维制图和基本三维设计。使用它时,无需懂得编程,即可自动制图,因此它在全球被广泛应用于土木建筑、装饰装潢、工业制图、工程制图、电子工业、服装加工等诸多领域。

AutoCAD 是由大量 C++ 代码编写的软件,经历了非常多的技术变革,从桌面到移动端再到 web。之前,InfoQ 上有一个演讲,题目是《AutoCAD & WebAssembly: Moving a 30 Year Code Base to the Web》,即通过 WebAssembly,让很多年代久远的 C++ 代码在 Web 上可以运行,并且保证了执行效率。

本来,我以为 WebAssembly 离我们很远,但在 2018 年 Google I/O 大会亲眼见到 AutoCad Web 应用后,非常震撼,效果如下图所示。

能够让如此庞大的项目跑在 Web 端,真的是非常了不起。通过 WebAssembly 技术,既能复用之前的 C++ 代码,又能完成 Web 化,这也许就是所谓的两全其美吧。

之前,全民直播的前端研发经理赵洋曾分享了 WebAssembly 在全民直播里对直播编解码方面的应用,效果也非常不错。

另外,许式伟在 ECUG Con 2018 上也分享了一个 Topic,主题是《再谈 Go 语言在前端的应用前景》,Go 的发展也遇到了瓶颈,专注后端开发是没办法让 Go 排到第一的,目前的一个方向是借助 GopherJS,将 Go 代码编译为 JS。这种实践是没问题的,和 Kotlin 类似,对于绝大部分 Go 用户也是非常好的。但问题在于,真正的前端不太可能换语言,目前连 Babel、ts 这种都折腾的心累,更何况切换到 Go。“求别更新了,老子学不动了”,这是大部分前端工程师的心声。

从 WebAssembly 的现状来看,对于复杂计算耗时的部分采用其他语言实现,确实是比较好的一种方式。从趋势上看,WebAssembly 让所有语言都能跑在浏览器上,浏览器上有了 vm,浏览器不就是操作系统了吗?

Chrome 的核心 JavaScript 引擎 V8 目前已包含了 Liftoff 这一新款 WebAssembly baseline 编译器。Liftoff 简单快速的代码生成器极大地提升了 WebAssembly 应用的启动速度。不过在桌面系统上,V8 依然会通过让 TurboFan 在后台重新编译代码的方式最终让代码运行性能达到峰值。

目前,V8 v6.9 (Chrome 69) 中的 Liftoff 已经设置为默认工作状态,也可以显式地通过 --liftoff/--no-liftoff 或者 chrome://flags/#enable-webassembly-baseline 开关来控制。另外,Node.js v11 采用的 v8 引擎的 v7 版本,对 WebAssembly 支持更好,虽然这没啥意义,但练手还是蛮好的。

移动端

Flutter 是 Google 推出的帮助开发者在 Android 和 iOS 两个平台,同时开发高质量原生应用的全新移动 UI 框架,和 React-native/Weex 一样支持热更新。Flutter 使用 Google 自己家的 Dart 语言编写,刚好今年 Dart 2 也正式发布,不知道二者之间是否有关联。目前 Dart 主攻 Flutter 和 Web 两块,同时提供了 pub 包管理器,俨然是一门全新的语言,学习成本有些高。反观 TypeScript 就非常容易被接受,基于 npm 生态,兼容 ES 语法,因此,2019 年对 Dart 我还是会持观望态度。

除了不喜欢 Dart 外,Flutter 的其他方面都很好,在移动端现在强运营的背景下,支持热更新是必备能力。

关于 Weex,一边骂一边用,很无奈的一种状态。Weex 本身是好东西,捐给了 Apache,目前在孵化中,会有一个不错的未来。但社区维护的非常差,问题 issue 不及时,文档不更新。如果公司没有架构组,还是比较难搞定的。

不过也有很多不错的案例,比如 2018 年优酷双十一活动就是使用 Weex 开发的,效果非常不错。通过自建的可视化活动搭建平台,能够非常高效的完成开发,结合 App 内的缓存,整体效果比 H5 好的多。

我对 Weex 的看法是,以前 Weex 只是解决 H5 渲染效率的问题,但如今强运营的背景,使得 Weex 承载了非常多的内容,比如动画、游戏甚至是图形图像处理等。可以看到,未来 Weex 还会战略性的增加。

总结

总结一下,2018 年大前端的现象:

前端三大框架已趋于平稳,标准化,向 Web Components 看齐。应用层面开始进入过渡封装周边的阶段,很多细节都会埋在框架里。PWA 平稳发展,兼容 4/5 浏览器,workbox 3 进一步简化开发,另外 PWA 桌面版已经开始兴起,未来会更多。多端受到重视,不再只是 all in mobile。WebAssembly 让更多语言可以运行在浏览器上,AutoCAD 的 web 版是非常好的例子。

强运营背景下,移动端以前端开发为主,已成定局。Flutter 局势暂不好说,还在观望中(主要是不喜欢 Dart)。TypeScript 落地很好,包容性更好:React 对.tsx 支持非常好,Vue 从 v2.5.0 之后对 ts 支持就非常好,Node.js(尤其是 Egg.js、midway)对 ts 支持也非常好。

5G 时代快来了,互联网的长期在线情况有可能会被打破。本地设备即客户端,可以大胆的想想。对前端来说,本地 web 服务,辅助日常开发,类似于 je 这样的模块会越来越多。

终上所述,未来浏览器会越来越重要,Web Os 的概念正在慢慢落地。另外三大框架趋于稳定,写法上也越来越像,学习成本是降低的。但周边应用层面的封装还会是爆发式增长,更多复杂的细节会被包装到应用框架里,可能还有很多不一样的开发方式需要大家熟悉。

对于开发者而言,唯一不变的就是学习能力。掌握了学习能力就能够应对这些趋势变化,无论是在三大框架混战时代,还是后面周边封装时代都能很开心的“折腾”。哪怕有一天 AI 真的能够替人写代码,能应变的人自然也是不怕的。

关于大前端的现状和未来我就分享到这里,希望能对你有所帮助。