webpack源码2

这篇我们从./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 [] \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)