webpack源码2

作者: 小强不是蟑螂啊 | 来源:发表于2018-09-05 21:16 被阅读0次

    这篇我们从./bin/webpack文件

    var path = require("path");
    // Local version replace global one
    try {
    var localWebpack = require.resolve(path.join(process.cwd(), "node_modules", "webpack", "bin", "webpack.js"));
    if(__filename !== localWebpack) {
    return require(localWebpack);
    }
    } catch(e) {}

    引入path模块,取到当前进程下的node_modules/webpack/bin/webpack.js的绝对路径,判断是否等于当前文件,如果不是,引用当前进程下的/bin/webpack.js

    var yargs = require("yargs")
    .usage("webpack " + require("../package.json").version + "\n" +
    "Usage: https://webpack.js.org/api/cli/\n" +
    "Usage without config file: webpack <entry> [<entry>] <output>\n" +
    "Usage with config file: webpack");

    require("./config-yargs")(yargs);
    引入yargs模块,调用./bin/config-yargs.js,配置webpack的各种命令。

    config-yargs.js:


    image.png

    命令中,--config 后面应该跟webpack配置文件的路径,--env:环境,--context:'绝对路径’等,
    使用webpack命令如下:
    "webpack --config build/webpack.dev.conf.js"

    3 .
    最后一部分大致结构入下:


    image.png

    err 错误,agrv参数,output 输出
    如果有err爆错并返回。
    argv["display"] = "verbose"; 表示命令中有verbose参数,表示webpack的在控制台输出打包过程是详细的。
    接下来引入/convert-argv,这个文件是我们根据命令中的各种参数去进行不同的处理,


    image.png
    image.png

    4
    进入到函数processOptions中,

    function processOptions(options) {
    // process Promise
    // 如果支持promise
    if(typeof options.then === "function") {
    options.then(processOptions).catch(function(err) {
    console.error(err.stack || err);
    process.exit(1); // eslint-disable-line
    });
    return;
    }

        var firstOptions = [].concat(options)[0]
        var statsPresetToOptions = require("../lib/Stats.js").presetToOptions;
    
        var outputOptions = options.stats;
        if(typeof outputOptions === "boolean" || typeof outputOptions === "string") {
            outputOptions = statsPresetToOptions(outputOptions);
        } else if(!outputOptions) {
            outputOptions = {};
        }
    
        ifArg("display", function(preset) {
            outputOptions = statsPresetToOptions(preset);
        });
    
        outputOptions = Object.create(outputOptions);
        if(Array.isArray(options) && !outputOptions.children) {
            outputOptions.children = options.map(o => o.stats);
        }
        if(typeof outputOptions.context === "undefined")
            outputOptions.context = firstOptions.context;
    
        ifArg("env", function(value) {
            if(outputOptions.env) {
                outputOptions._env = value;
            }
        });
    
        
    
    var webpack = require("../lib/webpack.js");
        Error.stackTraceLimit = 30;
        var lastHash = null;
        var compiler;
        try {
            compiler = webpack(options);
        } catch(err) {
            if(err.name === "WebpackOptionsValidationError") {
                if(argv.color)
                    console.error(
                    `\u001b[1m\u001b[31m${err.message}\u001b[39m\u001b[22m`
                    );
                else
                    console.error(err.message);
                // eslint-disable-next-line no-process-exit
                process.exit(1);
            }
    
            throw err;
        }
    
        if(argv.progress) {
            var ProgressPlugin = require("../lib/ProgressPlugin");
            compiler.apply(new ProgressPlugin({
                profile: argv.profile
            }));
        }
                // 解析的回调
        function compilerCallback(err, stats) {
            if(!options.watch || err) {
                // Do not keep cache anymore
                compiler.purgeInputFileSystem();
            }
            if(err) {
                lastHash = null;
                console.error(err.stack || err);
                if(err.details) console.error(err.details);
                process.exitCode = 1;
                return;
            }
            if(outputOptions.json) {
                process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2)+ "\n");
            } else if(stats.hash !== lastHash) {
                lastHash = stats.hash;
                var statsString = stats.toString(outputOptions);
                if(statsString)
                    process.stdout.write(statsString + "\n");
            }
            if(!options.watch && stats.hasErrors()) {
                process.exitCode = 2;
            }
        }
        // 如果已经有了监听
        if(firstOptions.watch || options.watch) {
            var watchOptions = firstOptions.watchOptions || firstOptions.watch || options.watch || {};
            if(watchOptions.stdin) {
                process.stdin.on("end", function() {
                    process.exit(); // eslint-disable-line
                });
                process.stdin.resume();
            }
            compiler.watch(watchOptions, compilerCallback);
            console.log("\nWebpack is watching the files…\n");
        } else
        // 第一次执行执行compiler
            compiler.run(compilerCallback);
    
    }
    

    上面一段代码是根据命令进行配置,"../lib/Stats.js"是输入到命令终端的代码颜色模块,正常,警告,错误等,然后引入"../lib/webpack.js",执行后执行回调,最后判断是否有监听,如果有进行重新打包,否则执行compiler.run(),说明这是第一次执行webpack命令,会配置环境,清空缓存等。

    相关文章

      网友评论

        本文标题:webpack源码2

        本文链接:https://www.haomeiwen.com/subject/xxpzwftx.html