专栏名称: 京东设计中心JDC
专业,创造力,激情,设计。京东用户体验设计部门,致力于创造更美好的电子商务购物体验。
目录
相关文章推荐
庞门正道  ·  准备好上班了吗? ·  2 天前  
ZaomeDesign  ·  每日灵感丨二月五日 ·  昨天  
庞门正道  ·  21张剪纸,剪出来的全是震撼~ ·  5 天前  
字体设计  ·  招福万来,夜间飞行 ·  1 周前  
国际家居  ·  比利时极简设计,朴实无华 ·  4 天前  
国际家居  ·  比利时极简设计,朴实无华 ·  4 天前  
51好读  ›  专栏  ›  京东设计中心JDC

JDC丨京东设计中心 -【译】如何在生产环境中部署ES2015+

京东设计中心JDC  · 公众号  ·  · 2017-11-07 15:19

正文

原文: https://philipwalton.com/articles/deploying-es2015-code-in-production-today/

大部分前端开发人员热衷于使用新的 JavaScript 语言特性来书写 JS 代码,例如 async 、 await 、 classes 、 arrow functions 等。然而,尽管目前所有的前沿浏览器都能运行 ES2015+ 代码(译注:ES2015及俗称的ES6),自然也能够支持我刚刚列举的新特性,但是为了兼容占有小比例的低版本浏览器用户,大部分的开发者仍然使用 polyfills 将代码编译成 ES5 语法。

这种情况无疑糟透了,在理想的世界里,我们将无需输送不必要的代码!

使用新的 JavaScript 和 DOM APIs ,我们可以 有条件的加载 ployfills ,因为我们能够在运行时使用特性检测判断浏览器是否支持这些语法。但是随着一些新的 JavaScript 语法的出现,由于任何未知的语法都会导致代码解析错误,并且不再执行之后的代码,导致单凭特性检测来检查新语法的支持程度很是棘手。

尽管对于新的语法特性检测还没有一个好的解决方案,但目前对于 ES2015 的基本语法特性检测我们还是有办法的。解决之道便是 < script type = "module" >

大部分开发者认为 < script type = "module" > 是用来加载 ES 模块的(事实的确如此),但是 < script type = "module" > 也拥有更直接且实用的功能——加载浏览器可以处理的、使用 ES2015+ 语法的 JavaScript 文件。

换句话说,每个支持 < script type = "module" > 的浏览器都支持你所熟知的大部分 ES2015+ 语法,例如:

  • 支持 < script type = "module" > 的浏览器也支持 async await 函数。

  • 支持 < script type = "module" > 的浏览器也支持 Class 类

  • 支持 < script type = "module" > 的浏览器也支持 arrow functions

  • 支持 < script type = "module" > 的浏览器也支持 fetch Promises Map Set 等更多 ES2015+ 语法。

因此,唯一需要做的就是为不支持 < script type = "module" > 的浏览器提供一个降级方案。幸运的是,如果你正在开发一个 ES5 版本的代码,你其实已经完成了该工作。现在你所需要做的是考虑如何生成 ES2015+ 版本的代码!

本文接下来将介绍如何实现这个方法,并讨论对 ES2015+ 代码的处理过程对我们未来如何编写模块有何影响。

实现方式

如果你已经使用了 webpack 或者 rollup 这类模块打包工具来生成 JS 文件,那么你应该继续保持。

接下来,除了当前的代码包,你还需要生成类似于第一份的另外一份代码包。(该代码包使用了 ES2015+ 语法),唯一的不同是你不需要将其编译成 ES5 语法的代码,并且不需要引入 polyfills 插件。

如果你已经开始使用 babel-preset-env (实际上你应该使用该插件),第二个步骤将非常简单,你所需要做的事情就是使用支持 < script type = "module" > 的浏览器,这样 babel 就会忽略没必要转化的语法。

换言之,这样操作之后就会输出 ES2015+ 语法代码,而不是 ES5 代码。

例如,假设你使用了 webpack 并且 JS 的入口文件是 ./path/to/main.js ,你当前的 ES5 版本的配置应该如下所示(注意,由于使用 ES5 语法书写,我给该代码包命名为 main-legacy )

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

module . exports = {

entry : {

'main-legacy' : './path/to/main.js' ,

},

output : {

filename : '[name].js' ,

path : path . resolve ( __dirname , 'public' ),

},

module : {

rules : [{

test : / \. js $ / ,

use : {

loader : 'babel-loader' ,

options : {

presets : [

[ 'env' , {

modules : false ,

useBuiltIns : true ,

targets : {

browsers : [

'> 1%' ,

'last 2 versions' ,

'Firefox ESR' ,

],

},

}],

],

},

},

}],

},

};

为了支持 ES2015+ 版本,你需要做的是生成第二个配置文件,该配置文件的使用环境是支持 < script type = "module" > 的浏览器, 如下面所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

module . exports = {

entry : {

'main' : './path/to/main.js' ,

},

output : {

filename : '[name].js' ,

path : path . resolve ( __dirname , 'public' ),

},

module : {

rules : [{

test : / \. js $ / ,

use : {

loader : 'babel-loader' ,

options : {

presets : [

[ 'env' , {

modules : false ,

useBuiltIns : true ,

targets : {

browsers : [

'Chrome >= 60' ,

'Safari >= 10.1' ,

'iOS >= 10.3' ,

'Firefox >= 54' ,

'Edge >= 15' ,

],

},

}],

],

},

},

}],

},

};


一旦运行,这两个配置文件就会输出两个 JS 文件:

  • main.js (该文件支持 ES2015+ 语法)

  • main-legacy.js (该文件支持 ES5 语法)

接下来的步骤就是修改 HTML 代码,有条件的加载浏览器中支持 ES2015+ 的模块。你可以使用下面两个标签 < script type = "module" > < script nomodule > :


1

2

3

4

5

6


注意:这里唯一的问题是 Safari 10 并不支持 nomodule 属性,但是为了解决这一问题,你可以在使用 < script nomodule > 标签前,在 HTML 中使用 内联JavaScript代码片段 (注意:这个插件已经安装在 Safari11 版本中了)。

注意事项

在大多数情况下,这种方法“仅仅是能够实现”,在实现该方法之前需要注意一些关于如何加载模块的细节:

1,模块的加载方式类似于 <







请到「今天看啥」查看全文


推荐文章
庞门正道  ·  准备好上班了吗?
2 天前
ZaomeDesign  ·  每日灵感丨二月五日
昨天
庞门正道  ·  21张剪纸,剪出来的全是震撼~
5 天前
字体设计  ·  招福万来,夜间飞行
1 周前
国际家居  ·  比利时极简设计,朴实无华
4 天前
国际家居  ·  比利时极简设计,朴实无华
4 天前
新材料在线  ·  一文看懂3D玻璃贴合产业链
7 年前