这篇我们从./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命令,会配置环境,清空缓存等。
网友评论