123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- #!/usr/bin/env node
- // @ts-ignore
- process.exitCode = 0;
- /**
- * @param {string} command process to run
- * @param {string[]} args commandline arguments
- * @returns {Promise<void>} promise
- */
- 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
- */
- /** @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."
- }
- ];
- 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();
- 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;
- }
|