• .16-浅析webpack源码之编译后流程梳理


      这节把编译打包后的流程梳理一下,然后集中处理compile。

      之前忽略了一个点,如下:

    new NodeEnvironmentPlugin().apply(compiler);
    // 引入插件加载
    if (options.plugins && Array.isArray(options.plugins)) {
        compiler.apply.apply(compiler, options.plugins);
    }
    compiler.applyPlugins("environment");
    compiler.applyPlugins("after-environment");
    compiler.options = new WebpackOptionsApply().process(options, compiler);

      在compiler对象的fs模块挂载完后,会对传入的插件进行加载,这个过程在内置插件加载之前。

      插件部分单独讲解,所以这个地方先暂时略过。 

      剩余流程如图:

      内置插件全部plugin完毕后,会检测编译的回调函数:

    if (callback) {
        if (typeof callback !== "function") throw new Error("Invalid argument: callback");
        // 检测是否有watch选项
        if (options.watch === true || (Array.isArray(options) && options.some(o => o.watch))) {
            const watchOptions = Array.isArray(options) ? options.map(o => o.watchOptions || {}) : (options.watchOptions || {});
            return compiler.watch(watchOptions, callback);
        }
        compiler.run(callback);
    }

      vue-cli的脚手架生产模式的构建文件build.js中就很明显的传了一个回调函数:

    webpack(webpackConfig, (err, stats) => { /**/ })

      这里的回调函数主要是输出一些打包信息,包括打包文件的状态、打包错误提示、打包完成提示等等。

      暂时不管这个回调,因此会直接返回compiler,回到预编译的webpack.js文件中。

      又回到了久违的bin/webpack.js,后面的流程简化后源码如下:

    try {
        compiler = webpack(options);
    } catch (err) { /**/ }
    // --progress用于输出打包信息
    if (argv.progress) {
        var ProgressPlugin = require("../lib/ProgressPlugin");
        compiler.apply(new ProgressPlugin({
            profile: argv.profile
        }));
    }
    // 输出打包信息的回调函数
    function compilerCallback(err, stats) { /**/ }
    // 如果有watch则打包后进程持续进行监视
    if (firstOptions.watch || options.watch) { /**/ }
    // 直接编译
    else
        compiler.run(compilerCallback);

      在返回compiler对象后,此时还未进行打包操作,只是准备好了一切,剩余的几步如下:

    1、检测--progress指令,该指令用于将进度输出到控制台

    2、检测--watch指令或者配置文件中的watch参数,如果有,则打包完后持续检测相关文件,发生变动立即调用打包操作

    3、没有配置watch则直接进行打包操作,打包完成后调用回调函数

      

      progress这个可以自己去尝试,可以想象成安装程序那个界面。

      watch指令作用如图:

      打包完进程并不会退出,当修改入口文件并保存后,会立即打包并刷新提示输出信息。

      这里先暂时不管watch。

      最后一步就是打包的操作:

    compiler.run(compilerCallback);

      传入的回调函数只是负责输出打包信息,源码如下:

    function compilerCallback(err, stats) {
        // 非watch模式下清理缓存
        if (!options.watch || err) {
            compiler.purgeInputFileSystem();
        }
        // 错误处理
        if (err) { /**/ }
        // 输出打包信息
        if (outputOptions.json) {
            process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + "
    ");
        } else if (stats.hash !== lastHash) {
            lastHash = stats.hash;
            var statsString = stats.toString(outputOptions);
            if (statsString)
                process.stdout.write(statsString + "
    ");
        }
        if (!options.watch && stats.hasErrors()) {
            process.exitCode = 2;
        }
    }

      stats是打包后生成的信息,将其格式化后通过prcess,stdout.write输出,这个输出方式底层就是console.log,上面那个图中打包完成信息就是通过这行代码输出的。

      

      至此,所以与打包过程无关的操作都已经完事,剩下的内容都集中在compiler.run这个调用中。

  • 相关阅读:
    Dapper使用
    EF5.X Code First表关联与延迟加载
    EF Code First 学习笔记:关系
    Entity Framework
    MVC3+EF4.1学习系列(五)----- EF查找导航属性的几种方式
    QML与C++混合编程
    如何将信号从javascript发射到qml
    qt quick中qml编程语言
    PyQt 5信号与槽的几种高级玩法
    静态编译OpenSSL并整合到Qt
  • 原文地址:https://www.cnblogs.com/QH-Jimmy/p/8089509.html
Copyright © 2020-2023  润新知