webpack/bin/webpack.js

139 lines
3.3 KiB
JavaScript
Raw Normal View History

2012-03-10 20:11:23 +08:00
#!/usr/bin/env node
2018-05-15 22:56:15 +08:00
/**
* @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) => {
2018-05-15 22:56:15 +08:00
const executedCommand = cp.spawn(command, args, {
2018-03-29 23:06:10 +08:00
stdio: "inherit",
shell: true
});
executedCommand.on("error", error => {
reject(error);
});
executedCommand.on("exit", code => {
if (code === 0) {
2018-05-15 22:56:15 +08:00
resolve();
} else {
reject();
}
});
});
2018-05-15 22:56:15 +08:00
};
2012-03-10 20:11:23 +08:00
2018-05-15 22:56:15 +08:00
/**
* @param {string} packageName name of the package
* @returns {boolean} is the package installed?
*/
const isInstalled = packageName => {
2018-05-09 20:00:15 +08:00
try {
require.resolve(packageName);
return true;
} catch (err) {
return false;
}
2018-05-15 22:56:15 +08:00
};
/**
* @typedef {Object} CliOption
* @property {string} name display name
* @property {string} package npm package name
* @property {string} binName name of the executable file
2018-05-15 22:56:15 +08:00
* @property {boolean} installed currently installed?
* @property {string} url homepage
*/
2019-03-29 05:57:38 +08:00
/** @type {CliOption} */
const cli = {
name: "webpack-cli",
package: "webpack-cli",
binName: "webpack-cli",
installed: isInstalled("webpack-cli"),
url: "https://github.com/webpack/webpack-cli"
};
2018-05-15 22:56:15 +08:00
2019-03-29 05:57:38 +08:00
if (!cli.installed) {
const path = require("path");
const fs = require("graceful-fs");
const readLine = require("readline");
2018-05-09 20:00:15 +08:00
2019-03-29 05:57:38 +08:00
const notify =
"CLI for webpack must be installed.\n" + ` ${cli.name} (${cli.url})\n`;
2018-05-09 20:00:15 +08:00
console.error(notify);
const isYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
const packageManager = isYarn ? "yarn" : "npm";
2018-05-15 22:56:15 +08:00
const installOptions = [isYarn ? "add" : "install", "-D"];
2018-05-15 22:56:15 +08:00
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,
2018-05-15 22:56:15 +08:00
output: process.stderr
});
// If we're not in terminal mode, readline won't execute the callback function below. Return here
// so that we can set the exit code properly.
if (!questionInterface.terminal) {
console.error(
"You need to install 'webpack-cli' to use webpack via CLI.\n" +
"You can also install the CLI manually."
);
process.exit(1);
}
questionInterface.question(question, answer => {
2018-03-13 16:36:10 +08:00
questionInterface.close();
2018-05-09 20:00:15 +08:00
const normalizedAnswer = answer.toLowerCase().startsWith("y");
2018-05-09 20:00:15 +08:00
2018-05-15 22:56:15 +08:00
if (!normalizedAnswer) {
2018-05-09 20:00:15 +08:00
console.error(
2018-09-05 20:01:44 +08:00
"You need to install 'webpack-cli' to use webpack via CLI.\n" +
"You can also install the CLI manually."
2018-05-09 20:00:15 +08:00
);
process.exitCode = 1;
return;
}
2018-05-09 20:00:15 +08:00
console.log(
2019-03-29 05:57:38 +08:00
`Installing '${
cli.package
}' (running '${packageManager} ${installOptions.join(" ")} ${
cli.package
}')...`
2018-05-09 20:00:15 +08:00
);
2019-03-29 05:57:38 +08:00
runCommand(packageManager, installOptions.concat(cli.package))
2018-05-15 22:56:15 +08:00
.then(() => {
2019-03-29 05:57:38 +08:00
require(cli.package); //eslint-disable-line
2018-05-09 20:00:15 +08:00
})
.catch(error => {
console.error(error);
process.exitCode = 1;
});
});
2019-03-29 05:57:38 +08:00
} else {
const path = require("path");
2019-03-29 05:57:38 +08:00
const pkgPath = require.resolve(`${cli.package}/package.json`);
// eslint-disable-next-line node/no-missing-require
const pkg = require(pkgPath);
// eslint-disable-next-line node/no-missing-require
2019-03-29 05:57:38 +08:00
require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName]));
}