共计 3566 个字符,预计需要花费 9 分钟才能阅读完成。
什么是模块化?
模块
- 现实生活中,咱们常见的手机就一个模块化设施(蕴含屏幕、芯片、内存、电磁、外壳等模块)。
- 在代码程序中,一个前端应用程序由根底组件模块、业务组件模块、网络库模块及各自工具类等模块组成。
模块化开发
实质上就是将应用程序划分成一个个 (相互依赖的) 模块来开发,而后将小模块组合起来。
- 模块中能够编写属于本人的逻辑代码,有本人的作用域,不会影响到其余的模块;
- 模块能够将本人心愿裸露的变量、函数、对象等导出给其模块应用;
益处
- 无效避免命名抵触
- 代码能最大限度复用
- 可维护性高
JavaScript 模块化标准
CommonJs 标准
- 特点:CommonJs 采纳同步加载模块形式,磁盘读取速度快。
- 语法:应用 require 援用和加载模块,exports 定义和导出模块,module 标识模块。应用 require 时须要去读取并执行该文件,而后返回 exports 导出的内容。
- 利用:服务端 node,webpack
// index.js | |
let a = require('./modA.js') | |
let b = require('./modB.js') | |
console.log('index.js-1', '执行结束', a.done, b.done) | |
// modA.js | |
exports.done = false | |
let b = require('./modB.js') | |
console.log('modA.js-1', b.done) | |
exports.done = true | |
console.log('modB.js-2', '执行结束') | |
// modB.js | |
exports.done = false | |
let a = require('./modA.js') | |
console.log('modB.js-1', a.done) | |
exports.done = true | |
console.log('modB.js-2', '执行结束') | |
/* | |
modB.js-1 false | |
modB.js-2 执行结束 | |
modA.js-1 true | |
modB.js-2 执行结束 | |
index.js-1 执行结束 true true | |
*/ |
执行程序:
- node 执行 index.js 文件,发现 require(‘./modA.js’),暂停 index.js 代码执行,进入 modA 模块
- 在 modA 中发现 require(‘./modB.js’),暂停 modA 代码执行,将已执行的局部 modA 代码缓存,随后进入 modB 模块
- 在 modB 中发现 require(‘./modA.js’),提取已缓存的局部 modA (因为 modA 代码全副执行完),执行所有的 modB 代码,结束后,缓存 modB 执行后果,执行栈返回至 modA
- 执行 modA 残余代码,结束后,缓存 modA,执行栈返回 index.js
- 在 index.js 发现 require(‘./modBjs’),提取已有的 modB 缓存,执行残余代码
AMD 标准
异步模块定义,所谓异步是指模块和模块的依赖能够被异步加载,他们的加载不会影响它前面语句的运行。无效防止了采纳同步加载形式中导致的页面假死景象。AMD 代表:RequireJS。
AMD 一开始是 CommonJS 标准中的一个草案,全称是 Asynchronous Module Definition,即异步模块加载机制。起初由该草案的作者以 RequireJS 实现了 AMD 标准,所以个别说 AMD 也是指 RequireJS。
特点:
- (1)异步加载:因为面向浏览器端,为了不影响渲染必定是异步加载。
- (2)依赖前置:所有的依赖必须写在最后的依赖数组中,速度快,然而会浪费资源,事后加载了所有依赖不论你是否用到(存在引入老本,没有思考按需加载)。
- 语法:通过 define 办法,将代码定义为模块;通过 require 办法,实现代码的模块加载。
- 利用:浏览器端,request.js。
//id:可选参数,它指的是模块的名字。//dependencies:可选参数,定义中模块所依赖模块的数组。//factory:模块初始化要执行的函数或对象 | |
//define(id?, dependencies?, factory); | |
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {exports.verb = function() {return beta.verb(); | |
//Or: | |
//return require("beta").verb();} | |
}); | |
//module:一个数组,外面的成员就是要加载的模块. | |
//callback:模块加载胜利之后的回调函数。//require([module], callback); | |
require(["a","b","c"],function(a,b,c){//code here}); |
CMD 标准
CMD 标准专门用于浏览器端,模块的加载是异步的,模块应用时才会加载执行。CMD 标准整合了 CommonJS 和 AMD 标准的特点。在 Sea.js 中,所有 JavaScript 模块都遵循 CMD 模块定义标准。
特点:
- (1)异步加载。
- (2)按需加载 / 依赖就近:用到了再援用依赖,不便了开发。
- (3)依赖于打包,加载逻辑存在于每个模块中, 扩充了模块的体积;加载速度和性能较差。
- 语法:通过 define 来定义模块,模块还依赖其余模块,在用到的中央援用即可;通过 require 办法实现代码的模块加载。
- 利用:浏览器端,sea.js。
// module1.js 文件 | |
define(function (require, exports, module) { | |
// 外部变量数据 | |
var data = 'atguigu.com' | |
// 外部函数 | |
function show() {console.log('module1 show()' + data) | |
} | |
// 向外裸露 | |
exports.show = show | |
}); | |
// module2.js 文件 | |
define(function (require, exports, module) { | |
module.exports = {msg: 'I Will Back'} | |
}); | |
// module3.js 文件 | |
define(function(require, exports, module) { | |
const API_KEY = 'abc123' | |
exports.API_KEY = API_KEY | |
}); | |
// module4.js 文件 | |
define(function (require, exports, module) {// 引入依赖模块(同步) | |
var module2 = require('./module2') | |
function show() {console.log('module4 show()' + module2.msg) | |
} | |
exports.show = show | |
// 引入依赖模块(异步) | |
require.async('./module3', function (m3) {console.log('异步引入依赖模块 3' + m3.API_KEY) | |
}) | |
}); | |
// main.js 文件 | |
define(function (require) {var m1 = require('./module1') | |
var m4 = require('./module4') | |
m1.show() | |
m4.show()}) |
ESM 标准
ES6 模块的设计思维,是尽量的动态化,使得编译时就能确定模块的依赖关系,以及输出和输入的变量。所以说 ES6 是编译时加载,不同于 CommonJS 的运行时加载(理论加载的是一整个对象),ES6 模块不是对象,而是通过 export 命令显式指定输入的代码,输出时也采纳动态命令的模式。
特点:
- (1)动态编译:在编译的时候就能确定依赖关系,以及输出和输入的变量。
- (2)依赖前置:所有的依赖必须写在最后的依赖数组中,速度快,然而会浪费资源,事后加载了所有依赖不论你是否用到(存在引入老本,没有思考按需加载)。
- 语法:模块性能次要由两个命令形成:export 和 import。export 命令用于规定模块的对外接口,import 命令用于输出其余模块提供的性能。
- 利用:浏览器端,node
// 模块 test.js | |
var info = { | |
name: 'name', | |
age: 18 | |
} | |
export default info | |
export var name= '陆地饼干' | |
export var age = 18 | |
// 援用 | |
import person, {name, age as myAge} from 'test.js' | |
console.log(person); // {name: 'name', age: 18} | |
console.log(name+ '=' + myAge); // 陆地饼干 =18 |
commonJS 和 ES Module 区别
ES Module 动态引入,编译时引入;Commonjs 动静引入,执行时引入。
具体查看:https://zhuanlan.zhihu.com/p/161015809
正文完