webpack 原理剖析

一、webpack 启动过程分析

1.从webpack命令行说起(此部分可视为进入构建前处理)

通过npm scripts 运行 webpack

  • 开发环境:npm run dev
  • 生产环境:npm run build

webpack运行的两种方式
1)通过 webpack 命令直接运行

  • webpack entry.js bundles.js
    2)通过 package 中的配置的 webpack 命令运行

这个过程发生了什么?
在命令行运行命令后,npm 会让命令行工具进入node_modules.bin目录查找是否存在webpack.sh 或者 webpack.cmd文件,如果存在,就执行,不存在,就抛出错误。
? 在我的项目中实际并未找到这两个文件
!实际入口是:nodel_module\webpack\bin\webpack.js
在这里插入图片描述
启动结果:找到webpack-cli(功能较全) 或者 webpack-commond(轻量化)对应的npm包,并且去执行。

2.webpack-cli 源码剖析

webpack-cli 做的事情:
webpack-cli 提供的不需要编译的命令

const NON_COMPILATION_ARGS = 
["init", //创建一份webpack配置文件
"migrate", //进行webpack版本迁移
"serve", //运行webpack-serve
"generate-loader", //生成webpack loader代码
"generate-plugin", //生成webpack plugin代码
"info" //返回与本地环境相关的一些信息
];

1)引入 yargs,对命令行进行定制,即让我们通过命令行添加参数的形式就可以直接去运行webpack对应的功能。

yargs包简介:
可以通过webpack --help查看webpack提供的命令参数类型
在这里插入图片描述
而这些类型都是来源于文件config-yargs:
在这里插入图片描述
也就是说我们可以直接通过命令行参数的形式对webpack进行配置
在这里插入图片描述
在cli.js中,引入了options选项
convert-argv:就是根据命令行或者webpack配置的一些参数,给options 增加响应的参数以及相应的一些插件。
在这里插入图片描述即调用的是webpack包lib下的webpack.js

二、webpack plugins机制原理解读

我们在使用webpack的时候都知道往plugins中疯狂的加plugin就能让pulgin起作用,那么这些plugins到底是怎么被调用的呢?

简述:webpack可以理解为是一种基于事件流的编程范例,webpack整个流程中定义了很多个事件,而每个plugin就是去订阅这些事件,当整个流程执行到某个事件时,就会去执行每个plugins订阅了该事件的方法。

webpack的核心模块为:compiler、compiltion
在这里插入图片描述
1)Tapable对外提供了同步钩子和异步钩子两类钩子
所有的同步异步钩子都是继承于hook的
在这里插入图片描述
2) 钩子实现的原理:
简述:hook内部维护了一个 taps[]
每次调用tap(同步钩子)时都会往taps中塞一个对应的函数,当调用call时,就会去执行taps中对应的函数方法。
例:

const { SyncHook } = require('tapable');
const hook = new SyncHook(['name']);
hook.tap('hello', (name) => {
    console.log(`hello ${name}`);
});
hook.tap('hello again', (name) => {
    console.log(`hello ${name}, again`);
});

hook.call('ahonn');
// hello ahonn
// hello ahonn, again

实际的细节实现比这个复杂得多,详细剖析见:
https://zhuanlan.zhihu.com/p/79221553

3)那么在webpack中,对于钩子是怎么用的呢?
1.创建钩子的位置:complier的构造函数中
在这里插入图片描述
3.钩子挂载的过程
在这里插入图片描述
3.对各个钩子监听各个钩子函数的调用过程
在complier.run中:最终进行了call的调用
在这里插入图片描述
在这里插入图片描述
1)上图的call方法只被调用了一次,是因为此处传入的params是已经被加工过的,实际还是会根据params的处理情况进行多个钩子监听函数的执行。
2)此时compliation才被创建出来,即就是要处理的钩子函数执行完成后进行的操作。compilation 实例能够访问所有的模块和它们的依赖(大部分是循环依赖)。它会对应用程序的依赖图中所有模块进行字面上的编译(literal compilation)。在编译阶段,模块会被加载(loaded)、封存(sealed)、优化(optimized)、分块(chunked)、哈希(hashed)和重新创建(restored)。

三、webpack 编译流程梳理:

简述:

1.通过loader(loader-runner)去解析模块(对模块的源代码进行转换,将不同的语言(其他资源例如 css,图片,或者其他的语法集比如jsx)转换为js)
2.通过parser,NormalModelFactory中使用的是acorn,作用:

将代码中通过依赖的模块,添加到模块依赖列表中去,这样的就不断的去分析依赖,不断的去构建,将构建结果存到compliation的modules中。
(注:解析依赖模块的时候,通过require引进来的是通过NormalModelFactory解析的,而带路径的模块则是通过ContextMOduleFactory解析的)

3.资源生成(modules->chunks)

什么是modules和chunks
转自:https://www.cnblogs.com/skychx/p/webpack-module-chunk-bundle.html
1)对于一份同逻辑的代码,当我们手写下一个一个的文件,它们无论是 ESM 还是 commonJS 或是 AMD,他们都是 module ;
2)当我们写的 module 源文件传到 webpack 进行打包时,webpack 会根据文件引用关系生成 chunk 文件,webpack 会对这个 chunk 文件进行一些操作;
3)webpack 处理好 chunk 文件后,最后会输出 bundle 文件,这个 bundle 文件包含了经过加载和编译的最终源文件,所以它可以直接在浏览器中运行。

4.优化,执行所有监听seal相关钩子的函数。
5.输出文件到dist目录
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue 和 Webpack 是开发现代前端应用程序的两个重要工具。Vue 是一个用于构建用户界面的渐进式 JavaScript 框架,而 Webpack 是一个模块打包工具。 Vue 的核心思想是将界面的不同部分抽象为组件,每个组件有自己的模板、样式和逻辑。Vue 在运行时会解析组件,并且通过虚拟 DOM 的方式进行高效的渲染和更新。 Webpack 则是一个用于打包模块的工具。它可以将各种类型的资源文件(JavaScript、CSS、图片等)作为模块进行处理,并将它们打包成静态文件,以用于浏览器端的加载和运行。 在 Vue 项目中使用 Webpack,通常会通过 webpack.config.js 文件进行配置。在配置中,我们可以定义入口文件、输出目录、加载器(Loaders)、插件(Plugins)等。 入口文件指定了 Vue 应用程序的入口点,通常是一个 JavaScript 文件。Webpack 会从这个入口文件开始,分析依赖关系,并且构建整个应用程序的依赖图。 加载器是用于处理各种类型文件的模块转换器。例如,Babel-loader 可以将 ES6+ 的 JavaScript 代码转换为兼容各种浏览器的 JavaScript 代码;CSS-loader 可以处理 CSS 文件,并将其转换为 JavaScript 对象;File-loader 可以处理图片文件,并将其转换为可在浏览器中使用的 URL。 插件是用于扩展 Webpack 功能的工具。例如,Vue-loader 插件可以将 Vue 的单文件组件(.vue)转换为 JavaScript 代码;HtmlWebpackPlugin 插件可以自动生成 HTML 文件,并将打包后的静态文件自动引入到 HTML 中。 总结起来,Vue 使用 Webpack 实现了模块化的开发方式,通过加载器和插件的配合,可以实现对各种类型文件的处理和打包。这样就能够以组件化的方式构建 Vue 应用程序,并且通过 Webpack 进行打包和优化,使应用程序更加高效和可维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fly_bit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值