webpack源码简版

  1. Compiler.js:负责整个编译过程的控制和管理,包含compiler构造函数,在构造函数中获取webpack.config.js的出口、入口、参数等
  2. Bundler.js:引入webpack.config.js和compiler.js,创建compiler实例化对象并传入options。
  3. 拿到webpack配置参数后开始根据入口文件解析文件内容(fs.readFileSync读取文件内容)
    (1). @babel/parser:将文件内容的的源代码解析成AST语法树,AST语法树的节点包含了文件依赖的文件名称。(type,start,end,…)
    (2). @babel/traverse:提取依赖的文件名称到一个数组中
    (3). @babel/core:通过babel.transformFromAst方法将ast转换成浏览器可执行的代码;返回一个对象{文件名,依赖数组,可执行代码},作为依赖图的一个节点
    (4). 遍历入口文件的依赖数组,数组中是文件名,递归执行上述方法直到找到所有的依赖,然后返回依赖对象。
  4. Bundler.js使用compiler对象的run方法生成依赖对象,并通过bundle方法解析graph(依赖图对象),使用eval方法来调用code并输出分发代码
  5. Bundler.js使用fs.writeFileSync将分发代码输出到文件中,生成bundle。

complier.js

// 文件操作模块,读取文件内容
const fs = require("fs");
const path = require("path");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const babel = require("@babel/core");
module.exports = class Complier {constructor(options) {const { entry, output } = options;this.entry = entry;this.output = output;} // 拿到参数、执行、分析入口文件run() {const mainAsset = this.createAsset(this.entry);const queue = [mainAsset];for (const asset of queue) {Object.values(asset.dependencies).forEach((filename) => {const child = this.createAsset(filename);queue.push(child);});}console.log(queue);return queue;}// 开始编译,构建ast语法树 filename: ./src/index.jscreateAsset(filename) {const content = fs.readFileSync(filename, "utf-8");const ast = parser.parse(content, { sourceType: "module" });// 创建依赖const dependencies = {};traverse(ast, {ImportDeclaration: ({ node }) => {// 获取文件的路径名如 './src/index.js' dirname='./src'const dirname = path.dirname(filename);const absPath = path.join(dirname, node.source.value);dependencies[node.source.value] = absPath;},});// 将ast转换成代码 // https://www.babeljs.cn/docs/babel-coreconst { code } = babel.transformFromAst(ast, null, {presets: ["@babel/preset-env"],});return { filename, dependencies, code };}
};

bundler.js

// 引入配置
const fs = require('fs');
const path = require('path')
const options = require('../webpack.config')const complier = require('./complier')const { entry, output } = optionsfunction bundle(graph){// 得到以依赖文件名的对象 let modules = {};graph.forEach(item => {modules[item.filename] = {dependencies: item.dependencies,code: item.code}})modules = JSON.stringify(modules)const result = `(function(graph){function require(filepath) {function localRequire(relativePath) {// 将代码中的require中的路径转换成dependencies存储的带文件夹名的路径return require(graph[filepath].dependencies[relativePath])}var exports = {}function fn(require, exports, code) {eval(code)}fn(localRequire, exports, graph[filepath].code)return exports}require('${entry}')})(${modules})`return result
}function createFile(code) {fs.writeFileSync(path.join(output.path, output.filename), code)
}const graph = new complier(options).run()
const result = bundle(graph)
createFile(result)

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

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

相关文章

Java自定义校验注解实现List、set集合字段唯一性校验

文章目录 一: 使用场景二: 定义FieldUniqueValid注解2.1 FieldUniqueValid2.2 注解说明2.3 Constraint 注解介绍2.4 FieldUniqueValid注解使用 三:自定义FieldUniqueValidator校验类3.1 实现ConstraintValidator3.2 重写initialize方法3.3 重…

STM32(HAL)多串口进行重定向(printf函数发送数据)

目录 1、简介 2.1 基础配置 2.1.1 SYS配置 2.1.2 RCC配置 2.2 串口外设配置 2.3 项目生成 3、KEIL端程序整合 4、效果测试 1、简介 在HAL库中,常用的printf函数是无法使用的。本文通过重映射实现在HAL库多个串口可进行类似printf函数的操作。 2.1 基础配置 2.…

【c++】VSCode配置 c++ 环境(重新制作)

上一篇帖子【c】VSCode配置 c 环境(小白教程)_vscode配置c/c环境_StudyWinter的博客-CSDN博客 大火,但是依旧有很多小伙伴反应没有配好环境,今天打算重新写一个教程,希望对大家有帮助。 1 MinGW下载安装 在CSDN上传了…

实现邮箱管理之gmail邮箱、office365(Azure)邮箱之披荆斩棘问题一览

要进行Office365邮箱的授权对接,你需要先申请一个应用,并获取授权访问令牌。 以下是一个简单的步骤: 登录 Azure 门户:https://portal.azure.com/创建一个新的应用程序,或者使用现有的应用程序。要创建新的应用程序&…

React Native从文本内容尾部截取显示省略号

<Textstyle{styles.mMeNickname}ellipsizeMode"tail"numberOfLines{1}>{userInfo.nickname}</Text> 参考链接&#xff1a; https://www.reactnative.cn/docs/text#ellipsizemode https://chat.xutongbao.top/

【ASP.NET MVC】使用动软(一)(9)

一、解决的问题 前文为解决数据库操作设计的 TestMysql 类&#xff0c;仅简单地封装了一个Query函数&#xff0c;代码如下&#xff1a; public class TestMysql{public static string SqlserverConnectStr "server127.0.0.1;charsetutf8;user idroot;persistsecurityin…

Redis 在电商秒杀场景中的应用

Redis 在电商秒杀场景中的应用 一、简介1.1 简介1.2 场景应用 二、Redis 优势与挑战2.1 优势2.2 秒杀场景的挑战 三、应用场景分析3.1 库存预热代码示例 3.2 分布式锁3.3 消息队列 四、系统设计方案4.1 架构设计4.2 技术选型4.3 数据结构设计 五、Redis 性能优化5.1 集群部署5.…

数据库数据恢复-Oracle数据库文件出现坏块的数据恢复案例

Oracle数据库故障&初检&分析&#xff1a; 打开Oracle数据库时报错&#xff0c;报错信息&#xff1a;“system01.dbf需要更多的恢复来保持一致性&#xff0c;数据库无法打开”。用户急需恢复zxfg用户下的数据。 出现上述报错的可能原因包括&#xff1a;控制文件损坏、数…

C高级--day3(shell中的输入、命令置换符、数组、算数运算、分支结构)

#!/bin/bash pls ~/ -l | grep "^-" | wc -l qls ~/ -l | grep "^d" | wc -l echo "普通文件个数&#xff1a;$p" echo "目录文件个数&#xff1a;$q"#!/bin/bash read file posexpr index $file \. strexpr substr $file $((pos1)) 2…

什么是Java中的Maven?

Java中的Maven&#xff0c;可以简单理解为“一个神奇的工具”&#xff0c;它可以自动帮你管理Java项目的依赖关系&#xff0c;让你不再为手动下载、配置各种库而烦恼。想象一下&#xff0c;你正在写一个Java项目&#xff0c;突然发现需要引入一个名为"第三方库"的模块…

视频是如何做成gif动图的?1分钟快速转gif动画

常见的电影、电视剧等视频体积较大不易于传输和保存。为了方便大家使用可以将视频制作成GIF&#xff0c;可直接发送给对方非常的方便。那么&#xff0c;要怎么将视频转换成gif动画呢&#xff1f;很简单&#xff0c;使用专业的gif图片在线制作工具–GIF中文网&#xff0c;无需下…

企业电子招投标采购系统java spring cloud+spring boot功能模块功能描述+数字化采购管理 采购招投标

​功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…

如何加深Java理解的思考--20230805

目录 一、Java的深度理解二、计算机科学基础三、知识系统结构化和基础化四、学习大牛的开发实践经验与思维逻辑&#xff0c;了解前沿新技术栈、新的解决方案&#xff0c;并批判性地吸收消化。注意思维逻辑很重要&#xff0c;很重要&#xff0c;很重要。很多时候这个东西需要自己…

Git 用户名邮箱的全局配置和单仓库配置(不同项目使用不同账号登录)

Git 用户名邮箱的全局配置和单仓库配置(不同项目使用不同账号登录) 需求 因工作和个人的仓库地址、用户名和邮箱都不一样,很多时候一个git账号无法满足工作和个人学习并行的需求。 全局用户名和邮箱是本地 git 客户端的变量&#xff0c;可配置&#xff0c;不随 git 库而改变…

【IDEA】常用插件清单

【IDEA】常用插件清单 arthas ideaCodeium: AI Autocomplete for xxxCommit-MessageGenerateAllSetterMaven HelperMybatisPlusOne Dark themePDF ViewerRainbow BracketsRestfulToolSequenceDiagramSonarLintTranslation arthas idea 快捷生成arthas命令 Codeium: AI Autoc…

微信云托管(本地调试)⑥:nginx、vue刷新404问题

一、nginx默认路径 1.1、默认配置文件路径&#xff1a;/etc/nginx/nginx.conf 1.2、默认资源路径&#xff1a;/usr/share/nginx/html/index.html 二、修改nginx.conf配置 &#xff08;注意配置中的&#xff1a;include /etc/nginx/conf.d/*.conf; 里面包了一个server配置文件…

大数据面试题:HBase的读写缓存

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 参考答案&#xff1a; HBase上RegionServer的cache主要分为两个部分&#xff1a;MemStore & BlockCache。 MemStore是写缓存&#xff0c;Block…

【flink】开启savepoint

先启动一个任务 flink run -c com.yang.flink.CDCJob test-cdc.jar开启savepoint 命令&#xff1a; flink savepoint JobID 文件地址 flink savepoint e929a11d79bdc5e6f140f2cfb92e1335 file:///workspace/flinkSavepoints/backend这样就开启好了 操作中的错误 详细信…

Day10-作业(SpringBootWeb案例)

作业1&#xff1a;完成课上预留给大家自己完成的功能 【部门管理的修改功能】 注意&#xff1a; 部门管理的修改功能&#xff0c;需要开发两个接口&#xff1a; 先开发根据ID查询部门信息的接口&#xff0c;该接口用户查询数据并展示 。(一定一定先做这个功能) 再开发根据ID…

锁策略, cas 和 synchronized 优化过程总结

目录 一、锁策略 1. 乐观锁和悲观锁 2. 读写锁 3. 重量级锁和轻量级锁 4. 自旋锁 5. 公平锁和非公平锁 6.可重入锁 vs 不可重入锁 二、CAS 1. CAS 是怎么实现的 1) 实现原子类 2) 实现自旋锁 3. CAS 的 ABA 问题 三、Synchronized 原理 1.Synchronized 加锁工作过程 3.1 偏向…