模块化是指把一个复杂的系统分解到多个模块以方便编码。
CommonJS
CommonJS是同步加载模块,以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。
每个模块内部,module代表当前模块。module变量是一个对象,属性exports是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。
核心思想:通过require同步加载依赖的其他模块,通过 module.exports 导出需要暴露的接口。
// 调用一
var myModule = require('module');
myModule.sayHello();
// module.js
module.exports.sayHello = function() {
console.log('Hello ');
};
// 调用二
var sayHello = require('module');
sayHello();
// module.js
module.exports = sayHello();
CommonJS的优点
代码可复用于 Node.js 环境下并运行,例如做同构应用;通过 NPM 发布的很多第三方模块都采用了 CommonJS 规范。- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
缺点
代码无法直接运行在浏览器环境下,必须通过工具转换成标准的 ES5。
AMD
AMD 全称 Asynchronous Module Definition,即异步模块定义。
它采用异步的方式去加载依赖的模块,模块的加载不影响语句的执行。所有依赖这个模块的语句都定义在一个回调函数中,等模块加载完成,回调函数才会运行。
/**
* id:模块名称
* dependencies:是个定义中模块所依赖模块的数组,默认为 [“require”, “exports”, “module”]
* factory:为模块初始化要执行的函数或对象
*/
define(id?, dependencies?, factory);
// 定义一个模块
define('module', ['dep'], function(dep) {
return exports;
});
// 导入和使用
require(['module'], function(module) {
})
AMD 的优点在于:
- 可在不转换代码的情况下直接在浏览器中运行;
- 可异步加载依赖;
- 可并行加载多个依赖;
- 代码可运行在浏览器环境和 Node.js 环境下。
AMD 的缺点在于JavaScript 运行环境没有原生支持 AMD,需要先导入实现了 AMD 的库后才能正常使用。
CMD
UMD
ES6 模块化
它将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
// 导入
import { readFile } from 'fs';
import React from 'react';
// 导出
export function hello() {};
export default {
// ...
};
缺点:目前无法直接运行在大部分 JavaScript 运行环境下,必须通过工具转换成标准的 ES5 后才能正常运行。
样式文件中的模块化
// util.scss 文件
// 定义样式片段
@mixin center {
// 水平竖直居中
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
// main.scss 文件
// 导入和使用 util.scss 中定义的样式片段
@import "util";
#box{
@include center;
}