webpack4与webpack3的区别

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

执行脚本到打包结束流程

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

每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。

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

这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha,只要直接写mocha test就可以了。

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

image.png
2、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文件
3、node_modules/webpack/bin/webpack.js首先会判断是否安装了webpack-cli模块,如果没有安装webpack-cli模块就会引导用户去安装,如果已经安装了webpack-cli模块,就会去执行node_modules\webpack-cli\bin\cli.js

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]
    ));
}

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

// 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...


记得要微笑
1.9k 声望4.5k 粉丝

知不足而奋进,望远山而前行,卯足劲,不减热爱。


引用和评论

0 条评论