网站首页 > 技术文章 正文
1. 同步加载
没有依赖
src\index.js
Bash
console.log(title)
复制代码
bundle.js
Bash
//导出对象
var exports = {}
//模块内容
console.log(title)
复制代码
打包模块分析
src\index.js
let title = require("./title.js");
console.log(title);
复制代码
src\title.js
module.exports = "title"
复制代码
bundle.js
未加入缓存
//模块定义
//key是模块ID,也就是模块相对于相前根目录的相对路径
var modules = {
"./src/title.js": (module) => {
module.exports = "title"
},
}
//加载模块,执行 modules 对应的函数
function require(moduleId) {
var module = {
exports: {},
}
modules[moduleId](module, module.exports, require)
return module.exports
}
//入口
var exports = {}
let title = require("./src/title.js")
console.log(title)
复制代码
2. 兼容性实现
2.1 common.js 加载 common.js
2.1.1 index.js
let title = require("./title")
console.log(title.name)
console.log(title.age)
复制代码
2.1.2 title.js
exports.name = "title_name"
exports.age = "title_age"
复制代码
2.1.3 bundle.js
;(() => {
//需要加载的模块
var modules = {
"./src/title.js": (module, exports) => {
exports.name = "title_name"
exports.age = "title_age"
},
}
//缓存
var cache = {}
//require 方法
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
}
// 入口
var exports = {}
;(() => {
let title = require("./src/title.js")
console.log(title.name)
console.log(title.age)
})()
})()
复制代码
2.2 common.js 加载 ES6 modules
2.2.1 index.js
let title = require("./title")
console.log(title)
console.log(title.age)
复制代码
2.2.2 title.js
export default "title_name"
export const age = "title_age"
复制代码
2.2.3 bundle.js
去除了自执行函数和模块缓存
- 打包前面是 commonjs 打包后不需要变,打包前是 esmodule 打包后得变
/**
* 如果原模块是esmodule
* 先执行require.r
* 再执行require.d
*/
var modules = {
"./src/title.js": (module, exports, require) => {
//1.声明或者说表示当前的模块原来是一个es module
require.r(exports)
//2. 定义属性
require.d(exports, {
age: () => age,
default: () => DEFAULT_EXPORTS, //值是一个getter
})
//默认导出
const DEFAULT_EXPORTS = "title_name"
//命名导出
const age = "title_age"
},
}
/**
* 执行modules对象对应的模块函数
* @param {*} moduleId 模块Id
* @returns module.exports
*/
function require(moduleId) {
var module = {
exports: {},
}
modules[moduleId](module, module.exports, require)
return module.exports
}
/**
* 给exports 上面定义属性
* @param {*} exports 导出对象
* @param {*} definition 定义的属性
*/
require.d = (exports, definition) => {
//遍历key
for (var key in definition) {
//在 definition 上不在 exports 上就赋值
if (require.o(definition, key) && !require.o(exports, key)) {
// 给exports 上面定义属性 geT 获取
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key],
})
}
}
}
//对象自身属性中是否具有指定的属性
require.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
/**
* 给exports 声明 Symbol.toStringTag为Module ,__esModule 未true
* @param {*} exports
*/
require.r = (exports) => {
if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, {
value: "Module",
})
}
Object.defineProperty(exports, "__esModule", {
value: true,
})
}
var exports = {}
let title = require("./src/title.js")
console.log(title)
console.log(title.default)
console.log(title.age)
复制代码
2.3 ES6 modules 加载 ES6 modules
2.3.1 index.js
import name, { age } from "./title"
console.log(name)
console.log(age)
复制代码
2.3.2 title.js
export default name = "title_name"
export const age = "title_age"
复制代码
2.3.3 bundle.js
/**
* 如果原模块是esmodule
* 先执行require.r
* 再执行require.d
*/
var modules = {
"./src/title.js": (module, exports, require) => {
//1.声明或者说表示当前的模块原来是一个es module
require.r(exports)
//2. 定义属性
require.d(exports, {
age: () => age,
default: () => _DEFAULT_EXPORT__,
})
// 此处为了实现Livbinding做准备
const _DEFAULT_EXPORT__ = (name = "title_name")
const age = "title_age"
},
}
var cache = {}
/**
* 执行modules对象对应的模块函数
* @param {*} moduleId 模块Id
* @returns module.exports
*/
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
}
/**
* 给exports 上面定义属性
* @param {*} exports 导出对象
* @param {*} definition 定义的属性
*/
require.d = (exports, definition) => {
for (var key in definition) {
if (require.o(definition, key) && !require.o(exports, key)) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key],
})
}
}
}
require.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
/**
* 给exports 声明 Symbol.toStringTag为Module ,__esModule 未true
* @param {*} exports
*/
require.r = (exports) => {
if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, {
value: "Module",
})
}
Object.defineProperty(exports, "__esModule", {
value: true,
})
}
//入口
var exports = {}
//标明是esModule模块
require.r(exports)
//加载对应的模块
var _title_0__ = require("./src/title.js")
//取值
console.log(_title_0__["default"])
console.log(_title_0__.age)
复制代码
2.4 ES6 modules 加载 common.js
2.4.1 index.js
import name, { age } from "./title"
console.log(name)
console.log(age)
复制代码
2.4.2 title.js
module.exports = {
name: "title_name",
age: "title_age",
}
复制代码
2.4.3 bundle.js
/**
* 如果原模块是esmodule
* 先执行require.r
* 再执行require.d
*/
var modules = {
"./src/title.js": (module, exports, require) => {
//1.声明或者说表示当前的模块原来是一个es module
require.r(exports)
//2. 定义属性
require.d(exports, {
age: () => age,
default: () => _DEFAULT_EXPORT__,
})
// 此处为了实现Livbinding做准备
const _DEFAULT_EXPORT__ = (name = "title_name")
const age = "title_age"
},
}
var cache = {}
/**
* 执行modules对象对应的模块函数
* @param {*} moduleId 模块Id
* @returns module.exports
*/
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
}
/**
* 给exports 上面定义属性
* @param {*} exports 导出对象
* @param {*} definition 定义的属性
*/
require.d = (exports, definition) => {
for (var key in definition) {
if (require.o(definition, key) && !require.o(exports, key)) {
Object.defineProperty(exports, key, {
enumerable: true,
get: definition[key],
})
}
}
}
require.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
/**
* 给exports 声明 Symbol.toStringTag为Module ,__esModule 未true
* @param {*} exports
*/
require.r = (exports) => {
if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, {
value: "Module",
})
}
Object.defineProperty(exports, "__esModule", {
value: true,
})
}
//入口
var exports = {}
//标明是esModule模块
require.r(exports)
//加载对应的模块
var _title_0__ = require("./src/title.js")
//取值
console.log(_title_0__["default"])
console.log(_title_0__.age)
复制代码
3 总结
核心方法
- **modules 对象 ** key 是模块 ID,也就是模块相对于相前根目录的相对路径 值为对应加载模块的内容函数
- require 方法 执行 modules 对象对应的模块函数 返回 modules.exports 对象
- require.d 方法 通过 defineProperty 给 exports 上设置属性 get 获取
- require.o 方法 对象自身属性中是否具有指定的属性
- require.r 方法 标明该模块是 esModele 模块
- require.n 方法 返回函数兼容性处理默认值 ,esModule 模块 是的返回 module["default"] 否则 commonjs 模块返回本身
兼容处理
- common.js 加载 common.js 直接调用 require 方法 执行 modules 对象对应的函数返回 modules.exports 对象
- common.js 加载 ES6 modules
- 直接调用 require 方法
- 执行 modules 对象对应的函数 调用 require.r 方法 标明该模块为 esModule 调用 require.d 方法 给 export 对象赋值
- 返回 modules.exports
- ES6 modules 加载 ES6 modules
- 模块入口 调用 require.r 标明是 esModule 模块
- 调用 require 方法 加载模块 调用 require.r 标明被加载的模块是 esModule 调用 require.d 方法 给 export 对象赋值
- 返回 加载的内容 modules.exports
- ES6 modules 加载 common.js
- 模块入口 调用 require.r 标明是 esModule 模块、
- 调用 require 方法 加载模块 返回对应模块内容
- 兼容处理返回的默认值 调用 require.n
- 上一篇: 前端工程化-webpack 分包的方式有哪些?
- 下一篇: 前端铜九铁十面试必备八股文——工程化
猜你喜欢
- 2025-05-02 前端铜九铁十面试必备八股文——工程化
- 2025-05-02 前端工程化-webpack 分包的方式有哪些?
- 2024-09-14 【前端工程化】构建多页面应用:Vite + Vue3 实战与自动化脚本详解
- 2024-09-14 前端越来越后端化,工程化?2020年你到底需要注意些什么?
- 2024-09-14 吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【下】
- 2024-09-14 前端工程化中的自动化测试有什么重要性?
- 2024-09-14 前端工程化 → 深入SDK架构设计
- 2024-09-14 从业务组件库看前端工程化
- 2024-09-14 前端工程师常见面试题(前端进阶)——前端工程化
- 2024-09-14 吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【中】
你 发表评论:
欢迎- 05-30为什么说网上的md5加密解密站都是通过彩虹表解密的?
- 05-30一文读懂md5,md5有什么用,什么是md5加盐
- 05-30Java md5加密解密数据
- 05-30MD5是什么?如何进行MD5校验?
- 05-30专家教你简单又轻松的MD5解密方法,一看就会
- 05-30多学习才能多赚钱之:vscode怎么安装插件
- 05-30VSCode无限画布模式(可能会惊艳到你的一个小功能)
- 05-30VSCode神级Ai插件Cline:从安装到实战【创建微信小程序扫雷】
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)