一、CLI
的解析和处理
我们以taro build --type weapp —watch
为例
{
_: [ 'build' ],
version: false,
v: false,
help: false,
h: false,
'disable-global-config': false,
type: 'weapp',
watch: true,
build: true
}
首先 ,cli
里面解析到命令行参数
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/66a06ded-09e1-4fa0-a845-48ceb09e1897/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=3b6210fafd8ffdab0a97515cb52942a43f5f92685ffccc0470abaa8139973aea&X-Amz-SignedHeaders=host&x-id=GetObject)
然后根据命令,kernel
的optsPlugins
属性里面会添加3个元素
taro cli
里内置的对build
命令处理的插件的路径,commandsPath
是所有内置命令插件的目录,targetPlugin
是根据命令来的,此处值为 build.js
@tarojs/plugin-platform-weapp
,小程序处理插件@tarojs/plugin-framework-react
,react
处理插件
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/4cc85a49-2132-455c-951d-03471378c647/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=f739bbbcaefc4cb93d825311df118b0e14047f95a0e3e7dc3158a6625c4a28f9&X-Amz-SignedHeaders=host&x-id=GetObject)
在初始化插件时,cliAndProjectPlugins
就是这3个插件,extraPlugins
是taro
预设的5个插件,最终一起初始化了8个插件,extraPlugins
里面的插件都是调用 registerMethod
来注册方法
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/3138d8e9-bfdc-4e7f-b684-20daf070c673/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=27c72d8230a1ff3ecdd1ae6acfcd121132c7c37609f0917e1d7bf8956b95ccab&X-Amz-SignedHeaders=host&x-id=GetObject)
初始完插件后,kernel
里面的hooks
字段有4个键值对
- build:
build.js
通过registerCommand
注册 - weapp:
@tarojs/plugin-platform-weapp
通过registerPlatform
方法注册 - modifyWebpackChain:
@tarojs/plugin-framework-react
监听的hook
- modifyRunnerOpts:
@tarojs/plugin-framework-react
监听的hook
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/f9ffb3fc-aee3-4d70-a8ee-6f3019283199/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=11971728157ef22809dfaa66ef35e7a53ebdcd4e1cb988b85f3c3b3aefc8661f&X-Amz-SignedHeaders=host&x-id=GetObject)
在kernel
的run
函数中,先触发了modifyRunnerOpts
这个钩子,进行编译的前置处理
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/0caa1122-14eb-4960-bf88-20395577b197/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=873ae2cf126244af440cacd849253ab4852782fe13c75998cc5eb8bfb0a9e1c9&X-Amz-SignedHeaders=host&x-id=GetObject)
然后又调用applyPlugins
方法,触发build
插件,build
插件里面又触发了当前platform
也就是@tarojs/plugin-platform-weapp
这个插件
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/28b2477e-c8c7-4c60-93e9-59ba1d70f9d7/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=a153c81bb18aefd7c67318a96a06bf24a835ef438ae7a0e7bb88b4558ea4e3c0&X-Amz-SignedHeaders=host&x-id=GetObject)
weapp
的插件实例化了一个Weapp
类,然后执行start
方法,Weapp
类的start
方法是从父类TaroPlatformBase
继承过来的
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/685bd03b-6593-4348-ab49-a20fcdcc5a40/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=a705b00199e2eb5fb46a6399f3d5bc6156d58788110bc1e75257713dec4f3b08&X-Amz-SignedHeaders=host&x-id=GetObject)
在Weapp
构造函数初始化时,新建了一个Template
类的实例赋值到this.template
上,后面的代码是在setup
完成后调用modifyTemplate
和modifyWebpackConfig
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/2503f23b-fa81-4eb6-a76b-858e0e1ff8da/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023251Z&X-Amz-Expires=3600&X-Amz-Signature=e6f8242cbd435af4104abf5e0d0fb3ea617fcf3de22bb72a96985889f55f0286&X-Amz-SignedHeaders=host&x-id=GetObject)
我们直接看build
方法
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/a4075fe5-66ce-418c-8183-95dbe5521300/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=a7a020d4d08d4676bbcbb5a750d043fe2ce90066927874b420100d241d1b22ea&X-Amz-SignedHeaders=host&x-id=GetObject)
build
方法执行的是buildImpl
,先根据编译配置选择使用vite
还是webpack
进行编译,require
相应的包,然后汇总配置信息调用编译器,options
内容打印如下
{
entry: { app: [ 'G:\\...\\src\\app.tsx' ] },
alias: {
'@/components': 'G:\\...\\src\\components'
},
copy: { patterns: [], options: {} },
sourceRoot: 'src',
outputRoot: 'dist/weapp',
platform: 'weapp',
framework: 'react',
compiler: {
type: 'webpack5',
prebundle: { enable: false, include: [Array], exclude: [Array] }
},
cache: { enable: false },
logger: undefined,
baseLevel: undefined,
csso: undefined,
sass: undefined,
uglify: undefined,
plugins: [],
projectName: '',
env: {
NODE_ENV: '"development"',
FRAMEWORK: '"react"',
TARO_ENV: '"weapp"',
TARO_PLATFORM: '"mini"',
TARO_VERSION: '"3.6.27"'
},
defineConstants: {},
designWidth: 750,
deviceRatio: { '640': 1.17, '750': 1, '828': 0.905 },
projectConfigName: undefined,
jsMinimizer: undefined,
cssMinimizer: undefined,
terser: undefined,
esbuild: undefined,
miniCssExtractPluginOption: { ignoreOrder: true },
postcss: {
'postcss-preset-env': { enable: true },
autoprefixer: { enable: false },
pxtransform: { enable: true, config: {} },
url: { enable: true, config: [Object] },
cssModules: { enable: false, config: [Object] }
},
isWatch: true,
mode: 'development',
blended: false,
isBuildNativeComp: false,
withoutBuild: false,
newBlended: false,
modifyWebpackChain: [Function: modifyWebpackChain],
modifyBuildAssets: [Function: modifyBuildAssets],
modifyMiniConfigs: [Function: modifyMiniConfigs],
modifyComponentConfig: [Function: modifyComponentConfig],
onCompilerMake: [Function: onCompilerMake],
onParseCreateElement: [Function: onParseCreateElement],
onBuildFinish: [Function: onBuildFinish],
nodeModulesPath: 'G:\\...\\node_modules',
buildAdapter: 'weapp',
platformType: 'mini',
globalObject: 'wx',
fileType: {
templ: '.wxml',
style: '.wxss',
config: '.json',
script: '.js',
xs: '.wxs'
},
template: Template {
_baseLevel: 16,
exportExpr: 'module.exports =',
thirdPartyPatcher: {},
supportXS: true,
isXMLSupportRecursiveReference: true,
Adapter: {
if: 'wx:if',
else: 'wx:else',
elseif: 'wx:elif',
for: 'wx:for',
forItem: 'wx:for-item',
forIndex: 'wx:for-index',
key: 'wx:key',
xs: 'wxs',
type: 'weapp'
},
internalComponents: {
View: [Object],
Icon: [Object],
... // 微信端的组件及属性,完整内容在 packages\taro-platform-weapp\src\components.ts
},
focusComponents: Set(3) { 'input', 'textarea', 'editor' },
voidElements: Set(13) {
'progress',
'icon',
'rich-text',
'input',
'textarea',
'slider',
'switch',
'audio',
'ad',
'official-account',
'open-data',
'navigation-bar',
'voip-room'
},
nestElements: Map(16) {
'view' => -1,
'catch-view' => -1,
'cover-view' => -1,
'static-view' => -1,
'pure-view' => -1,
'block' => -1,
'text' => -1,
'static-text' => 6,
'slot' => 8,
'slot-view' => 8,
'label' => 6,
'form' => 4,
'scroll-view' => 4,
'swiper' => 4,
'swiper-item' => 4,
'root-portal' => 3
},
buildPageTemplate: [Function (anonymous)],
buildBaseComponentTemplate: [Function (anonymous)],
buildCustomComponentTemplate: [Function (anonymous)],
buildXScript: [Function (anonymous)],
isSupportRecursive: false,
buildTemplate: [Function (anonymous)],
transferComponents: {},
modifyTemplateResult: [Function (anonymous)],
pluginOptions: {}
},
runtimePath: '@tarojs/plugin-platform-weapp/dist/runtime',
taroComponentsPath: '@tarojs/plugin-platform-weapp/dist/components-react'
}
二、webpack-chain
在上文执行runner
方法后,便进入了打包部分
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/fb187459-2d66-42cf-8b04-b07c00d6ddce/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=be053edb3ab7a07291faf1a153356a3ce6c9547ac4a6009c42d5aabb247df07c&X-Amz-SignedHeaders=host&x-id=GetObject)
首先创建一个MiniCombination
类的实例然后执行make
方法,这个make
方法实际上是从父类Combination
继承来的
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/8443bf68-aabc-4593-bf9b-fae04fbb0f7e/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=d8888cc38f33cc2663e6a7e07bfc479ffd8c2c5f7d4343849a8ec9236af69dac&X-Amz-SignedHeaders=host&x-id=GetObject)
make
方法内部调用了3个函数,pre
是对上面传进来的options
又添加了几个字段保存到this.config
上,process
是子类MiniCombination
重载的方法,post
方法是触发modifyWebpackChain
,webpackChain
,onWebpackChainReady
这3个钩子
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/204a1d0e-1d85-4b77-b968-1aea853d180c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=47fde982b6d439b30e061fdf0a70148759736cae1b32457fecd1b2bd8b1735c1&X-Amz-SignedHeaders=host&x-id=GetObject)
process
函数首先实例化了一个MiniBaseConfig
类的实例,这个MiniBaseConfig
是在构造函数里面修改了一些配置,它继承于BaseConfig
类,在BaseConfig
类的构造函数里面,新建了一个webpack-chain
的实例,并且通过chain.merge
方法添加了一些基础设置
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/006bb9b7-9297-4910-a4c9-95e22207cd44/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023251Z&X-Amz-Expires=3600&X-Amz-Signature=1e3d6d1d9104d0687177c20f096d741c6520f8539af489cc36165ac3177a49ec&X-Amz-SignedHeaders=host&x-id=GetObject)
在process
函数里实例化MiniWebpackPlugin
类,调用getPlugins
方法获取需要用到的plugin
{
providerPlugin: { plugin: [class ProvidePlugin], args: [ [Object] ] },
definePlugin: { plugin: [class DefinePlugin], args: [ [Object] ] },
miniCssExtractPlugin: {
plugin: [class MiniCssExtractPlugin] {
loader: 'G:\\...\\mini-css-extract-plugin\\dist\\loader.js'
},
args: [ [Object] ]
},
miniSplitChunksPlugin: {
plugin: [class MiniSplitChunksPlugin extends SplitChunksPlugin],
args: [ [Object] ]
},
miniPlugin: { plugin: [class TaroMiniPlugin], args: [ [Object] ] }
}
在process
函数里实例化MiniWebpackModule
类,调用getModules
方法获取需要用到的loader
{
rule: {
sass: { test: /\.sass$/, oneOf: [Array] },
scss: { test: /\.scss$/, oneOf: [Array] },
less: { test: /\.less$/, oneOf: [Array] },
stylus: { test: /\.styl(us)?$/, oneOf: [Array] },
normalCss: { test: /\.(css|qss|jxss|wxss|acss|ttss)(\?.*)?$/, oneOf: [Array] },
script: { test: /\.[tj]sx?$/i, use: [Object], include: [Array] },
template: {
test: /\.(wxml|axml|ttml|qml|swan|jxml)(\?.*)?$/,
type: 'asset/resource',
generator: [Object],
use: [Array]
},
xscript: {
test: /\.wxs$/,
type: 'asset/resource',
generator: [Object],
use: [Array]
},
media: {
test: /\.(mp4|webm|ogg|mp3|m4a|wav|flac|aac)(\?.*)?$/,
type: 'asset',
parser: [Object],
generator: [Object]
},
font: {
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
type: 'asset',
parser: [Object],
generator: [Object]
},
image: {
test: /\.(png|jpe?g|gif|bpm|svg|webp)(\?.*)?$/,
type: 'asset',
parser: [Object],
generator: [Object]
}
}
}
在getOptimization
方法里面设置了common
、vendors
和taro
3个chunks
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/5b8f809b-84d1-474a-ad65-a32f59d2f9e8/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=30be73ca213503e5653ba8e423348e2c6e856fd72cd6bfd95b640d9b82a45994&X-Amz-SignedHeaders=host&x-id=GetObject)
最后通过 chain.merge
合并配置
三、webpack插件
(一)TaroWebpackBarPlugin
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/0e95340c-8e76-4792-b067-f677c5f1518c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=c26035552a1ec9954ed0786591a6d95a2e69e722fbaf151782d945a657d7bfda&X-Amz-SignedHeaders=host&x-id=GetObject)
在BaseConfig
类的构造函数中,webpack-chain
配置里面默认有一个插件 TaroWebpackBarPlugin
,这个插件是taro
对webpackbar 插件进行的一个封装
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/f77d3e5c-787b-4281-b648-4652b3724ef2/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=a4ed3dd81e49e9e4243616e1db49dbc276510ab5fecc358230836cc8216f62ed&X-Amz-SignedHeaders=host&x-id=GetObject)
因为小程序环境没有实现DOM
和BOM
接口,这里自动加载了taro
自己的实现
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/959461c6-f348-4bf7-9c01-129fec671e95/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=49f9eb1c852bfcc328de39f79f2ae84cc59cecd3f45909b152c5c266f3a2bf15&X-Amz-SignedHeaders=host&x-id=GetObject)
设置一些全局变量
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/72038ca6-a71d-46fc-8747-5fa089eec3cb/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=834148150ebc7b3c2536e1652831120f39b0501bab0bb067e65d137a28ecb294&X-Amz-SignedHeaders=host&x-id=GetObject)
引入mini-css-extract-plugin
插件
(五)MiniSplitChunksPlugin
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/9cb42133-0a69-463b-8321-ccc01e00feae/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=36d604d9962b3f69d02a14cca40b80bfd00e3bf93adeac13beb64fad609fbd32&X-Amz-SignedHeaders=host&x-id=GetObject)
基于 SplitChunksPlugin 插件实现的分包优化策略,可将分包依赖提取到分包中,以减小小程序主包大小
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/6260d83e-7b82-4fd1-84ee-984ad48bd817/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=fdc8bacea6948f09cd299f54dcc81249b4cff06c06cbf5079063f2e77e11e7cf&X-Amz-SignedHeaders=host&x-id=GetObject)
apply
方法中,先判断了项目有没有设置分包结构,如果没有设置,则无需处理直接return
,随后监听thisCompilation
钩子在每次初始化 compilation
时进行处理
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/f930abb0-b52c-413c-a596-048cfb40953c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=a92938384243653018cbd3d34ca20cc51e0e7aa93969110ad2553f27c6d93cb8&X-Amz-SignedHeaders=host&x-id=GetObject)
在optimizeChunks
钩子中获取chunks
进行判断,先根据chunks
的name
过滤出属于分包的chunks
,然后遍历过滤后的结果,获取每个chunk
包含的模块,再对chunk
模块进行遍历,如果某个module
没有在主包中用到,并且有多个分包使用了这个module
,则将这个module
和对应的chunks
信息记录到this.subCommonDeps
中,同时对cacheGroups
的配置进行了调整,来创建要放到分包中的chunk
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/7c91c310-9d5f-4861-bb99-2326f9ef1e5e/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=f3e465efcc5bd438493d4e9f7a1eb8856d874c945b23e31756cb4ad01ab7e429&X-Amz-SignedHeaders=host&x-id=GetObject)
这里是覆盖了SplitChunksPlugin
的getCacheGroups
方法, normalizeCacheGroups
方法是从SplitChunksPlugin
中复制而来
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/d5527b6f-36a6-4223-8eaa-03e5b74e55b8/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=329cd6964ded84b621ce47e5bf11578b9af7f4b51f94a7e0bf391a367ce69683&X-Amz-SignedHeaders=host&x-id=GetObject)
上图是webpack
中SplitChunksPlugin
插件的代码,可以看到SplitChunksPlugin
的getCacheGroups
方法就是在构造函数中通过normalizeCacheGroups
生成的
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/87a3be6a-51af-43bb-b798-1f78ba236936/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=9c778933c8844c3876f445e01c1918db81ff41bf46bc12ad51af28ab97217afa&X-Amz-SignedHeaders=host&x-id=GetObject)
监听afterOptimizeChunks
钩子,在chunk
优化完成后,获取之前抽离到分包的sub-vendors
和sub-common
,this.subCommonDeps
是按照模块的MD5
值分组的,这里又将其转换成按照chunk
分组存到 this.subCommonChunks
中
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/269dad43-7560-4806-b3e8-b389a25c4892/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=528008088ece26863ee46b81dfc4ad07e0bea3ba1523033191dba89a463ee96c&X-Amz-SignedHeaders=host&x-id=GetObject)
监听processAssets
钩子,处理分包文件,先引入sub-vendors
部分,然后获取this.subCommonChunks
指定entryName
对应的sub-common
,遍历sub-common
,将模块都复制到分包目录下,同时分包文件引入复制过来的资源,最后,将根目录下的sub-common
资源删掉不输出
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/ecd3f596-d6c4-4f4d-a1fd-e0e459dfff3d/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=e2802e6cd4a8f9c7a422750da0018ec0c3e7231493a7cfc43b68bd1a331093f4&X-Amz-SignedHeaders=host&x-id=GetObject)
(六)TaroMiniPlugin
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/0c79efeb-5408-408f-b12c-e966339dc74a/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=bcfd9b70c513fead34f672e533cbcd19436f73793527621f7030876514709adc&X-Amz-SignedHeaders=host&x-id=GetObject)
apply
函数如下
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/7a5f9459-1a52-4aa1-9cfe-81e44f47f974/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=076cb952aacc3a63d3f66939496ceddf7aa16aae25e973a4f1c23d4e9c0cb822&X-Amz-SignedHeaders=host&x-id=GetObject)
因为我们是开发模式,所以run
这个hook
不会触发
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/34eab14f-8b05-4bb3-83c8-21bedde8febd/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=3a123f4739166a5569d8ead64ff4143db565ba6e3eb592b2f367a9e3f2d2328f&X-Amz-SignedHeaders=host&x-id=GetObject)
在watchRun
里面,首先获取changedFiles
修改的文件,也就是 Compiler.modifiedFiles
,第一次启动编译这个值是undefined
,后面每次修改文件都返回一个Set
集合,这样通过this.isWatch
来区分是否是第一次编译,后面会在第一次编译时打印一些页面信息等,随后执行了run
方法
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/7745c928-9386-49d0-9d61-f3153d0680e9/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=5dbd3deae127cdb431b03993a368e16df601a6124cd7492cd2e7bedb3de59d4b&X-Amz-SignedHeaders=host&x-id=GetObject)
因为我们不是编译小程序原生插件,所以isBuildPlugin
是false
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/ff67f036-9b09-4a90-bfff-fd908aff5d98/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=70b0d81e3ab3bc1743ebed930b13fb63f797b20d4c6dc67d6c42422d13b7843e&X-Amz-SignedHeaders=host&x-id=GetObject)
getAppConfig
方法获取app.config.js
里面的内容并保存到this.appConfig
中
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/3d65d83c-d3ee-4da1-b059-3142ad91ab3e/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=7452f2e2e684cb8948d06203d63ecab2a77924be75cc1b72c4e07f8bd4c2443a&X-Amz-SignedHeaders=host&x-id=GetObject)
这里还调用了compileFile
方法,compileFile
方法是专门读取页面配置的,也就是以.config
+扩展名结尾的文件,读取完会将数据保存到this.filesConfig
中
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/c9740584-8931-4f47-ab1f-adecede28bc9/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=7bdd06f6c270c7496e9f7d5231489c0c5c6a9f0cccc541a07b40803c672686f1&X-Amz-SignedHeaders=host&x-id=GetObject)
getAppConfig
方法里面还调用了build
插件传入的modifyAppConfig
函数来触发modifyAppConfig
钩子
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/9ed0de0c-6158-498a-ba74-fb67d33658b5/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=b00c56c5e46f538c0f5b4672db2475194a5f5f2c484e17e0d44cc92c24cb9db8&X-Amz-SignedHeaders=host&x-id=GetObject)
getPages
方法首先根据编译配置获取需要预渲染的页面保存到 this.prerenderPages
中,接着调用getTabBarFiles
方法收集tabbar
的信息,收集所有页面信息保存到this.pages
中
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/d88f8b23-180a-4295-a366-76a5b6933191/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=2aa78fb3a24238acf41e1177a0cb6d03b6734c7ece54dc350cb7bb4530ea6c63&X-Amz-SignedHeaders=host&x-id=GetObject)
getPagesConfig
方法对每个页面调用了compileFile
方法收集页面配置
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/4e85b161-c8c2-413d-a45c-f54e9e2fee36/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=4ca464ed2829fe317dae3bd16787dae4243b8b75e1d6210cd375a5152f336d04&X-Amz-SignedHeaders=host&x-id=GetObject)
getDarkMode
方法保存编译配置中的 themeLocation
到this.themeLocation
中
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/13660ea7-680d-4019-9f62-8e7a7479bb9d/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=9c01fd5e567a0a7fc27d8e6fb942c58babec05e193af8d6d48fde1d79abe96cc&X-Amz-SignedHeaders=host&x-id=GetObject)
getConfigFiles
先调用this.addEntry
方法,遍历 this.filesConfig
,将已有的文件信息以Map
对象的格式存到 this.dependencies
中,key
为文件路径,value
为TaroSingleEntryDependency
类的实例,TaroSingleEntryDependency
类继承自 webpack.dependencies.ModuleDependency
![](https://prod-files-secure.s3.us-west-2.amazonaws.com/44da4746-95f3-43f1-b4eb-1901acbbe54d/6ab304ea-dc73-428c-9ec0-08c87962d0b4/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45HZZMZUHI%2F20240908%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20240908T023252Z&X-Amz-Expires=3600&X-Amz-Signature=9994ddb4ecd03169555acdcc5fa9ae311201683794cf0ca032e23fceebc4eded&X-Amz-SignedHeaders=host&x-id=GetObject)
然后监听监听compilation
的beforeChunkAssets
钩子,在创建 chunk asset
之前,删掉其中的 config chunk