commonjs
基本使用
name.js
module.exports = "一句话";
main.js
let word = require('./name.js')
console.log('word',word)
核心理解如下
var modules = {
"./name.js": () => {
var module = {};
module.exports = "一句话";
return module.exports;
},
};
const require = (modulePath) => {
return modules[modulePath]();
};
let word = require("./name.js");
console.log(word, "word");
源码实现过程
- 初始化:定义
modules
对象 - 定义缓存对象
cache
- 定义加载模块函数
require
- 执行入口函数
//接受模块的路径为参数,返回具体的模块的内容
function require(modulePath) {
var cachedModule = cache[modulePath]; //获取模块缓存
if (cachedModule !== undefined) {
//如果有缓存则不允许模块内容,直接retuen导出的值
return cachedModule.exports;
}
//如果没有缓存,则定义module对象,定义exports属性
//这里注意!!!module = cache[modulePath] 代表引用的是同一个内存地址
var module = (cache[modulePath] = {
exports: {},
});
//运行模块内的代码,在模块代码中会给module.exports对象赋值
modules[modulePath](module, module.exports, require);
//导入module.exports对象
return module.exports;
}
esmodule
基本使用
name.js
const author = "a man";
export const age = "18";
export default author;
main.js
import author, { age } from "./name";
console.log(author, "author");
console.log(age, "age");
编译原理
前置步骤与commonjs相同,module.exports对象挂载属性做如下操作
- 初始化:定义
modules
对象 - 定义缓存对象
cache
- 定义加载模块函数
require
- 执行入口函数
- 通过setModuleTag将当前模式标记为es module +
- 将age和default代理给exports对象将其导出 +
//模块定义
var modules = {
"./src/name.js": (module, exports, require) => {
//给该模块设置tag:标识这是一个ES Module
require.setModuleTag(exports);
//通过代理给exports设置属性值
require.defineProperty(exports, {
age: () => age,
default: () => DEFAULT_EXPORT,
});
const author = "a man";
const age = "18";
const DEFAULT_EXPORT = author;
},
};
var cache = {};
function require(modulePath) {
var cachedModule = cache[modulePath];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var module = (cache[modulePath] = {
exports: {},
});
modules[modulePath](module, module.exports, require);
return module.exports;
}
//对exports对象做代理
require.defineProperty = (exports, definition) => {
for (var key in definition) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key],
});
}
};
//标识模块的类型为ES Module
require.setModuleTag = (exports) => {
Object.defineProperty(exports, Symbol.toStringTag, {
value: "Module",
});
Object.defineProperty(exports, "__esModule", {
value: true,
});
};
//以下是main.js编译后的代码
//拿到模块导出对象exports
var _name__WEBPACK_IMPORTED_MODULE_0__ = require("./src/name.js");
console.log(_name__WEBPACK_IMPORTED_MODULE_0__["default"], "author");
console.log(_name__WEBPACK_IMPORTED_MODULE_0__.age, "age");
从commonjs加载esModule
name.js
export const age = 18;
export default "author"
main.js
let obj = require("./name");
console.log(obj, "obj");
用esmodule的导出 commonjs的导入
var modules = {
"./src/name.js": (module, exports, require) => {
require.setModuleTag(exports);
require.defineProperty(exports, {
age: () => age,
default: () => DEFAULT_EXPORT,
});
const age = 18;
const DEFAULT_EXPORT = "author";
},
};
var cache = {};
function require(moduleId) {
var cachedModule = cache[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var module = (cache[moduleId] = {
exports: {},
});
modules[moduleId](module, module.exports, require);
return module.exports;
}
require.defineProperty = (exports, definition) => {
for (var key in definition) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key],
});
}
};
require.setModuleTag = (exports) => {
Object.defineProperty(exports, Symbol.toStringTag, {
value: "Module",
});
Object.defineProperty(exports, "__esModule", {
value: true,
});
};
(() => {
let obj = require("./src/name.js");
console.log(obj, "obj");
})();
从esModule加载commonjs
name.js
module.exports = "author";
main.js
import author from "./name";
console.log(author, "author");
会多一个 require.n,用于将default挂载,核心原理不变
用commonjs原理导出 esmodule引入
var modules = {
"./src/name.js": (module) => {
module.exports = "不要秃头啊";
},
};
var cache = {};
function require(modulePath) {
var cachedModule = cache[modulePath];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var module = (cache[modulePath] = {
exports: {},
});
modules[modulePath](module, module.exports, require);
return module.exports;
}
require.n = (module) => {
var getter =
module && module.__esModule ? () => module["default"] : () => module;
require.defineProperty(getter, {
a: getter,
});
return getter;
};
require.defineProperty = (exports, definition) => {
for (var key in definition) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key],
});
}
};
require.setModuleTag = (exports) => {
Object.defineProperty(exports, Symbol.toStringTag, {
value: "Module",
});
Object.defineProperty(exports, "__esModule", {
value: true,
});
};
var __webpack_exports__ = {};
(() => {
"use strict";
require.setModuleTag(__webpack_exports__);
var _name__WEBPACK_IMPORTED_MODULE_0__ = require("./src/name.js");
var _name__WEBPACK_IMPORTED_MODULE_0___default = require.n(
_name__WEBPACK_IMPORTED_MODULE_0__
);
console.log(_name__WEBPACK_IMPORTED_MODULE_0___default(), "author");
})();