❇️

Introduction to ES Modules

原文地址

Introduction to ES Modules

介绍

ES ModulesECMAScript 的模块标准.

众所周知 Node.js 使用 CommonJS 规范好久了, 但是浏览器仍未有一个自己的模块系统, 直到 ECMAScript 关于模块系统的首要决议通过后, 浏览器这才有了自己的模块系统.

这项标准在 ES6 中测试完成, 各大浏览器为了保持正常运作都开始实现 ESM 标准, 现在支持 ESM 都浏览器有: Chrome, Safari, EdgeFirefox (v60).

模块系统是非常酷的功能, 因为它可以让你封装各种各样的功能方法, 并且暴露给其他的 JS 文件.

caniuse-modules

语法

导入模块的语法:

import package from 'module-name'

使用 CommonJS 规范:

const package = require('module-name')

一个模块是一个 js 文件使用 export 关键字来导出一个或多个值(object, function, variable). 比如, 这个模块导出了一个返回大写字母的方法:

uppercase.js

export default str => str.toUpperCase()

在本例中, 此模块定义了一个默认的导出方法, 因此它可以是匿名函数. 其余的就必须给导出的内容一个值.

现在任何其他的 js 模块都可以导入此模块里的方法.

在 HTML 里可以使用 <script> 标签并使用 type="module" 属性来添加一个模块:

<script type="module" src="index.js"></script>

备注: 这个模块导入的加载就像使用了 defer 语法的标签: 使用 async 和 defer 快速加载 js

需要注意的是任何 type="module" 的脚本都是在严格模式下的.

在这个例子中, uppercase.js 定义了一个默认的导出, 因此当导入它时, 我们需要给它设定一个名字:

import toUpperCase from './uppercase.js'
toUpperCase('test') //'TEST'

你可以使用绝对路径来导入一个模块, 使用跨域的模块:

import toUpperCase from 'https://flavio-es-modules-example.glitch.me/uppercase.js'

这也是可行的导入语法:

import { toUpperCase } from '/uppercase.js'
import { toUpperCase } from '../uppercase.js'

这是非法的导入:

import { toUpperCase } from 'uppercase.js'
import { toUpperCase } from 'utils/uppercase.js'

因为它既不是绝对路径也不包含 .//.

其他 import/export 选项

上面的例子:

export default str => str.toUpperCase()

它导出了一个默认的方法, 当然你也可以导出多个值, 使用:

const a = 1
const b = 2
const c = 3

export { a, b, c }

其他模块可以这么导入所有的值:

import * from 'module'

你可以只导入几个值, 使用解构语法:

import { a } from 'module'
import { a, b } from 'module'

你还可以重命名任何值, 使用关键字 as:

import { a, b as two } from 'module'

你可以导入默认的, 非默认的, 就像在 react 中:

import React, { Component } from 'react'

你在[这里](https://glitch.com/edit/#!/flavio-es-modules-example?path=index.html可以看到 ESM 的例子

CORS

ESM 的加载是有跨域资源共享机制的, 这意味着如果你想引用一个其他域名下的脚本, 它们必须有一个有效的 CORS 请求头来允许跨域请求比如 Access-Control-Allow-Origin: *.

浏览器不支持处理方法

使用 type="module"nomodule 混合处理

<script type="module" src="module.js"></script>
<script nomodule src="fallback.js"></script>

总结

ESM 是现代浏览器更新里最重要的一个特性, 他被包含在 ES6 里, 但是实现它仍然有很长的路要走.

现在我们可以使用它, 但是要记住如果一个页面中有好多模块的话, 那么对浏览器性能肯定是有影响的, 因此这是浏览器运行时必须要面对的一个问题.

尽管 ESM 在浏览器支持的现在,Webpack 在前端仍然扮演了重要的角色, 但是在语言层面添加如此重要的特性对各端包括 Node.js 的统一来说是非常重大的.

在我们一生中,命运赐予我们每个人三个导师,三个朋友,三名敌人,三个挚爱。但这十二人总是不以真面目示人,总要等到我们爱上他们、离开他们、或与他们对抗时,才能知道他们是其中哪种角色。