背景
面试中可能会被问到模块化,类似:谈谈模块化的历程?AMD和CMD的区别?这里整理一下。
模块化是什么
编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。
进化史
- 简单封装:Namespace 模式
- 匿名函数:IIFE 模式(立即执行函数)
- 模块模式:引入依赖
- 现代模块化的基石
把代码进行模块化拆分的好处:
- 提高了代码的复用性
- 提高了代码的可维护性
- 可以实现按需加载
- 避免命名冲突(减少空间污染)
实现方式: 页面引入
<script>
加载资源
进而引发的问题
请求过多
依赖模糊
难以维护
模块化规范
CommonJS
说明:
- 每个文件(JS文件)都可当做一个模块
- 在服务器:模块的加载是运行时同步加载的(可能会有阻塞)
- 在浏览器:模块需要提前编译打包处理
基本语法:
//暴露模块 module.exports = value exports.xxx = value //引入模块 require(xxx) 第三方模块:xxx 为模块名 自定义模块:xxx 为模块文件路径
服务器端实现:
Node.js nodejs.cn/
浏览器端实现:
Browserify 称为 CommonJS 的浏览器端的打包工具
全局安装:
npm installl browserify -g // 打包文件路径 输出文件路径 bundle打包的意思,打包之前,dist这个文件一定要存在!!! browserify js/src/app.js -o js/dist/bundle.js
最终index页面引入的实际上是打包好的bundle.js文件
AMD
专门用于浏览器端,模块的加载是异步的
Asynchronous Module Definition 异步模块加载机制
定义暴露模块
//定义没有依赖的模块 define(function(){ return 模块 }) //定义有依赖的模块,第一个参数为数组 define(['module1', 'module2'], function(m1, m2) { return 模块 }) //引入使用模块 require(['module1', 'module2'], function (m1, m2) { //使用 m1/m2 })
ES6模块
- es6.ruanyifeng.com/
- 依赖模块需要编译打包处理
基本语法
- 导出模块:export
- 导入模块:import
实现(浏览器端)
- 使用 Babel 将 ES6 的代码编译为 ES5 代码
- 使用 Browserify 编译打包 js
npm install babel-cli -g npm install babel-preset-es2015 --save-dev npm install babel-preset-env
Babel的配置文件是.babelrc,存放在项目的根目录下。使用Babel的第一步,就是配置这个文件。
该文件用来设置转码规则和插件,基本格式如下。
{ "presets": [], "plugins": [] }
presets字段设定转码规则,官方提供以下的规则集,你可以根据需要安装。
# ES2015转码规则 $ npm install --save-dev babel-preset-es2015 # react转码规则 $ npm install --save-dev babel-preset-react # ES7不同阶段语法提案的转码规则(共有4个阶段),选装一个 $ npm install --save-dev babel-preset-stage-0 $ npm install --save-dev babel-preset-stage-1 $ npm install --save-dev babel-preset-stage-2 $ npm install --save-dev babel-preset-stage-3
然后,将这些规则加入.babelrc。
{ "presets": [ "es2015", "react", "stage-2" ], "plugins": [] }
babel相关知识
$babel js/src -d js/build js/src/main.js -> js/build/main.js js/src/module1.js -> js/build/module1.js js/src/module2.js -> js/build/module2.js js/src/module3.js -> js/build/module3.js browserify js/build/main.js -o js/dist/bundle.js
UMD
规范
说明
Universal Module Definition
兼容多个运行环境的统一模块化规范
github.com/umdjs/umd
实现
Babel 打包
总结
CMD这里没记录,不怎么重要
AMD 推崇依赖模块前置,CMD 推崇依赖模块就近
require是对模块的复制,import是对模块的引用
AMD/CMD/CommomJS 模块化规范是运行时加载,ES6 模块化规范是编译时输出接口