1. createModuleAssets();

// Generating module resources generates resources after generating the hash
this.hooks.beforeModuleAssets.call();
this.createModuleAssets();
// Iterate through modules to get 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);
        // Trigger emitAsset to generate resources
        this.emitAsset(
          fileName,
          module.buildInfo.assets[assetName],
          assetsInfo ? assetsInfo.get(assetName) : undefined
        );
        this.hooks.moduleAsset.call(module, fileName); }}}}// Generate resources
function emitAsset() {
  this.assets[file] = source;
	this.assetsInfo.set(file, assetInfo);
}
Copy the code

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. Obtain template
  const template = chunk.hasRuntime() 
    ? this.mainTemplate : this.chunkTemplate;
  // 2. Execute getRenderManifest to trigger renderManifest
  // The result registered in JavascriptModulesPlugin pushes a render method
  const manifest = template.getRenderManifest({
    moduleTemplates: this.moduleTemplates,
  })
  for (const fileManifest of manifest) {
     // 3. Get the path and related info
    const pathAndInfo = this.getPathWithInfo
    // 4. Execute render method
    source = fileManifest.render();
    // 映射资源 compilation.assets
    this.emitAsset(file, source, assetInfo); }}Copy the code

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(
          // The hook that triggers the JavascriptModulesPlugin
					this.hooks.modules.call()
				);
        return source
      })
  }
  getRenderManifest(options) {
    this.hooks.renderManifest.call(result, options)
  }
  render() {
    // 1. Generate runTime code
    const buf = this.renderBootstrap()
    // 2. Wrap runtime and chunk codes
    // render tap in constructor
    let source = this.hooks.render.call()
    source = this.hooks.renderWithEntry.call(source, chunk, hash);
    return new ConcatSource(source, ";"); }}Copy the code

2.2 ChunkTemplate

class ChunkTemplate {
  getRenderManifest(options) {
    this.hooks.renderManifest.call(result, options); }}Copy the code

2.3 JavascriptModulesPlugin

class JavascriptModulesPlugin {
  apply(compiler) {

    / / the parse and the 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 adds jSONP code asynchronous wrap code
    let source = chunkTemplate.hooks.render.call()
    source = chunkTemplate.hooks.renderWithEntry.call(source, chunk);
    return new ConcatSource(source, ";"); }}Copy the code

2.4 the Template

class Template {
  // chunkModule render is also executed here
  static renderChunkModules(chunk, filterFn, moduleTemplate) {
    const source = new ConcatSource();
		const modules = chunk.getModules().filter(filterFn);
    // Call the render method
    const allModules = modules.map(module= > {
      return {
        id: module.id,
        // The arguments passed by moduleTemplate generate code for each module
        source: moduleTemplate.render(module, dependencyTemplates, { chunk }) }; }); }}Copy the code

2.5 ModuleTemplate

// Execute the render method for moduleTemplate
class ModuleTemplate {
  render(module, dependencyTemplates, options) {
    // Execute module's source method
    const moduleSource = module.source()
    // Do some work with the source code again
    const moduleSourcePostContent = this.hooks.content.call()
    const moduleSourcePostModule = this.hooks.module.call()
    // FunctionModulePlugin wraps source code
    const moduleSourcePostRender = this.hooks.render.call()
    // Add comments to the code
    return this.hooks.package.call()
  }
}
Copy the code

2.6 NormalModule

class NormalModule {
  source(dependencyTemplates, runtimeTemplate, type = "javascript") {
    Execute the Generate method of JavascriptGenerator
    const source = this.generator.generate()
  }
}
Copy the code

2.7 NormalModuleFactory

class NormalModuleFactory {
  constructor(context, resolverFactory, options) {
    this.hooks.factory.tap("NormalModuleFactory".() = > (result, callback) = > {
      // return by 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); }}Copy the code

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() {
    // Parse adds dependencies when building module
    const template = dependencyTemplates.get(dependency.constructor);
    Webpack-sources treats the source code differently depending on the dependency
    // Add code to modify the code specifically do not analyze after the package generated code structuretemplate.apply(dependency, source, runtimeTemplate, dependencyTemplates); }}Copy the code

2.9 dependencyTemplates

// Add five dependencies to the Dependencies directory
HarmonyCompatibilityDependency 
HarmonyInitDependency  
ConstDependency  
HarmonyImportSideEffectDependency  
HarmonyImportSpecifierDependency 
Copy the code

2.9.1 HarmonyCompatibilityDependency

// HarmonyImportSpecifierDependency
HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependencyTemplate {
  apply(dep, source){}}Copy the code

2.9.2 HarmonyInitDependency

HarmonyInitDependency.Template = class HarmonyInitDependencyTemplate {
  apply() {
    item.template.harmonyInit()
  }
}
Copy the code

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); }};Copy the code

2.9.4 HarmonyImportSideEffectDependency

HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDependencyTemplate extends HarmonyImportDependency.Template {}
Copy the code

2.9.5 HarmonyImportDependency

HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate {
	apply(dep, source, runtime) {
		// no-op}}Copy the code

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); }}Copy the code

2.10 WebpackOptionsApply

class WebpackOptionsApply {
  process(options, compiler) {
    switch (options.target) {
      JsonpTemplatePlugin = require("./web/JsonpTemplatePlugin");
      new JsonpTemplatePlugin().apply(compiler);
      newFunctionModulePlugin().apply(compiler); }}}Copy the code

2.11 FunctionModulePlugin

class FunctionModulePlugin {
	apply(compiler) {
		compiler.hooks.compilation.tap("FunctionModulePlugin".compilation= > {
			newFunctionModuleTemplatePlugin().apply( compilation.moduleTemplates.javascript ); }); }}Copy the code

2.11.1 FunctionModuleTemplatePlugin

class FunctionModuleTemplatePlugin {
  apply(moduleTemplate) {
    moduleTemplate.hooks.render.tap("FunctionModuleTemplatePlugin".(moduleSource, module) = > {
      	source.add()
    })
    moduleTemplate.hooks.package.tap()
  }
}
Copy the code

2.12 JsonpTemplatePlugin

class JsonpTemplatePlugin {
	apply(compiler) {
		compiler.hooks.thisCompilation.tap("JsonpTemplatePlugin".compilation= > {
			new JsonpMainTemplatePlugin().apply(compilation.mainTemplate);
			newJsonpChunkTemplatePlugin().apply(compilation.chunkTemplate); }); }}Copy the code

2.12.1 JsonpMainTemplatePlugin

2.12.2 JsonpChunkTemplatePlugin

class JsonpChunkTemplatePlugin {
  apply(chunkTemplate) {
    // Add jSONP code
    chunkTemplate.hooks.render.tap(
			"JsonpChunkTemplatePlugin".(modules, chunk) = >{})}}Copy the code