模块化的历史
前端模块化的历史可以参考JavaScript 模块化七日谈。
不同规范的比较
| 规范 | 适用场景 | 特性 |
|---|---|---|
| es6 import | 浏览器和服务器端 | 静态分析 |
| commonjs | 服务器 | 运行时加载 |
| amd | 浏览器 | 运行时加载 |
commonjs
运行时加载:本质上是整体加载模块,生成一个对象,然后再从这个对象上面读取方法
es6模块
es6 的设计思想是尽量静态化,使得编译时就能确定模块的依赖关系,以及输入和输出变量。利用这个特性可以做tree shaking。es6的语法很简单,平常工作中天天都在使用,接下来讲一下它的一些特性。
export特性
- export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。不能直接输出值
export 1
var m = 1
export 1
这两种写法都是错误的
export var m = 1
- 由于
export对外的是接口,所以与其对应的值是动态绑定关系,即通过接口,可以取到模块内部实时的值 export只能放在模块顶层,如果处于块级作用域中会报错,因为这样就没法做静态优化,这违背了es6模块的设计初衷export.default本质是将后面的值,赋给default变量
export default var 1 //报错
export default 1 //正确
import特性
通过export显式指定输出,不能引用模块本身
import()
import命令无法取代require的动态加载功能,就出现了import()函数来完成动态加载,这个函数的返回值是promise
适用场景:
- 按需加载:react路由的按需加载
import('./A.js).then((moduleA) => {
console.log(moduleA.default)
})
模块化的展望
前端工程的模块化,除了js外,还需包括css和html。虽然react/css-modules和vue都将它们合并开发,但是还很依赖webpack等打包工具。目前css的模块化方案是styled-component,通过js动态创建class,而html方面是html Modules,如果 html得到了浏览器,编辑器的模块化支持,未来可能会取代 jsx 成为最强大的模块化、模板语言。