• .21-浅析webpack源码之事件流this-compilation


      上一节生成Compilation实例后,添加了一些属性,随后触发this-compilation事件流,如下:

    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;
    }

      事件流的名字this-compilation我想了半天也不懂啥意思,从其内容来看其实也只算是一个预编译,叫pre-compilation似乎更好。

      总之先不管那么多,继续跑流程,流程图如下:

      this-compilation事件流的plugin来源有两个地方,分别是:

    // 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}`)
            );
        }
    });

      两者都出现在WebpackOptionsApply模块中,依次看具体内容。

    JsonpTemplatePlugin

      这里依次在上节中提到的Compilation几个属性上加载插件(Tapable),首先是:

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

      该插件源码整理如下:

    "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;

      可见,这里只是注入对应的事件流,这里我在注释同时给出了该属性初始化时的plugin,可以对比一下,只有local-vars是重复的。

      既然没有任何的apply操作,就暂时先跳过。

      然后是第二个:

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

      源码如下:

    "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;

      同样只是注入事件流,该属性在初始化没有做操作,所有事件流只有这两。

      第三个:

    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;

      与上面那个类似。

      该模块注入完结。

    CachePlugin

      该插件注入了多个事件流,直接上与this-compilation事件流相关的代码:

    compiler.plugin("this-compilation", compilation => {
        // TODO remove notCacheable for webpack 4
        // 这个属性我从头到尾找不到哪出现的
        // 反正注释说webpack4会将其移除
        if (!compilation.notCacheable) {
            // cache => {}
            compilation.cache = cache;
            // 注入事件流
            compilation.plugin("child-compiler", (childCompiler, compilerName, compilerIndex) => { /**/ });
        }
        // 不可能到达的else
        else if (this.watching) {
            compilation.warnings.push(
                new Error(`CachePlugin - Cache cannot be used because of: ${compilation.notCacheable}`)
            );
        }
    });

      果然是只是注入事件流,这里的notCacheable不知道在哪定义的,也不知道如何修改。

      

      总之this-compilation也并不是编译,只是为一些辅助模块注入事件流。

  • 相关阅读:
    【C#】Color颜色对照表
    eslint的实践
    关于babel和webpack结合使用的实践
    前端学习博客
    css学习4--网格布局
    css学习3--flexbox布局
    CSS学习2-布局介绍
    css学习1
    前端性能优化
    line-height介绍
  • 原文地址:https://www.cnblogs.com/QH-Jimmy/p/8125655.html
Copyright © 2020-2023  润新知