全部代码写在一个 js 文件中,耦合度高,全局变量污染,代码复杂,难维护,不安全,所以出现了模块化。
模块化,就是将一个复杂的程序依据一定的规则/规范封装成多个文件,最终再组合在一起。模块的内部数据是私有的,通过向外部暴露接口与其他模块通信。
模块化规范是什么?
引入 js 文件越来越多,请求过多,还是会有全局变量污染、变量重名、依赖关系复杂无法保证顺序等问题,因此有了模块化规范。
模块化规范有 CommonJS、AMD、CMD、ES6 四种。
CommonJS | AMD | CMD | ES6 | |
---|---|---|---|---|
用于服务器端,即 nodejs 环境,模块加载是同步的 | 用于浏览器端,模块加载是异步的 | 用于浏览器端,模块加载是异步的类似 AMD | ||
在浏览器中 | 使用 Browserify 编译打包 | 依赖于 Require.js | 使用 Babel 将 ES6->ES5,使用 Browserify 编译打包 js |
CommonJS
CommonJS 语法
module.exports = xxx
// 或
exports.x = xxx
require("xxx")
在 node 环境中运行 CommonJS
node app.js
在浏览器中运行 CommonJS
若想在浏览器中运行 CommonJS,在 index.html 直接引入 app.js,浏览器是无法理解的,需要使用 Browserify 将 app.js 编译打包成浏览器可识别的语法。
npm install browserify -g
browserify app.js -o dist/bundle.js
<script type="text/javascript" src="./dist/bundle.js"></script>
关于 module.exports 和 exports 的区别,请看这篇你搞懂module.exports和exports了吗?
AMD
AMD 语法
// 定义没有依赖的模块
define(function(){
return module
})
// 定义有依赖的模块
// m1和m2对应依赖的模块module1和module2返回的
define([module1,module2], function(m1,m2){
return module
})
require([module1,module2], function(m1,m2){})
CMD(不常用,不重要)
CMD 语法
// 定义没有依赖的模块
define(function(require, exports, module){
exports.xxx = value
module.exports = value
})
// 定义有依赖的模块
define(function(require, exports, module){
// 引入依赖模块(同步)
var module2 = require('./module2')
// 引入依赖模块(异步)
require.async('./module3', function(m3){
})
// 暴露模块
exports.xxx = value
})
define(function(require){
var m1 = require('./module1')
m1.show()
})
ES6
ES6语法
最简单,export,import,默认导出 export default { }
在浏览器中运行ES6
安装 babel、browserify
npm i babel-cli browserify -g npm i babel-preset-es2015 --save-dev
添加 .babelrc 文件
// .babelrc { "presets": ["es2015"] }
编译、打包
babel js -d lib // 使用babel将ES6编译为ES5 browserify lib/app.js -o dist/bundle.js
页面引入打包后的文件
<script type="text/javascript" src="./dist/bundle.js"></script>