webpack打包是怎么执行的
Posted mcgee0731
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack打包是怎么执行的相关的知识,希望对你有一定的参考价值。
webpack和webpack-cli是npm包,运行于node环境,执行打包操作时会执行:
- window环境下,执行yarn webpack实际查找了 node_modules/.bin/webpack.cmd 文件并执行
- webpack.cmd 内根据安装的cli(两种webpack-cli,webpack-command),实现不同处理逻辑。
- 我们安装了webpack-cli,因此根据代码 require 了 node_modules/webpack-cli/package.json 中的 bin 入口文件,也就是 ./bin/cli.js
cli.js 是个 cli 执行命令行, 内部是 IIFE 函数
- 函数主要作用处理用户交互信息,require("webpack")并调用了 webpack(options)
- 实例化 Compiler.js类,赋给 compiler变量,compiler继承 tapable 库,贯穿整个编译流程(一般运行文件Compile.js都存在/lib目录下)
- 给 compiler 设置 Node 文件读写能力
- 给 compiler 循环挂载 我们自定义的 plugins
- 处理 webpack内部默认插件,其中最重要的是入口插件 EntryOptionPlugin, 此实例对象主要作用是 埋下一个 make 钩子监听
- 给 make钩子 回调内部添加 compilation.addEntry 方法,此时钩子回调并未触发,addEntry也不会执行, 重要!
条件处理完成,钩子也埋完后。调用 实例对象 run 方法,即 compiler.run,重要!
- run方法内部执行 compile 编译方法,compile 方法会 根据 compiler实例 创建一个 compilation 实例,compilation 继承自 tapable库
- 实例化后,触发上面埋的 make 钩子,执行上面埋的 make 钩子的回调,并传入初始化的 compilation 实例对象
- 此时执行 compilation.addEntry, 执行模块编译和打包生成dist的操作都在这个方法内, 重要!
- addEntry 内会 以 normalModuleFactory 模板创建一个 NormalModule 标准模块
- normalModuleFactory 类模板中有一些操作, (build方法, dobuild方法, 读取内容方法),用于操作编译我们写的模块
- 此时一个 标准的 NormalModule模块被创建,执行buildMoudle,操作 NormalModule 模块
- 主要操作就是 读取文件内容,操作 ast 语法树修改文件内容(例如:require改成__webpack_require__,以及内部的文件引用路径)
- 将修改后的内容写回到文件中,执行回调,也就是 afterBuild 方法
- 在afterBuild中我们会判断当前修改的模块是否有依赖,递归判断,将模块的依赖项也进行上述修改
- 将模块和模块依赖修改后,执行回调,处理chunk问题,模块和模块依赖之间有chunk的关系,同一chunk可以有多个模块,
- 当前所有的入口模块都被存放在了 compilation 对象的 entries 数组里
- 所谓封装 chunk 指的就是依据某个入口,然后找到它的所有依赖,将它们的源代码放在一起,之后再做合并
- 跟谁合并?跟ejs模板文件合并,生成 dist/bundle.js 文件
以上是关于webpack打包是怎么执行的的主要内容,如果未能解决你的问题,请参考以下文章