(1)npm script
- //开发环境
- npm run dev
- //生产环境
- npm run build
(2)webpack直接执行
webpack entry.js bundle.js
(1)在命令行运行以上命令后,npm会让命令行工具进入node_modules\.bin 目目录查找是否存在 webpack.sh 或者 webpack.cmd 文件,如果存在,就执行,不存在,就抛出错误。
(2)实际的入口文件是:node_modules\webpack\bin\webpack.js
- #!/usr/bin/env node
-
- // @ts-ignore
- //正常执行返回(exitCode为0,error为null),报错会修改exitCode同时throw error
- process.exitCode = 0;
-
- /**
- * @param {string} command process to run
- * @param {string[]} args commandline arguments
- * @returns {Promise<void>} promise
- */
- //运行某个命令
- //command:npm
- //arg: install xxx -d
- //提供一个方案快速的去执行一个命令,而不需要再命令行里手动地去输入命令
- const runCommand = (command, args) => {
- const cp = require("child_process");
- return new Promise((resolve, reject) => {
- const executedCommand = cp.spawn(command, args, {
- stdio: "inherit",
- shell: true
- });
-
- executedCommand.on("error", error => {
- reject(error);
- });
-
- executedCommand.on("exit", code => {
- if (code === 0) {
- resolve();
- } else {
- reject();
- }
- });
- });
- };
-
- /**
- * @param {string} packageName name of the package
- * @returns {boolean} is the package installed?
- */
- //判断某个包是否安装
- const isInstalled = packageName => {
- try {
- require.resolve(packageName);
-
- return true;
- } catch (err) {
- return false;
- }
- };
-
- /**
- * @typedef {Object} CliOption
- * @property {string} name display name
- * @property {string} package npm package name
- * @property {string} binName name of the executable file
- * @property {string} alias shortcut for choice
- * @property {boolean} installed currently installed?
- * @property {boolean} recommended is recommended
- * @property {string} url homepage
- * @property {string} description description
- */
- //webpack 可用的CLI:webpack-cli和webpack-command
- /** @type {CliOption[]} */
- 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."
- },
- //相对来说更加轻量
- {
- name: "webpack-command",
- package: "webpack-command",
- binName: "webpack-command",
- alias: "command",
- installed: isInstalled("webpack-command"),
- recommended: false,
- url: "https://github.com/webpack-contrib/webpack-command",
- description: "A lightweight, opinionated webpack CLI."
- }
- ];
- //判断两个CLI是否安装了
- const installedClis = CLIs.filter(cli => cli.installed);
- //一个没有安装
- if (installedClis.length === 0) {
- const path = require("path");
- const fs = require("fs");
- const readLine = require("readline");
- //错误提示
- let notify =
- "One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:";
-
- for (const item of CLIs) {
- if (item.recommended) {
- notify += `\n - ${item.name} (${item.url})\n ${item.description}`;
- }
- }
-
- console.error(notify);
- //提供帮助自动安装
- const isYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
-
- const packageManager = isYarn ? "yarn" : "npm";
- const installOptions = [isYarn ? "add" : "install", "-D"];
-
- console.error(
- `We will use "${packageManager}" to install the CLI via "${packageManager} ${installOptions.join(
- " "
- )}".`
- );
- //询问是否安装
- const question = `Do you want to install 'webpack-cli' (yes/no): `;
-
- const questionInterface = readLine.createInterface({
- input: process.stdin,
- output: process.stderr
- });
- questionInterface.question(question, answer => {
- questionInterface.close();
- //是否输入yes
- const normalizedAnswer = answer.toLowerCase().startsWith("y");
-
- if (!normalizedAnswer) {
- console.error(
- "You need to install 'webpack-cli' to use webpack via CLI.\n" +
- "You can also install the CLI manually."
- );
- process.exitCode = 1;
-
- return;
- }
- //开始安装
- const packageName = "webpack-cli";
-
- console.log(
- `Installing '${packageName}' (running '${packageManager} ${installOptions.join(
- " "
- )} ${packageName}')...`
- );
- //执行安装命令
- runCommand(packageManager, installOptions.concat(packageName))
- .then(() => {
- require(packageName); //eslint-disable-line
- })
- .catch(error => {
- console.error(error);
- process.exitCode = 1;
- });
- });
- //安装了一个,直接使用
- } else if (installedClis.length === 1) {
- const path = require("path");
- const pkgPath = require.resolve(`${installedClis[0].package}/package.json`);
- // eslint-disable-next-line node/no-missing-require
- const pkg = require(pkgPath);
- // eslint-disable-next-line node/no-missing-require
- require(path.resolve(
- path.dirname(pkgPath),
- pkg.bin[installedClis[0].binName]
- ));
- } else {
- //安装了两个,提示要删掉一个才可以运行
- console.warn(
- `You have installed ${installedClis
- .map(item => item.name)
- .join(
- " and "
- )} together. To work with the "webpack" command you need only one CLI package, please remove one of them or use them directly via their binary.`
- );
-
- // @ts-ignore
- process.exitCode = 1;
- }
webpack 最终找到 webpack-cli (webpack-command) 这个 npm 包,并且执行 CLI。