1. createModuleAssets();
// 生成module资源 在生成hash之后会生成资源
this.hooks.beforeModuleAssets.call();
this.createModuleAssets();
// 遍历modules 获取module.buildInfo.assets
function createModuleAssets() {
for (let i = 0; i < this.modules.length; i++) {
const module = this.modules[i];
if (module.buildInfo.assets) {
const assetsInfo = module.buildInfo.assetsInfo;
for (const assetName of Object.keys(module.buildInfo.assets)) {
const fileName = this.getPath(assetName);
// 触发emitAsset生成资源
this.emitAsset(
fileName,
module.buildInfo.assets[assetName],
assetsInfo ? assetsInfo.get(assetName) : undefined
);
this.hooks.moduleAsset.call(module, fileName);
}
}
}
}
// 生成资源
function emitAsset() {
this.assets[file] = source;
this.assetsInfo.set(file, assetInfo);
}
复制代码
2. createChunkAssets
this.hooks.beforeChunkAssets.call();
this.createChunkAssets(); // chunk
const mainTemplate = new MainTemplate(this.outputOptions)
const chunkTemplate = new ChunkTemplate(this.outputOptions);
const moduleTemplates = {
javascript: new ModuleTemplate(this.runtimeTemplate, "javascript"),
webassembly: new ModuleTemplate(this.runtimeTemplate, "webassembly")
};
function createChunkAssets() {
// 1. 获取template
const template = chunk.hasRuntime()
? this.mainTemplate : this.chunkTemplate;
// 2. 执行getRenderManifest 触发renderManifest钩子
// JavascriptModulesPlugin中注册的 result中push一个render方法
const manifest = template.getRenderManifest({
moduleTemplates: this.moduleTemplates,
})
for (const fileManifest of manifest) {
// 3. 得到路径和相关info
const pathAndInfo = this.getPathWithInfo
// 4. 执行render方法
source = fileManifest.render();
// 映射资源 compilation.assets
this.emitAsset(file, source, assetInfo);
}
}
复制代码
2.1 MainTemplate
class MainTemplate {
constructor(outputOptions) {
this.hooks.render.tap("MainTemplate",() => {
// webpack-sources
const source = new ConcatSource();
source.add("/******/ (function(modules) { // webpackBootstrap\n");
source.add(
// 触发 JavascriptModulesPlugin 的钩子
this.hooks.modules.call()
);
return source
})
}
getRenderManifest(options) {
this.hooks.renderManifest.call(result, options)
}
render() {
// 1.生成runTime代码
const buf = this.renderBootstrap()
// 2.包裹 runtime 与 chunk 代码
// render在构造器中tap的
let source = this.hooks.render.call()
source = this.hooks.renderWithEntry.call(source, chunk, hash);
return new ConcatSource(source, ";");
}
}
复制代码
2.2 ChunkTemplate
class ChunkTemplate {
getRenderManifest(options) {
this.hooks.renderManifest.call(result, options);
}
}
复制代码
2.3 JavascriptModulesPlugin
class JavascriptModulesPlugin {
apply(compiler) {
// parse 和 generator
normalModuleFactory.hooks.createParser
.for("javascript/auto")
.tap("JavascriptModulesPlugin", options => {
return new Parser(options, "auto");
});
normalModuleFactory.hooks.createGenerator
.for("javascript/auto")
.tap("JavascriptModulesPlugin", () => {
return new JavascriptGenerator();
});
compiler.hooks.compilation.tap( "JavascriptModulesPlugin", (compilation, { normalModuleFactory }) => {
// mainTemplate
compilation.mainTemplate.hooks.renderManifest.tap("JavascriptModulesPlugin", (result, options) => {
result.push({
render: () =>
compilation.mainTemplate.render()
})
})
// modules
compilation.mainTemplate.hooks.modules.tap( "JavascriptModulesPlugin", () => {
return Template.renderChunkModules()
})
// chunkTemplate
compilation.chunkTemplate.hooks.renderManifest.tap("JavascriptModulesPlugin", (result, options) => {
result.push({
render: () =>
this.renderJavascript(
compilation.chunkTemplate,
chunk,
moduleTemplates.javascript, // options.moduleTemplates
dependencyTemplates
)
})
})
//
})
}
renderJavascript(chunkTemplate, chunk, moduleTemplate, dependencyTemplates) {
const moduleSources = Template.renderChunkModules()
const core = chunkTemplate.hooks.modules.call()
// render JsonpChunkTemplatePlugin 添加jsonp代码 异步包裹代码
let source = chunkTemplate.hooks.render.call()
source = chunkTemplate.hooks.renderWithEntry.call(source, chunk);
return new ConcatSource(source, ";");
}
}
复制代码
2.4 Template
class Template {
// chunkModule的render也是执行这里
static renderChunkModules(chunk, filterFn, moduleTemplate) {
const source = new ConcatSource();
const modules = chunk.getModules().filter(filterFn);
// 调用render方法
const allModules = modules.map(module => {
return {
id: module.id,
// moduleTemplate 传递过来的参数 生成每个module的代码
source: moduleTemplate.render(module, dependencyTemplates, {
chunk
})
};
});
}
}
复制代码
2.5 ModuleTemplate
// 执行moduleTemplate的render方法
class ModuleTemplate {
render(module, dependencyTemplates, options) {
// 执行module的source方法
const moduleSource = module.source()
// 对源码再次做一些处理
const moduleSourcePostContent = this.hooks.content.call()
const moduleSourcePostModule = this.hooks.module.call()
// FunctionModulePlugin 对源码进行包裹
const moduleSourcePostRender = this.hooks.render.call()
// 添加注释代码
return this.hooks.package.call()
}
}
复制代码
2.6 NormalModule
class NormalModule {
source(dependencyTemplates, runtimeTemplate, type = "javascript") {
// 执行JavascriptGenerator的generate方法
const source = this.generator.generate()
}
}
复制代码
2.7 NormalModuleFactory
class NormalModuleFactory {
constructor(context, resolverFactory, options) {
this.hooks.factory.tap("NormalModuleFactory", () => (result, callback) => {
// resolver返回的
createdModule = new NormalModule(result);
})
this.hooks.resolver.tap("NormalModuleFactory", () => (data, callback) => {
callback(null, {
parser: this.getParser(type, settings.parser),
generator: this.getGenerator(type, settings.generator),
})
})
}
getGenerator() {
// JavascriptModulesPlugin
const generator = this.hooks.createGenerator
.for(type)
.call(generatorOptions);
this.hooks.generator.for(type).call(generator, generatorOptions);
}
}
复制代码
2.8 JavascriptGenerator
class JavascriptGenerator {
generate() {
const source = new ReplaceSource(originalSource);
this.sourceBlock()
}
sourceBlock() {
for (const dependency of block.dependencies) {
this.sourceDependency()
}
// block.variables
for (const childBlock of block.blocks) {
this.sourceBlock()
}
}
sourceDependency() {
// build module 的时候 执行 parse 添加的依赖
const template = dependencyTemplates.get(dependency.constructor);
// 根据不同的依赖对源码做不同的处理 webpack-sources 感觉就是对源码进行处理
// 增加代码 修改代码 具体做了什么不分析 之后看打包生成的代码结构
template.apply(dependency, source, runtimeTemplate, dependencyTemplates);
}
}
复制代码
2.9 dependencyTemplates
// 经过ast的处理 增加了5个依赖 对应不同的模板 在 dependencies 目录下
HarmonyCompatibilityDependency
HarmonyInitDependency
ConstDependency
HarmonyImportSideEffectDependency
HarmonyImportSpecifierDependency
复制代码
2.9.1 HarmonyCompatibilityDependency
// HarmonyImportSpecifierDependency
HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependencyTemplate {
apply(dep, source) {}
}
复制代码
2.9.2 HarmonyInitDependency
HarmonyInitDependency.Template = class HarmonyInitDependencyTemplate {
apply() {
item.template.harmonyInit()
}
}
复制代码
2.9.3 ConstDependency
ConstDependency.Template = class ConstDependencyTemplate {
apply(dep, source) {
if (typeof dep.range === "number") {
source.insert(dep.range, dep.expression);
return;
}
source.replace(dep.range[0], dep.range[1] - 1, dep.expression);
}
};
复制代码
2.9.4 HarmonyImportSideEffectDependency
HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDependencyTemplate extends HarmonyImportDependency.Template {}
复制代码
2.9.5 HarmonyImportDependency
HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate {
apply(dep, source, runtime) {
// no-op
}
}
复制代码
2.9.5 HarmonyImportSpecifierDependency
HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependencyTemplate extends HarmonyImportDependency.Template {
apply(dep, source, runtime) {
super.apply(dep, source, runtime);
const content = this.getContent(dep, runtime);
source.replace(dep.range[0], dep.range[1] - 1, content);
}
}
复制代码
2.10 WebpackOptionsApply
class WebpackOptionsApply {
process(options, compiler) {
switch (options.target) {
JsonpTemplatePlugin = require("./web/JsonpTemplatePlugin");
new JsonpTemplatePlugin().apply(compiler);
new FunctionModulePlugin().apply(compiler);
}
}
}
复制代码
2.11 FunctionModulePlugin
class FunctionModulePlugin {
apply(compiler) {
compiler.hooks.compilation.tap("FunctionModulePlugin", compilation => {
new FunctionModuleTemplatePlugin().apply(
compilation.moduleTemplates.javascript
);
});
}
}
复制代码
2.11.1 FunctionModuleTemplatePlugin
class FunctionModuleTemplatePlugin {
apply(moduleTemplate) {
moduleTemplate.hooks.render.tap("FunctionModuleTemplatePlugin", (moduleSource, module) => {
source.add()
})
moduleTemplate.hooks.package.tap()
}
}
复制代码
2.12 JsonpTemplatePlugin
class JsonpTemplatePlugin {
apply(compiler) {
compiler.hooks.thisCompilation.tap("JsonpTemplatePlugin", compilation => {
new JsonpMainTemplatePlugin().apply(compilation.mainTemplate);
new JsonpChunkTemplatePlugin().apply(compilation.chunkTemplate);
});
}
}
复制代码
2.12.1 JsonpMainTemplatePlugin
2.12.2 JsonpChunkTemplatePlugin
class JsonpChunkTemplatePlugin {
apply(chunkTemplate) {
// 添加jsonp代码
chunkTemplate.hooks.render.tap(
"JsonpChunkTemplatePlugin",
(modules, chunk) => {}
)
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)