从入口文件开始,构建module,匹配文件类型的loader链,运行loader进行处理,得到module的依赖文件。 再对依赖文件进行module构建,由此递归形成module的依赖网。 根据入口和其他成组需要,组织chunk与module映射关系,并分组chunkGroup。最后根据chunk做静态文件的输出。
template
- main
- chunk
- 一个文件视为 `dependency`
- `dependency` ----`ModuleFactory`-->> `module`
- `module` 的 `dependency` ->> `module` ==》 `module graph`
-
- 用 `loader` 预处理 `module`
- 模块之间的依赖关系 `dependency`
lib/node/NodeEnvironmentPlugin.js
compiler.hooks.environment
compiler.hooks.afterEnvironment
lib/WebpackOptionsApply.js
target
library
externals
devtool
module
entry
做到支持 String, Array, Function
,增加 make
插件使增加入口entry-option
compilation
插件compiler.hooks.afterPlugins
compiler.resolverFactory.hooks.resolveOptions
compiler.hooks.afterResolvers
compiler.hooks.beforeRun
compiler.hooks.run
compilation.hooks.needAdditionalPass
compiler.hooks.done
compiler.hooks.additionalPass
compiler.hooks.failed
根据文件变化时间戳判断是否更新
compiler.hooks.watchRun
compiler.hooks.watchClose
compiler.hooks.beforeCompile
compiler.hooks.compile
compiler.hooks.thisCompilation
compiler.hooks.compilation
compiler.hooks.make
compilation.prefetch
/ compilation.addEntry
SingleEntryPlugin MultiEntryPlugin DllEntryPlugin DynamicEntryPlugin PrefetchPlugin AutomaticPrefetchPlugin
compilation.hooks.addEntry
compilation.hooks.failedEntry
compilation.hooks.succeedEntry
module
(这里以normalModuleFactory
作说明)
自定义模块类需绑定工厂:
compilation.dependencyFactories.set(userDependency, userFactory)
自定义的 dependencie 需继承webpack/lib/Dependency.js
自定义的 factory 需有create(data: ModuleFactoryCreateData, callback: ModuleCallback)
函数lib/NormalModule.js
/lib/NormalModuleFactory.js
before-resolve
factory
resolver(): resolver
require
字符串正则解析,得到内敛 loader
格式:
loader!loader!loader!file
前部可以设置此文件是否使用外部的前/中/后处理
- '-!xxxx' 只使用外部后处理
- '!xxxx' 不使用外部中处理
- '!!xxxx' 不使用任何外部loader
loader
loader
根据enforce
指定使用的时机并以此排序 顺序:外部后 - 内敛 - 外部中 - 外部前 后续会从左往右调用loader
的pitch
方法(有返回值时不再执行后面的loader
),再从右往左调用loader
方法
resolve
验证模块和loader有效parser
after-resolve
create-module()
module
实例module(): module
dependencie
绑定 module
做缓存 ············ __NormalModuleFactoryCache
build-module(modules): void
loader
处理
loader
内部解析文件处理完后转成js格式文本返回或直接调用loaderContext.callback
program(ast, comments): any
得到
dependencies
hash
warn/error
failed-module(modules): void
succeed-module(modules): void
module
作为 preparedChunk
compilation.hooks.finishModules
compilation.hooks.seal
compilation.hooks.optimizeDependenciesBasic
compilation.hooks.optimizeDependencies
compilation.hooks.optimizeDependenciesAdvanced
compilation.hooks.afterOptimizeDependencies
compilation.hooks.beforeChunks
compilation.hooks.afterChunks
compilation.hooks.optimize
compilation.hooks.optimizeModulesBasic
compilation.hooks.optimizeModules
compilation.hooks.optimizeModulesAdvanced
compilation.hooks.afterOptimizeModules
compilation.hooks.optimizeChunksBasic
compilation.hooks.optimizeChunks
compilation.hooks.optimizeChunksAdvanced
compilation.hooks.afterOptimizeChunks
compilation.hooks.optimizeTree
compilation.hooks.afterOptimizeTree
compilation.hooks.optimizeChunkModulesBasic
compilation.hooks.optimizeChunkModules
terser-webpack-plugin
做 Tree-Shakingcompilation.hooks.optimizeChunkModulesAdvanced
compilation.hooks.afterOptimizeChunkModules
compilation.hooks.shouldRecord
compilation.hooks.reviveModules
compilation.hooks.optimizeModuleOrder
compilation.hooks.advancedOptimizeModuleOrder
compilation.hooks.beforeModuleIds
compilation.hooks.moduleIds
compilation.hooks.optimizeModuleIds
compilation.hooks.afterOptimizeModuleIds
compilation.hooks.reviveChunks
compilation.hooks.optimizeChunkOrder
compilation.hooks.beforeChunkIds
compilation.hooks.optimizeChunkIds
compilation.hooks.afterOptimizeChunkIds
compilation.hooks.recordModules
compilation.hooks.recordChunks
crypto
compilation.hooks.beforeHash
compilation.hooks.afterHash
compilation.hooks.recordHash
compilation.hooks.beforeModuleAssets
compilation.hooks.shouldGenerateChunkAssets
compilation.hooks.beforeChunkAssets
compilation.hooks.additionalChunkAssets
compilation.hooks.record
compilation.hooks.additionalAssets
compilation.hooks.optimizeChunkAssets
compilation.hooks.afterOptimizeChunkAssets
compilation.hooks.optimizeAssets
compilation.hooks.afterOptimizeAssets
compilation.hooks.needAdditionalSeal
compilation.hooks.afterSeal
compiler.hooks.afterCompile
compiler.hooks.shouldEmit
compiler.hooks.assetEmitted
compiler.hooks.afterEmit
compiler.hooks.emit
recordsInputPath/recordsOutputPath/recordsPath
webpackConfig.resolve.plugins
resolve
parsedResolve
describedResolve
rawModule
module
relative
describedRelative
directory
existingDirectory
undescribedRawFile
rawFile
file
existingFile
resolved
以‘下划线拼写’定义,
resolver.getHook
并支持before-
和after-
前缀
resolver.getHook(name).tapAsync(pluginName, (request, resolveContext, callback)=>{return callback()})
resolver.getHook(name).tapPromise(pluginName, (request, resolveContext)=>{return Promise.resolve(undefined)})
chunk 拆分插件,根据配置
options.optimization.splitChunks
运行
在compilation.hooks.optimizeChunksAdvanced
阶段
遍历modules
根据test
配置匹配 -> 根据优先级(priority
/size
/...)-> 根据maxInitialRequests
/maxAsyncRequests
去除多的chunk
默认:
const splitChunks = {
// 选择哪些 chunk 进行优化
// all - 优化所有chunks,chunk 可以在异步和非异步 chunk 之间共享
// async - 非异步 chunk
// (chunk)=>boolean - 判断函数
chunks: 'async',
// 生成 chunk 的最小体积(以 bytes 为单位)
minSize: 20000,
minRemainingSize: 0,
// 拆分前必须共享模块的最小 chunks 数
minChunks: 1,
// 按需加载时的最大并行请求数
maxAsyncRequests: 30,
// 入口点的最大并行请求数
maxInitialRequests: 30,
enforceSizeThreshold: 50000,
// 缓存组,继承上面的属性
cacheGroups: {
defaultVendors: {
// 匹配规则
test: /[\\/]node_modules[\\/]/,
// 优先级
priority: -10,
// 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
reuseExistingChunk: true,
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
// 设置为 false 以禁用默认缓存组
// defaultVendors: false
// default: false
},
}
对有依赖关系的 compiler 同步编译;无依赖关系的,依次运行编译,因编译过程异步,即是同时编译的。
期间 chunks/modules 一直未释放,为 Stats 提供数据。
!
分隔!
之后为文件??
后面带ident
RuleSet
定义与解析(存在对象中)compiler.options.module.defaultRules.concat(compiler.options.module.rules)
对文件的缓存,定义并保存lastAccess
用于maxAge
判断。