21 - A Brief Analysis of Compoile Process-Event Flow This-Compoilation of Web Pack Source Code

Keywords: Javascript Webpack Attribute

After generating the Compilation instance in the previous section, some attributes are added, and then the flow of this-compilation events is triggered, as follows:

Compiler.prototype.newCompilation = (params) => {
    // new Compilation()
    const compilation = this.createCompilation();
    compilation.fileTimestamps = this.fileTimestamps;
    compilation.contextTimestamps = this.contextTimestamps;
    compilation.name = this.name;
    compilation.records = this.records;
    compilation.compilationDependencies = params.compilationDependencies;
    // Go!
    this.applyPlugins("this-compilation", compilation, params);
    this.applyPlugins("compilation", compilation, params);
    return compilation;
}

The name of the event stream is this-compilation, which I haven't understood for half a day. In terms of its content, it's actually a pre-compilation. It seems better to call it pre-compilation.

Anyway, no matter how many, keep running. The flow chart is as follows:

There are two sources of plugin s for this-compilation event flow, namely:

// JsonpTemplatePlugin
class JsonpTemplatePlugin {
    apply(compiler) {
        compiler.plugin("this-compilation", (compilation) => {
            compilation.mainTemplate.apply(new JsonpMainTemplatePlugin());
            compilation.chunkTemplate.apply(new JsonpChunkTemplatePlugin());
            compilation.hotUpdateChunkTemplate.apply(new JsonpHotUpdateChunkTemplatePlugin());
        });
    }
}
// CachePlugin
compiler.plugin("this-compilation", compilation => {
    // TODO remove notCacheable for webpack 4
    if (!compilation.notCacheable) {
        compilation.cache = cache;
        compilation.plugin("child-compiler", (childCompiler, compilerName, compilerIndex) => { /**/ });
    } else if (this.watching) {
        compilation.warnings.push(
            new Error(`CachePlugin - Cache cannot be used because of: ${compilation.notCacheable}`)
        );
    }
});

Both appear in the WebpackOptions Apply module, looking at the specific content in turn.

 

JsonpTemplatePlugin

Tapable is loaded on several attributes of Compilation mentioned in the previous section, first of all:

compilation.mainTemplate.apply(new JsonpMainTemplatePlugin());

The source code of the plug-in is as follows:

"use strict";
const Template = require("./Template");
class JsonpMainTemplatePlugin {
    apply(mainTemplate) {
        // this.plugin("startup", (source, chunk, hash) => { /**/ });
        // this.plugin("render", (bootstrapSource, chunk, hash, moduleTemplate, dependencyTemplates) => { /**/ });
        // this.plugin("local-vars", (source, chunk, hash) => { /**/ });
        // this.plugin("require", (source, chunk, hash) => { /**/ });
        // this.plugin("module-obj", (source, chunk, hash, varModuleId) => { /**/ });
        // this.plugin("require-extensions", (source, chunk, hash) => { /**/ });
        mainTemplate.plugin("local-vars", function(source, chunk) { /**/ });
        mainTemplate.plugin("jsonp-script", function(_, chunk, hash) { /**/ });
        mainTemplate.plugin("require-ensure", function(_, chunk, hash) { /**/ });
        mainTemplate.plugin("require-extensions", function(source, chunk) { /**/ });
        mainTemplate.plugin("bootstrap", function(source, chunk, hash) { /**/ });
        mainTemplate.plugin("hot-bootstrap", function(source, chunk, hash) { /**/ });
        mainTemplate.plugin("hash", function(hash) { /**/ });
    }
}
module.exports = JsonpMainTemplatePlugin;

Obviously, here is only the injection of the corresponding event stream, here I also give the plugin when the attribute is initialized in the annotation, which can be compared, only local-vars are repetitive.

Since there is no apply operation, skip it for the time being.

Then the second one:

compilation.chunkTemplate.apply(new JsonpChunkTemplatePlugin());

The source code is as follows:

"use strict";
const ConcatSource = require("webpack-sources").ConcatSource;
class JsonpChunkTemplatePlugin {
    apply(chunkTemplate) {
        chunkTemplate.plugin("render", function(modules, chunk) { /**/ });
        chunkTemplate.plugin("hash", function(hash) { /**/ });
    }
}
module.exports = JsonpChunkTemplatePlugin;

Similarly, it only injects event streams, which are not operated on during initialization, and only these two are all event streams.

Third:

compilation.hotUpdateChunkTemplate.apply(new JsonpHotUpdateChunkTemplatePlugin());
"use strict";
const ConcatSource = require("webpack-sources").ConcatSource;
class JsonpHotUpdateChunkTemplatePlugin {
    apply(hotUpdateChunkTemplate) {
        hotUpdateChunkTemplate.plugin("render", function(modulesSource, modules, removedModules, hash, id) { /**/ });
        hotUpdateChunkTemplate.plugin("hash", function(hash) { /**/ });
    }
}
module.exports = JsonpHotUpdateChunkTemplatePlugin;

Similar to the one above.

The module is injected.

 

CachePlugin

The plug-in injects multiple event streams directly related to this-compilation event stream:

compiler.plugin("this-compilation", compilation => {
    // TODO remove notCacheable for webpack 4
    // This property I can't find anywhere from beginning to end.
    // Anyway, commentary says webpack4 It will be removed
    if (!compilation.notCacheable) {
        // cache => {}
        compilation.cache = cache;
        // Injection Event Flow
        compilation.plugin("child-compiler", (childCompiler, compilerName, compilerIndex) => { /**/ });
    }
    // Impossible else
    else if (this.watching) {
        compilation.warnings.push(
            new Error(`CachePlugin - Cache cannot be used because of: ${compilation.notCacheable}`)
        );
    }
});

The notCacheable here does not know where to define it or how to modify it.

  

In a word, this-compilation is not compilation, it just injects event streams into some auxiliary modules.

Posted by wmolina on Tue, 18 Dec 2018 19:39:04 -0800