IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> webpack解析初探 -> 正文阅读

[JavaScript知识库]webpack解析初探

最近花了一点时间探究webpack5的源码,通过网上的一些文章的辅助去更好的理解这个项目。接下来分析一个常规的解析过程。

首先是是使用vscode的Node调试,通过vscode的run?and?debug添加调试配置,默认生成的launch.json文件如下{

????"version":?"0.2.0",

????"configurations":?[

????????{

????????????"type":?"pwa-node",

????????????"request":?"launch",

????????????"name":?"Launch?Program",

????????????"skipFiles":?[

????????????????"<node_internals>/**"

????????????],

????????????"program":?"${workspaceFolder}\\mytest\\index.js"

????????}

????]

}

配置program调试入口,然后点击三角形按钮就可以调试代码。

?

?

如图在新建了一个mytest的文件夹下创建一个index.js作为调试的入口,掉用lib/index.js。引入webpack在lib/webpack.js中导出函数,调用这个函数一步步往下执行。

在开始之前我们先来了解一下Hooks类使用的是tapable,?它包含几个方法SyncHook,

????SyncBailHook,?

????AsyncParallelHook,

????AsyncSeriesHook

通过tap注册事件和回调,并通过call,callAsync,promise.then来触发。当然还可以注册拦截器来监听hook执行的各个阶段。

Tapable是webpack的精髓,通过hook注册和触发事件,贯穿整个构件解析的生命周期,后面的解析我们会讲到,compiler以及compiler.compilation都注册了很多操作的Hooks.

接下来我们正是进入源码,lib/webpack.js中导出的函数,主要是create函数创建并返回compiler实例和watch标记以及watchOptions配置。

当我们的调用的函数存在回调是会判断是否是watch,是的话执行compiler.watch,否则执行compiler.run。

const?{?compiler,?watch,?watchOptions?}?=?create();

????????????????if?(watch)?{

????????????????????compiler.watch(watchOptions,?callback);

????????????????}?else?{

????????????????????compiler.run((err,?stats)?=>?{

????????????????????????compiler.close(err2?=>?{

????????????????????????????callback(err?||?err2,?stats);

????????????????????????});

????????????????????});

????????????????}

????????????????return?compiler;

可以构件单个compiler调用的是createCompiler,后者多个createMultiCompiler,下面我们一单个为例

const?createCompiler?=?rawOptions?=>?{

????const?options?=?getNormalizedWebpackOptions(rawOptions);

????applyWebpackOptionsBaseDefaults(options);

????const?compiler?=?new?Compiler(options.context,?options);

????new?NodeEnvironmentPlugin({

????????infrastructureLogging:?options.infrastructureLogging

????}).apply(compiler);

????if?(Array.isArray(options.plugins))?{

????????for?(const?plugin?of?options.plugins)?{

????????????if?(typeof?plugin?===?"function")?{

????????????????plugin.call(compiler,?compiler);

????????????}?else?{

????????????????plugin.apply(compiler);

????????????}

????????}

????}

????applyWebpackOptionsDefaults(options);

????compiler.hooks.environment.call();

????compiler.hooks.afterEnvironment.call();

????new?WebpackOptionsApply().process(options,?compiler);

????compiler.hooks.initialize.call();

????return?compiler;

};

首先是获取用户的配置加上默认的配置,生成最新的配置。然后创建compiler实例,

NodeEnvironmentPlugin插件是用来扩展node,加文件缓存、文件读取和写入、文件监听。这里文件监听使用的是Watchpack库。

执行用户配置的插件,在添加webpac默认配置。

接下来所有重要的逻辑都是在WebpackOptionsApply这里面处理的,通过配置去执行对应的插件。

compiler.hooks.make.tapAsync("EntryPlugin",?(compilation,?callback)?=>?{

????????????compilation.addEntry(context,?dep,?options,?err?=>?{

????????????????callback(err);

????????????});

????????});

主要来看入口文件的处理,?EntryOptionPlugin插件中EntryPlugin通过调用compilation.addEntry从入口文件开始处理。

此外如果入口是一个函数,则调用DynamicEntryPlugin也会添加入口文件。

在网上看到别人分析的源码,我觉得这张图结构很清晰,可以说明的生命周期的各个阶段所做的事:

?

addEntry方法中调用addModuleTree去处理相关的模块依赖,调用dependencyFactories

处理模块的依赖dependency.constructor。然后handleModuleCreation内部处理,最后调用factorizeModule解析模块。用factorizeQueue将模块解析压入模块解析队列中执行。

首先调用工程的factory.create函数,调用的是compilation.dependencyFactories.set(

????????????????????EntryDependency,

????????????????????normalModuleFactory

????????????????);

放入的normalModuleFactory。

大致步骤addModule添加模块,然后_handleModuleBuildAndDependencies构建模块buildModule和处理模块依赖processModuleDependencies。通过_processModuleDependencies方法中handleModuleCreation循环构建。

在构建过程中需要处理一些loader,在NormalModule中调用_doBuild中的runLoaders去处理,最终返回资源和webpackAST信息。

最后调用compilation.seal将模块转换成chunk代码块,最后通过emitAssets输出合并后的代码块输出文件。

?

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-15 18:10:55  更:2021-12-15 18:11:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:44:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码