cjs的代表是commonjs,只能运行在node环境中,浏览器并不认识。所有需要webpack或者其他工程化工具
CMD代表库: Sea.js
AMD代表库: requirejs
commonjs打包话工具: browserify
各种规范支持: webpack
原生ES Moudle: vite
commonjs使用
javascript
// main.js
const util = require('./util')
function doSomething() {
console.log('Doing something...');
util.doUtilStuff();
}
module.exports = {
doSomething
}
// util.js
function doUtilStuff() {
console.log('doUtilStuff')
}
exports.doUtilStuff = doUtilStuff
commonjs可以使用2种导出方式: module.exports 和 exports。
module.exports是整个文件模块的出口对象。exports是module.exports的引用,用来简化导出操作。
加载文件规则:
-
解析文件路径,如果是 本地模块则在本地查找引入,核心模块则在内置模块中加载
-
.js : 解析为javascripte代码。 .json解析为json 对象。 .node: 编译后的二进制模块
-
加载的js文件,node会进行编译然后执行
-
加载的模块会进行缓存避免重复加载
循环引用:是指2或多个文件之间相互引用。这种情况会引发文件未初始化的问题。
javascript
// a.js
const B = require('./B')
console.log('---- Start A ----')
const say = () => {
console.log('say name ph', B.walk())
}
console.log('---- End A ----')
module.exports = {
name: 'Module A',
say
}
// b.js
const A = require('./A')
console.log('---- Start B ----')
const walk = () => {
console.log('I can ', A.name, ' when I walk')
}
console.log('---- End B ----')
module.exports = {
name: 'Module B',
walk
}
(node:46206) Warning: Accessing non-existent property 'Symbol(Symbol.toStringTag)' of module exports inside circular dependency
(node:46206)警告:在循环依赖中访问模块导出的不存在的属性'Symbol(nodejs.util.inspect.custom)'(使用' node -trace-warnings...'以显示创建警告的位置)
引发问题:会使得引用一方的代码未初始化话就引入,从而报错。
解决方案:
- 重构代码
- **延迟加载
**b.js 中的require('./A') 或者a.js中的require('./B') 放入调用时的函数中。让文件先完成初始化即可。 - 使用弱引用
commonjs的原理?为什么在文件中可以直接使用require 和 exports/module.exports?
在b.js 文件中加入 console.log('---- Start B ----', arguments.callee.toString()), 得到如下:
javascript
function (exports, require, module, __filename, __dirname) {
console.log('---- Start B ----', arguments.callee.toString())
const walk = () => {
const A = require('./A')
console.log('I can ', A.name, ' when I walk')
}
console.log('---- End B ----')
module.exports = {
name: 'Module B',
walk
}
}
什么是UMD?
UMD(Universal Module Definition)是JavaScript模块的一种通用模块定义模式。它的产生背景主要是为了解决JavaScript模块化在不同环境中的兼容性问题。随着前端开发的复杂度增加,开发者需要编写能够在多种环境下运行的代码,包括浏览器端和服务器端。然而,不同的环境支持不同的模块化规范,如AMD(异步模块定义)、CommonJS等。为了编写能够在这些环境中无缝运行的代码,UMD应运而生。
javascript
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD环境
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS环境
module.exports = factory(require('jquery'));
} else {
// 全局变量环境
root.myModule = factory(root.jQuery);
}
}(this, function ($) {
// 模块主体
function privateMethod() {
// 私有方法
}
function publicMethod() {
// 公共方法
}
return {
publicMethod: publicMethod
};
}));