webpack和webpack-cli模块源码分析

webpack4与webpack3的区别

webpack4.0 之后,彷佛执行方式就发生了改变,再也不是 webpack 一波流,而是多了一个 webpack-cliwebpack3webpack-cli是合在webpack中。因此在命令行运行 webpack 命令的同时,会提示让你再装一个 webpack-clihtml

执行脚本到打包结束流程

一、当咱们安装了webpack模块后,就会在node_modules/.bin目录下生成一个webpack、webpack.cmd,webpacklinux下的命令脚本,webpack.cmdwindows下命令脚本,webpack.cmd能够在windows系统上直接运行。node

每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。所以,只要是 Shell(通常是 Bash)能够运行的命令,就能够写在 npm 脚本里面。linux

比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量(软链接),执行结束后,再将PATH变量恢复原样。webpack

这意味着,当前目录的node_modules/.bin子目录里面的全部脚本,均可以直接用脚本名调用,而没必要加上路径。好比,当前项目的依赖里面有 Mocha,只要直接写mocha test就能够了。git

// 执行一下命令
cd .\node_modules\.bin\
ls

image.png
二、package.jsonscript配置dev: webpack --mode development,当执行npm run dev至关于执行webpack --mode development
image.png
webpack.cmd执行时会判断当前目录下是否存在node执行程序,若是存在就使用当前node进程执行node_modules/webpack/bin/webpack.js,若是当前目录下不存在node进程,则使用全局(也就是本地)node执行node_modules/webpack/bin/webpack.js文件
三、node_modules/webpack/bin/webpack.js首先会判断是否安装了webpack-cli模块,若是没有安装webpack-cli模块就会引导用户去安装,若是已经安装了webpack-cli模块,就会去执行node_modules\webpack-cli\bin\cli.jsgithub

const CLIs = [
    {
        name: "webpack-cli",
        package: "webpack-cli",
        binName: "webpack-cli",
        alias: "cli",
        installed: isInstalled("webpack-cli"),
        recommended: true,
        url: "https://github.com/webpack/webpack-cli",
        description: "The original webpack full-featured CLI."
    },
    {
        // some coding
    }
];

const installedClis = CLIs.filter(cli => cli.installed);

if (installedClis.length === 0) {
    // some coding
    const question = `Do you want to install 'webpack-cli' (yes/no): `;
    // some coding
} else if (installedClis.length === 1) {
    const path = require("path");
    const pkgPath = require.resolve(`${installedClis[0].package}/package.json`);
    const pkg = require(pkgPath);
    console.log(path.resolve(
        path.dirname(pkgPath),
        pkg.bin[installedClis[0].binName]
    )) // E:\项目\webpack学习\node_modules\webpack-cli\bin\cli.js
    require(path.resolve(
        path.dirname(pkgPath),
        pkg.bin[installedClis[0].binName]
    ));
}

四、node_modules\webpack-cli\bin\cli.js中会require("webpack")引入webpack模块(/node_modules/lib/webpack.js)获得一个webpack函数,运行webpack函数,返回一个compiler对象,执行compiler中的run,开始编译web

// node_modules/bin/cli.js
(function() {
    // 一大堆配置
    // something code ...
    yargs.parse(process.argv.slice(2), (err, argv, output) => {
        // something code ...
        function processOptions(options) {
            // 各类if else 过滤和配置
            // something code...
            const webpack = require("webpack");
            let compiler;
            try {
                // 运行webpack函数,返回一个compiler对象
                compiler = webpack(options); 
            } catch (err) {
                // something code...
            }
            // 执行compiler中的run,开始编译。
            compiler.run(compilerCallback);
        }
        processOptions(options);
    })
    // something code ...

})()
// node_modules/webpack/lib/webpack.js
const webpack = (options, callback) => {
    // some coding
    return compiler;
}
exports = module.exports = webpack;

参考:
npm 脚本的原理:http://www.ruanyifeng.com/blo...
webpack-cli源码解析:https://www.jianshu.com/p/ec8...npm

相关文章
相关标签/搜索