1.发展历程
- 函数模式:借助函数作用域来模拟模块化,将不同功能封装成不同的函数。缺点:各个函数在同一个文件中,混乱地相互调用,存在命名冲突的风险。
- 对象模式:利用对象实现命名空间的概念。缺点:数据不安全,任何开发者都可以修改。
- CommonJs规范:本地同步加载。Node.js中,每个文件就是一个模块,具有单独的作用域,对其他文件是不可见的。特点:1.文件即模块,文件内的所有代码都运行在独立的作用域中,因此不会污染全局空间。2.模块可以被多次引用、加载,第一次加载时会被缓存,之后都从缓存中直接读取结果。3.module.export属性输出的是值的拷贝,值被输出后,模块内再发生变化不会影响输出值。
- AMD规范:浏览器异步加载模块。通过require.js实现,define方法将代码定义为模块,require方法实现代码的加载。AMD遵循前置原则,需要把模块所需要的依赖都提前声明在依赖数组中。
- CMD规范:整合了CommonJs和AMD规范特点,通过sea.js实现,可以通过同步或者异步加载模块。CMD遵循就近原则,只需要在具体代码逻辑中使用依赖前,引入依赖的模块。
- UMD规范:允许在环境中同时使用AMD和CommonJs规范。利用立即执行函数根据环境来判断需要的参数类别。
- ES模块化:静态化在编译时就确定模块之间的依赖关系,每个模块的输入和输出变量也都是确定的。它输出的是值的引用。静态设计的缺点:1.只能在文件顶部引入依赖。2.导出的变量类型受到严格限制。3.变量不允许被重新绑定,引入的模块名只能是字符串常量,不可以动态确定依赖。优点:可以通过分析作用域推导出变量和导入依赖变量之间的关系,在没有明显引用时,清除无用代码。
2.ES模块化使用
在浏览器中使用:
<script type="module">
import module1 from './module1'
</script>
<script nomodule>
alert('你的浏览器不支持ES模块,请先升级!')
</script>
使用type="module"也可以进行ES Next兼容性试探。
在Node.js中使用:
执行脚本,用法要求相应的文件后缀名必须为.mjs
node --experimental-modules module1.mjs
import module1 from './module1.mjs'
另一种方法是,安装babel-cli和babel-preset-env,配置.babelrc文件后,执行./node_modules/.bin/babel-node或npx babel-node