模块化
将大程序拆分成互相依赖的小文件,再用简单的方法将它们拼装起来。
为何需要模块化
原始情况
规模较大的前端项目,不可能使用一个 JS 文件就能写完,不同的功能需要封装到不同的 JS 文件中,这样便于开发也便于维护。
<script src="./util.js"></script>
<script src="./a-util.js"></script>
<script src="./a.js"></script>
这样使用的问题:
- 这些代码中的函数必须是全局变量,才能暴露给使用方,但是全局变量会造成很严重的污染,很容易覆盖别人的或者被别人覆盖;并且依赖关系不明确,可能会出现加载问题。
使用模块化之后
ES6 模块功能主要由 export 和 import 两个命令构成,export 用于规定模块的对外接口,impotr 用于输入其他模块的功能。
a.js
// 1. 使用 export
export const name = "zhangsan";
export const age = "18";
// 2. 使用 export default
//(export default 输出一个叫作 default 的变量或者方法,可以给他取任意名字)function fn(){}
export default fn
b.js
// 1.
import {name, age} from './a.js'
// 或者
import * as person from './a.js'
console.log(person.name, person.age)
//2.
import xxx from './a.js'
}
AMD
AMD 规范全称是 Asynchronous Module Definition,即异步模块加载机制。代表工具是 require.js
,使用之后它会定义两个全局函数:
- define 定义一个变量并返回,可供其他 js 引用
- require 引用其他已经定义好的变量
- 依赖的代码会自动、异步加载
首先是 a.js
define(function () {
return {fn: function (data) {
// code
console.log(data)
}
}
})
然后是 b.js
require(['./a.js'], function (a) {a.fn('A')
})
然后在页面中引用 <script src="js/require.js" data-main="./a.js"></script>
,运行时注意,各个 js 文件会异步加载
CommonJS
CommonJS 是 nodejs 中模块定义的规范,但是这种规范越来越被放在前端开发来使用(当然这需要构建工具的编译),原因如下
- 前端开发依赖的插件和库,都可以从 npm 中获取
- 构建工具的高度自动化,使得使用 npm 的成本非常低
CommonJS 不会异步加载各个 JS,而是同步一次性加载出来。CommonJS 的一个模块就是一个脚本文件
我们先来看一下 CommonJS 的输入和输出都是什么规范。
util.js
module.exports = {getFormatDate: function (date, type) {if (type === 1) {return '2017-06-15'}
if (type === 2) {return '2017 年 6 月 15 日'}
}
}
a-util.js
var util = require('util.js')
module.exports = {aGetFormatDate: function (date) {return util.getFormatDate(date, 2)
}
}
AMD 和 CommonJS 的不同使用场景
CommonJS 解决的问题和 AMD 一样,不过是不同的标准, 不同的工具使用场景不一样而已。
- 使用 AMD:各种代码都是自己定义的,不用依赖于 npm
- 使用 CommonJS:依赖于 npm