2.模块化
什么叫做模块化?
将JS进行拆分,从script引入,到引入entry.js,entry作为入口,引入各个模块
CJS规范
简介
- nodejs默认的模块化规范是,每个文件就是一个模块,有自己的作用域
- node中CJS模块加载采用同步加载方式
- 通过require加载模块,通过exports或module.exports输出模块
特点
- 所有代码都是运行在模块作用域中,不会污染全局环境
- 模块可以多次加载,第一次加载时会运行模块,模块输出结果会被缓存,再次加载时会运行模块,模块输出结果会被缓存,再次加载时,会从缓存结果中直接读取模块输出结果
- 模块加载的顺序,按照其在代码中出现的顺序
- 模块输出的值是值的拷贝,类似于IIFE方案中的内部变量
cjs打包规范
- 如果要在浏览器中使用cjs规范,需要安装browserify:
npm install browserify -g
- 在使用browserify的命令进行打包:
browserify modele_test/cjs/entry.js -o dist/bundle.js
- 注意:当出现多个模块时,每个模块都需要单独进行打包-
brwoserify打包原理
- 本质还是通过自执行函数实现模块化
- 将每个模块编号,存入一个对象,每个模块标记依赖模块
- 实现了require方法,核心是通过call方法调用模块,并传入require,module,exorts方法,通过module存储模块信息,通过exorts存储模块输出信息
AMD规范
- AMD规范采用异步加载模块,允许指定回调函数
- node模块通常都位于本地,加载速度快,所以适用于同步加载
- 在浏览器环境下,模块的获取需要进行请求,因此异步加载的方式更实用
CMD规范
- CMD整合了CJS和AMD的优点,模块加载是异步的
- CMD专门用于浏览器端,
- AMD和CMD最大的问题是没有通过语法升级解决模块化
ESM规范
- ESM设计理念是希望在编译时就确定模块依赖关系及输入输出
- CJS和AMD必须在运行时才能确定依赖和输入,输出
- ESM通过import加载模块,通过export输出模块
注意:最近浏览器中,已经支持了ESM的规范了,所以我们可以直接通过script标签引入ESM规范的文件,设置type=‘module’即可
CJS规范和ESM规范对比
- CJS模块输出的是值的拷贝,ES6模块输出的是值的引用
- CJS模块时运行时加载,ES6模块是编译时输出接口
- CJS是单个值导出,ESM可以导出多个
- CJS模块为同步加载,ESM支持异步加载
- CJS的this是当前模块,ESM的this是undefined
- CJS和ESM的语法不同
脚本和模块对比
- 模块具备更多地开发效率,可读性强,复用高效
- 脚本具有更高的页面性能,而模块文件多,加载速度慢
- 模块在浏览器中运行会存在兼容性问题,要特别注意
浏览器模块化的局限
- 缺乏模块管理能力,模块分散在各个项目中
- 性能加载慢,无法在大型项目中直接使用
- 这两个问题是npm和webpack核心解决的问题