.22-浅析webpack源码之compile流程-事件流compilation总览

  呃,终于到了这地方……

newCompilation(params) {
    // ...
    this.applyPlugins("this-compilation", compilation, params);
    // 31
    console.log(this._plugins[‘compilation‘].length);
    this.applyPlugins("compilation", compilation, params);
    return compilation;
}

  MMP,有31个函数,估计可以写到明年了。

  这里先梳理所有事件的注入来源,经检测,全部来源于WebpackOptionsApply中,回到那个可怕的模块,梳理后如下:

class WebpackOptionsApply extends OptionsApply {
    constructor() {
        super();
    }
    process(options, compiler) {
        // ...
        if (typeof options.target === "string") {
            // ...
            switch (options.target) {
                case "web":
                    JsonpTemplatePlugin = require("./JsonpTemplatePlugin");
                    NodeSourcePlugin = require("./node/NodeSourcePlugin");
                    compiler.apply(
                        new JsonpTemplatePlugin(options.output),
                        // plugin + 3
                        new FunctionModulePlugin(options.output),
                        new NodeSourcePlugin(options.node),
                        new LoaderTargetPlugin(options.target)
                    );
                    break;
                    // ...
            }
        }
        // ...

        // plugin + 1
        compiler.apply(new EntryOptionPlugin());
        compiler.applyPluginsBailResult("entry-option", options.context, options.entry);
        // plugin + 24
        compiler.apply( /**/ );

        compiler.apply( /**/ );

        // ...
        // plugin + 1
        compiler.apply(new TemplatedPathPlugin());
        // plugin + 1
        compiler.apply(new RecordIdsPlugin());
        // plugin + 1
        compiler.apply(new WarnCaseSensitiveModulesPlugin());
        // ...
        return options;
    }
}

  还好都集中在一个地方,这样又可以写流水账了。

  这里先要过一个地方,之前似乎遗留了:

compiler.apply(new EntryOptionPlugin());
compiler.applyPluginsBailResult("entry-option", options.context, options.entry);

  这里注入了entry-option事件流,并在下一行代码触发,所以直接进去看实现:

function itemToPlugin(context, item, name) {
    if (Array.isArray(item)) {
        return new MultiEntryPlugin(context, item, name);
    }
    return new SingleEntryPlugin(context, item, name);
}

module.exports = class EntryOptionPlugin {
    apply(compiler) {
        // context => options.context
        // entry => options.entry
        compiler.plugin("entry-option", (context, entry) => {
            // 针对单字符串或数组情况
            if (typeof entry === "string" || Array.isArray(entry)) {
                // 输出文件为main
                compiler.apply(itemToPlugin(context, entry, "main"));
            }
            // 对象 => 多入口
            else if (typeof entry === "object") {
                Object.keys(entry).forEach(name => compiler.apply(itemToPlugin(context, entry[name], name)));
            }
            // 函数
            else if (typeof entry === "function") {
                compiler.apply(new DynamicEntryPlugin(context, entry));
            }
            return true;
        });
    }
};

  这里针对字符串、数组、对象、函数四种情况分别做了处理,先只看单字符串,其余情况后面单独讲解。

  单字符串会进入SingleEntryPlugin插件:

"use strict";
const SingleEntryDependency = require("./dependencies/SingleEntryDependency");
class SingleEntryPlugin {
    constructor(context, entry, name) {
        this.context = context;
        this.entry = entry;
        this.name = name;
    };
    apply(compiler) {
        compiler.plugin("compilation", (compilation, params) => { /**/ });
        compiler.plugin("make", (compilation, callback) => { /**/ });
    };
    static createDependency(entry, name) {
        // 该模块有一个isEqualResource方法判断entry是否一样
        const dep = new SingleEntryDependency(entry);
        dep.loc = name;
        return dep;
    }
}

  这里引入的SingleEntryDependency原型链比较长,而且没有什么营养,出一个示意图,不贴源码了:

  可以看到该模块注入了两个事件流,静态方法后面再讲。

  第一小节先这样结束吧!

原文地址:https://www.cnblogs.com/QH-Jimmy/p/8137144.html

时间: 2024-10-09 08:09:33

.22-浅析webpack源码之compile流程-事件流compilation总览的相关文章

boost.asio源码剖析(三) ---- 流程分析

* 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: 1 #include <iostream> 2 #include <boost/asio.hpp> 3 4 // 异步连接回调函数 5 void on_connect(boost::system::error_code ec) 6 { 7 if (ec) // 连接失败, 输出错误码 8 std::cout << "async connect error:"

webpack源码-依赖收集

webpack源码-依赖收集 version:3.12.0 程序主要流程: 触发make钩子 Compilation.js 执行EntryOptionPlugin 中注册的make钩子 执行compilation.addEntry 执行compilation._addModuleChain Compilation.js 执行moduleFactory.create(this.semaphore.avaiable 初始化为100) Compilation.js 执行this.buildModule

webpack源码分析——配置调试环境

无论是阅读webpack源码,还是编写webpack的plugin和loader,配置调试环境都是很有必要的.weabpack的运行环境是nodejs,调试webpack就是调试nodejs程序.我们平时使用的IDE如eclipse.webstorm都支持nodejs的调试.本文以eclipse(Version: Oxygen.1a Release (4.7.1a))为例,进行讲解. 在这个例子里面,我们使用webpack <entry> [<entry>] <output&

spring boot 源码解析 启动流程

spring boot 源码解析 启动流程 在面试过程中经常被问到过spring boot的启动流程,今天就翻一下源码整体看一下: 首先,新建一个启动类,可以看到是首先调用的SpringApplication的静态方法run @SpringBootApplication public class SourceReadApplillcation { public static void main(String[] args) { SpringApplication.run(SourceReadAp

jQuery源码解析之on事件绑定

本文采用的jQuery源码为jquery-3.2.1.js jquery的on方法用来在选定的元素上绑定一个或多个事件处理函数. 当参数selector存在时,通常会用来对已经存在的元素或将来即将添加到文档中的元素做事件委托,表示当点击document中的selector元素时,将触发function回调函数. 1 <div id="div" style="font-weight:800;font-size:24px;text-align:center;color:re

从Chrome源码看浏览器的事件机制

.aligncenter { clear: both; display: block; margin-left: auto; margin-right: auto } .crayon-line span::after { content: " " } p { font-size: 15px; text-indent: 2em } #colorbox.crayon-colorbox,#cboxOverlay.crayon-colorbox,.crayon-colorbox #cboxWr

Skynet服务器框架(二) C源码剖析启动流程

引言: 之前我们已经完成了在Linux下配置安装 skynet 的环境,并成功启动了 skynet 服务框架,为了从底层更好地理解整个框架的实现过程,我们有必要剖析一下源码,由于底层的源码都是用C语言写的,lua脚本基本是用来进行业务层开发,所以我们从C源码开始解读框架.打开下载包的 skynet-src 目录,这里是skynet框架的核心C源码,接下来我们就要来解读 skynet_main.c 和 skynet_start.c 这两个与skynet启动相关的C源码. 1.入口函数和初始化: 我

webpack源码分析——参数初始化

webpack比较常见的用法有两种:一.使用配置文件:二.不使用配置文件(用命令 webpack <entry> [<entry>] <output>).这两种方式参数的初始化方式不太一样: 方式一.从配置文件和shell语句中读取并合并参数:方式二.从shell语句从直接读取入口和出口参数.本文会结合源码,分析一下这两种方式的实现.(文章使用的webpack版本是3.10.0) webpack执行的入口文件是bin目录下面的webpack.js,负责参数转换处理的文件

idea 导入 jdk源码 解决compile code 后阅读jdk 源码

在用intelliJ IDEA阅读代码时,跟踪到例如java.io.File类文件时,在关键代码段总会出现 “compile code”字样,使人不能真正跟踪到代码内部去. 为解决此问题,如下操作: step1:下载jdk源码,src.jar 1.1 mac安装的jdk路径 :/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/ 源码所在位置:/library/java/javavirtualmachines/1.6.0_65-b14-462.j