文章目录
commonjs 模块代码
文件目录
// index.js入口文件
const testName = require('./testName.js')
console.log(testName)
// testName.js文件
module.exports = 'testName: xiaoMing'
生成代码
(() => {
var __webpack_modules__ = ({
"./testName.js": ((module) => {
module.exports = 'testName: xiaoMing';
})
});
// 缓存模块加载结果
var __webpack_module_cache__ = {};
// 通过__webpack_require__进行模块的加载
function __webpack_require__(moduleId) {
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var module = __webpack_module_cache__[moduleId] = {
exports: {}
};
// 在这里moduleId即为:"./testName.js",加载__webpack_modules__对象中对应的方法
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
return module.exports;
}
(() => {
// 如果加载的模块又加载了其他模块,会通过__webpack_require__递归解析
var testName = __webpack_require__("./testName.js");
console.log(testName);
})();
})()
esmodule 模块代码
文件目录
// index.js文件,删除原有代码,用下边代码覆盖
import testName, { age } from './testName.js'
console.log(testName, age)
// testName.js
export default 'test_name_xiaoMing'
export const age = 'test_age_22'
生成代码
(() => {
"use strict";
var __webpack_modules__ = {
"./testName.js": (__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
// 标识是esmoudle模块
__webpack_require__.r(__webpack_exports__);
// 通过Object.defineProperty定义导出对象的内容
__webpack_require__.d(__webpack_exports__, {
"age": () => age,
"default": () => __WEBPACK_DEFAULT_EXPORT__
});
const __WEBPACK_DEFAULT_EXPORT__ = 'test_name_xiaoMing';
var age = 'test_age_22';
}
};
var __webpack_module_cache__ = {};
// 加载模块的方法
function __webpack_require__(moduleId) {
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== undefined) {
return cachedModule.exports;
}
var module = __webpack_module_cache__[moduleId] = {
exports: {}
};
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
return module.exports;
}
(() => {
__webpack_require__.d = (exports, definition) => {
for (var key in definition) {
// 如果给出的对象中有,但要导出的对象中没有,才通过Object.defineProperty在导出对象中定义
if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key]
});
}
}
};
})();
(() => {
// 检测对象是否存在某个属性
__webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
})();
(() => {
// 标识esmodule模块的方法
__webpack_require__.r = exports => {
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, {
value: 'Module'
});
}
Object.defineProperty(exports, '__esModule', {
value: true
});
};
})();
var __webpack_exports__ = {};
(() => {
// 标识入口文件是否是esmodule
__webpack_require__.r(__webpack_exports__);
// 返回导出的内容
var _testName_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./testName.js");
console.log(_testName_js__WEBPACK_IMPORTED_MODULE_0__["default"], _testName_js__WEBPACK_IMPORTED_MODULE_0__.age);
})();
})();
-
和commonjs的区别
- 可以看到在esmodule生成的代码中,最后确定导出对象的内容是通过 Object.defineProperty 定义的,而commonjs直接添加进对象,这其实和两个模块导出内容的方式有关:
- esmodule导出的是一个引用,在内部修改后,任何地方都可以获取到它模块内最新的值,但commonjs仅仅是值的拷贝,内部修改了这个值,就不会再同步到外部
- 二者的区别如下:
// commonjs
let age = 1
let obj = { age: age }
console.log(obj.age) // 1
age = 222
console.log(obj.age) // 1
// esmodule
let age = 1
let obj = {}
Object.defineProperty(obj, 'age', {
enumerable: true,
get: () => age
})
console.log(obj.age) // 1
age = 222
console.log(obj.age) // 222
commonjs require esmodule 模块代码
文件目录:
// index.js文件,删除原有代码,用下边代码覆盖
const testName = require('./testName.js')
console.log(testName.default, testName.age)
// testName.js文件
export default 'test_name_xiaoMing'
export const age = 'test_age_22'
生成代码:
(() => {
var modules = {
"./testName.js": (module, exports, require) => {
"use strict";
require.r(exports);
// cjs 导入 esm 的内容,遵循esm的值导出规范,通过Object.defineProperty定义导出内容
require.d(exports, {
"age": () => age,
"default": () => _DEFAULT_EXPORT__
});
const _DEFAULT_EXPORT__ = 'test_name_xiaoMing';
var age = 'test_age_22';
}
};
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.d = (exports, definition) => {
for (var key in definition) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key]
});
}
};
require.r = exports => {
Object.defineProperty(exports, Symbol.toStringTag, {
value: 'Module'
});
Object.defineProperty(exports, '__esModule', {
value: true
});
};
(() => {
var testName = require("./testName.js");
// esm 默认导出的内容,需要通过['default']获取
console.log(testName["default"], testName.age);
})();
})();
esmodule import commonjs 模块代码
文件目录:
// index.js文件
import testName, { age } from './testName.js'
console.log(testName, age)
// testName.js文件
module.exports = {
age: 'age_11',
testName: 'test_xiaoMing'
}
生成代码:
(() => {
var modules = {
"./testName.js": module => {
// 导入 cjs 模块内容,遵循 cjs 值导出规范,只是值的拷贝,直接放在对象上
module.exports = {
age: 'age_11',
testName: 'test_xiaoMing'
};
}
};
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.d = (exports, definition) => {
for (var key in definition) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key]
});
}
};
require.r = exports => {
Object.defineProperty(exports, Symbol.toStringTag, {
value: 'Module'
});
Object.defineProperty(exports, '__esModule', {
value: true
});
};
// 会新增一个根据不同模块,获取导出内容的方法,如果是 esm 则 module['default'] ,如果是 cjs 则 直接返回module
// 模块会通过 require.r 来进行标识
require.n = module => {
var getter = module && module.__esModule ? () => module['default'] : () => module;
// 就是给当前的getter添加了个a属性,指向自己,作用其实就是在获取默认导出对象的时候,不需要加()执
// 行只需要getter.a便可以获取到默认导出对象
require.d(getter, {
a: getter
});
return getter;
};
var exports = {};
(() => {
"use strict";
// 判断入口文件是否是 esm
require.r(exports);
// 获取导出对象
var _testName_js_0__ = require("./testName.js");
// 这里导入的内容没有通过require.r标识,所以返回的内容直接就是一个() => module
var _testName_js_0___default = require.n(_testName_js_0__);
console.log(_testName_js_0___default(), _testName_js_0__.age);
})();
})();