CommonJs模块化实现原理ES Module模块化原理

CommonJs模块化实现原理

首先看一个案例
初始化项目

npm init
npm i webpack -D

目录结构如下

在这里插入图片描述
webpack.config.js

const path = require("path");
module.exports = {mode: "development",entry: "./src/index.js",output: {path: path.resolve(__dirname, "dist"),filename: "[name].js",},devtool: "source-map"
};

src/index.js

const b = require("./b");
const a = require("./a");
console.log(a, b)

src/a.js

let a = "这是a"
module.exports = a;

src/b.js

let b = "这是b"
module.exports = b;

build.js

const { webpack } = require("webpack");
const webpackOptions = require("./webpack.config.js");const compiler = webpack(webpackOptions);compiler.run((err, stats) => {console.log(err)
});

进行node ./build.js后查看dist文件下

(() => { var __webpack_modules__ = ({"./src/a.js": ((module) => {let a = "这是a"module.exports = a;}),"./src/b.js":((module) => {let b = '这是b'module.exports = b;})});// The module cachevar __webpack_module_cache__ = {};// The require functionfunction __webpack_require__(moduleId) {// Check if module is in cachevar cachedModule = __webpack_module_cache__[moduleId];if (cachedModule !== undefined) {return cachedModule.exports;}// Create a new module (and put it into the cache)var module = __webpack_module_cache__[moduleId] = {// no module.id needed// no module.loaded neededexports: {}};// Execute the module function__webpack_modules__[moduleId](module, module.exports, __webpack_require__);// Return the exports of the modulereturn module.exports;}var __webpack_exports__ = {};(() => {const b = __webpack_require__("./src/b.js");const a = __webpack_require__("./src/a.js");console.log(a, b);})();})()
;
//# sourceMappingURL=main.js.map

分析一下打包产物

首先看下 webpack_modules,我们在src/index.js中引入了a.js、b.js, webpack会把’src/a.js’、‘src/b.js’作为modules的key值,该模块内容作为modules的value值;

 var __webpack_modules__ = ({"./src/a.js": ((module) => {let a = "这是a"module.exports = a;}),"./src/b.js":((module) => {let b = '这是b'module.exports = b;})});

定义 __webpack_require__函数

	var __webpack_module_cache__ = {};function __webpack_require__(moduleId) {// 判断一下缓存中有没有当前modulevar cachedModule = __webpack_module_cache__[moduleId];if (cachedModule !== undefined) {// 缓存中有的话走缓存,返回cachedModule.exportsreturn cachedModule.exports;}// 缓存中没有就重新创建一个moudle,设置export对象,并放入缓存var module = __webpack_module_cache__[moduleId] = {exports: {}};// 执行模块代码, 传入当前module,根据需要传入module.exports, __webpack_require__,module.exports会在模块中赋值__webpack_modules__[moduleId](module, module.exports, __webpack_require__);// 返回module.exportsreturn module.exports;}

执行入口函数,为防止命名污染,封装成立即执行函数。

 (() => {const b = __webpack_require__("./src/b.js");const a = __webpack_require__("./src/a.js");console.log(a, b);})();

ES Module模块化原理

src/index.js

import a from './a'
import {b} from './b'
console.log(a, b);

src/a.js

const a = "这是a"
export default a

src/b.js

export const b = '这是b'

node ./build.js 之后main.js如下:

 (() => { "use strict";var __webpack_modules__ = ({"./src/a.js":((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__, {"default": () => (__WEBPACK_DEFAULT_EXPORT__)});const a = "这是a"const __WEBPACK_DEFAULT_EXPORT__ = (a);}),"./src/b.js":((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__, {b: () => (b)});const b = '这是b'})});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) {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))})();(() => {__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__ = {};(() => {__webpack_require__.r(__webpack_exports__);var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/a.js");var _b__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/b.js");console.log(_a__WEBPACK_IMPORTED_MODULE_0__["default"], _b__WEBPACK_IMPORTED_MODULE_1__.b);})();})()
;
//# sourceMappingURL=main.js.map

如果是通过export default 方式导出的,那就在 exports 对象加一个 default 属性

var __webpack_modules__ = ({"./src/a.js":((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {// 在 ESM 模式下声明 ESM 模块标识__webpack_require__.r(__webpack_exports__);// 将模块导出的内容附加的模块对象上,如果是通过export default导出,给exports的对象加default属性__webpack_require__.d(__webpack_exports__, {"default": () => (__WEBPACK_DEFAULT_EXPORT__)});const a = "这是a"const __WEBPACK_DEFAULT_EXPORT__ = (a);}),"./src/b.js":((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {__webpack_require__.r(__webpack_exports__);__webpack_require__.d(__webpack_exports__, {b: () => (b)});const b = '这是b'})});

通过__webpack_require__.r把模块标识为 ES Module
了解Symbol.toStringTag

(() => {__webpack_require__.r = (exports) => {if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });}Object.defineProperty(exports, '__esModule', { value: true });};})();

通过__webpack_require__.d对exports做代理

(() => {__webpack_require__.d = (exports, definition) => {for(var key in definition) {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))})();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/267455.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux驱动入门——编写第一个驱动

目录 前言 驱动入门知识 1.APP 打开的文件在内核中如何表示 2.打开字符设备节点时,内核中也有对应的 struct file 编写 Hello 驱动程序步骤 1.流程介绍 2.驱动代码: 3.应用层代码: 4.本驱动程序的 Makefile 内容: 5.上机…

基于JavaWeb+BS架构+SpringBoot+Vue图书个性化推荐系统的设计和实现

基于JavaWebSpringBootVue图书个性化推荐系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图 源码获取入口 Lun文目录 目 录 摘 要 I 1 绪论 1 1.1研究背景 1 1.2研究现状 1 1.3研究内容 2 2 系统关键技术 3 2.1 Spring Boot框架 3 2.2 JAVA技术 3 2.3 MY…

Java 第8章 本章作业

目录 4.通过继承实现员工工资核算打印功能 6.父类和子类中通过this和super都可以调用哪些属性和方法 8.扩展如下的BankAccount类 10.判断测试类中创建的两个对象是否相等 11.向上转型&向下转型 12.equals和的区别 15.什么是多态,多态具体体现有哪些? 16. java的动…

轻量封装WebGPU渲染系统示例<47>- 多种光源(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/MultiLightsShading.ts 当前示例运行效果: 此示例基于此渲染系统实现,当前示例TypeScript源码如下: export class MultiLightsShading {private mRscene…

多源异构数据融合是什么,在进行故障预测、诊断、辨识的时候有什么有优点和缺点!

文章目录 1、多源异构数据融合是什么2、多源异构数据融合的优点主要包括:3、多源异构数据融合进行故障辨识的缺点 1、多源异构数据融合是什么 多源异构数据融合是将来自于不同设备、传感器、系统或网络等多个数据源的数据进行整合并综合分析处理的一种技术。这种数…

Linux高级管理-基于域名的虚拟Web主机搭建

客服机限制地址 通过 Require 配置项&#xff0c;可以根据主机的主机名或P地址来决定是否允许客户端访问。在httpd服 务器的主配置文件的<Location>&#xff0c;<Directory>、<Files>、<Limit>配置段中均可以使用Require 配置 项来控制客户端的访问。使…

【产品经理】产品的实现,需要做好战略规划

产品的实现需要做好产品规划&#xff0c;而产品的规划决定了产品的方向。本文从战略规划的重要性、产品定位、设计产品架构图三个方向&#xff0c;详细地为大家梳理了产品实现的前期准备。 我们知晓了如何去发掘问题&#xff0c;并找到解决方案。 可对于问题的处理&#xff0c…

第77讲:二进制方式搭建MySQL数据库5.7版本以及错误日志管理

二进制方式搭建MySQL数据库5.7版本 前面是使用的yum的方式安装的MySQL数据库&#xff0c;在企业生产环境中大多数都用二进制方式安装。 本次使用二进制方式搭建MySQL 5.7.36版本。 1.二进制安装MySQL5.7版本 1.1.下载MySQL5.7版本的二进制文件 [rootmysql ~]# wget https://d…

【代码随想录】算法训练计划48

dp 1、198. 打家劫舍 题目&#xff1a; 输入&#xff1a;[2,7,9,3,1] 输出&#xff1a;12 偷窃到的最高金额 2 9 1 12 。 思路&#xff1a; 只有两种情况&#xff0c;递推公式就好说了,dp[i]永远都是题意&#xff0c;就是当前偷到的最大金额 func rob(nums []int) int…

市场全局复盘 20231208

一、板块成交额排名&#xff1a; 资金流入前三个板块K 线&#xff1a; 行业成交额排名&#xff1a; 个股资金流入排名&#xff1a; select 成交额排名 ,近日指标提示 ,短线主题 ,涨停分析,CODE,名称,DDE大单净量,现价,量比,连板天,周涨停,月涨停,年涨停天,连涨天,…

win11 无法登录微软账户 终极解决方案

背景&#xff1a;win11突然无法登录微软账户&#xff0c;office无法激活&#xff0c;Edge里的微软账户也无法登录&#xff0c;反馈中心也无法打开等&#xff0c;有网络&#xff0c;浏览器可以访问微软并进行登录。 试过网上的网络配置&#xff08;SSL及TLS协议勾选&#xff09…

RabbitMQ-hello

0. pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0…