前端开发规范在node中遵循CommonJS,浏览器中遵循ES Modules
ES Modules基本特性
- 通过给 script 添加 type = module 的属性,就可以以ES Module的标准执行其中的 JS 代码了
- 自动采用严格模式(严格模式代表就是不能在全局范围使用this)
- 每个 ES Module 都是运行在单独的私有作用域中
- ESM 是通过 CORS 的方式请求外部 JS 模块的,需要服务端的头部允许CORS请求才行
- ESM 的 script 标签会延迟执行脚本,在网页渲染完成之后才会执行,与defer属性效果相同
导出和导入
导出
- export可以导出变量、类、方法等,并可以使用as重命名
- export default是导出默认,在导入页面必须给默认导出声明新的变量名
- 默认导出的对象结构可以理解为对象字面量,而普通exports导出的对象结构只是固定的用法,不能理解为对象字面量
- 导出的内容只是给了外部一个引用关系,并不是将值赋给了外部变量,外部的值会受内部改变的影响
- 导出的成员是只读成员,不能在外部修改
导入
- **import * as mod from ‘…’**可以将导出的内容都放到mod中作为属性
- **import {} from ‘…’**可以只执行该模块,而不会导入该模块的成员
- import方法可以在任意位置导入模块,并得到一个promise,这就是动态加载模块,按需导入
- import后面可以跟两个成员,第一个是导出的默认成员,第二个就是其它的具名成员
导出导入
- **export { 模块名 } from ‘…’**将导入的成员直接导出
浏览器环境polyfill
有些浏览器不支持ESM的方式,需要转成ES5
unpkg可以提供各种包的cdn,使用script标签引入
- browser-es-module-loader 可以在所有浏览器中搭建可运行ESM的环境
- babel-browser-build browser-es-module-loader包的babel依赖
- promise-polyfill IE浏览器的ESM运行环境
注如果浏览器支持ES6,使用该包会导致重复引用模块,可以使用script标签的nomodule属性,则标签内的部分只会在不支持ES6的浏览器中运行
ESM in NodeJS
在nodeJS中使用ESM需要将文件扩展名改为mjs,且node版本要大于8.5,启用命令为node --experimental-modules index.mjs
node版本大于12后可以在package.json中添加type: module字段来使全局使用ESM模式,不需要再修改文件后缀
ESM和CommonJS
- ES Modules中可以导入CommonJS模块
- CommonJs中不能导入ES Modules模块
- CommonJS始终只会导出一个默认成员
- 注意import不是解构导出对象