Js模块化
【成长期】原始的js模块化
// 使用立即执行函数 + var的方式
// 例如 有base.js 和 main.js两个文件
// 其中main.js需要调用base.js中的函数 可以这样写/** base.js */
var baseModule = (function () {var a = 1;var b = 11;var c = 22;console.log(a, b, c);function addA() {a++;}return {addA,}
})()/** main.js */
baseModule.addA();
【成熟期】CommonJs
// base.js
var a = 1;
var b = 2;
var c = 3;module.exports = {a, b, c
}// main.js
const base = require('./base.js');
console.log(base.a,base.b,base.c
)/** 编译后实际执行的是以下的代码 */
// base.js
(function (exports, require, module, __filename, __dirname) {...let count = 0;const increase = () => ++count;module.exports = {increase,count}return module.exports;}
).call(thisValue, module.exports, require, module, __filename, __dirname)// main.js
(function (exports, require, module, __filename, __dirname) {...}
).call(thisValue, exports, require, module, __filename, __dirname)
● 缺点
○ 无法动态加载模块只支持同步加载模块
○ 因为commonJs是为了Nodejs设计的 没有异步问题不大
○ 服务器端同步加载模块的方案
面试题:
● module.exports跟export之间的关系
○ 两个指向的是同一个东西 module.exports = exports
○ module.exports可以支持只导出单个变量或者函数
● 如何避免循环引用
○ commonJs本身做了缓存 当require过某个文件时 它会将结果缓存下来
○ 下次使用就不用重新再走一遍
○ 可以重新设计该模块
AMD async module define
非同步加载模块
允许异步加载 define(id, [depends], callback); require([module], callback);
// 定义模块的方式
define('amdCountModule',['depModule1', 'depModule2'],(depModule1, depMOdule2) => {return {...}}
)require(['amdCountModule'],amdCountModule => {amdCountModule.xxx... }
)// 如果再AMD中使用require的方式加载同步模块可以么?
define(require => {...,const depModule1 = require('depModule1');const depModule2 = require('depModule2');exports.xx = xx;exports.cc = cc;
})
CMD
define(function(require, exports, module) {let depModule1 = require('depModule1');deoModule1.xxx();if (xxx) {let depModule2 = require('depModule2');}}
)
UMD universal module define
…太复杂了
ESM ecmscript module
import xxx from '..';import { xx } from '..';export xxx;export default {...
}// 在nodejs中使用esm
// 首先命名要改成 .mjs结尾
// node >= 13.2.0// 如何支持异步加载
import('...'); // 返回的是一个promise