| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2020-03-13 00:51:26 +08:00
										 |  |  |  * @param {string[]} args command line arguments | 
					
						
							| 
									
										
										
										
											2018-05-15 22:56:15 +08:00
										 |  |  |  * @returns {Promise<void>} promise | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const runCommand = (command, args) => { | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 	const cp = require("child_process"); | 
					
						
							| 
									
										
										
										
											2018-02-26 06:17:27 +08:00
										 |  |  | 	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 | 
					
						
							| 
									
										
										
										
											2018-02-26 06:17:27 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 		executedCommand.on("error", error => { | 
					
						
							| 
									
										
										
										
											2018-02-26 06:17:27 +08:00
										 |  |  | 			reject(error); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 		executedCommand.on("exit", code => { | 
					
						
							|  |  |  | 			if (code === 0) { | 
					
						
							| 
									
										
										
										
											2018-05-15 22:56:15 +08:00
										 |  |  | 				resolve(); | 
					
						
							| 
									
										
										
										
											2018-02-26 06:17:27 +08:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				reject(); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2018-02-08 08:28:38 +08:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											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 => { | 
					
						
							| 
									
										
										
										
											2021-06-07 22:34:01 +08:00
										 |  |  | 	if (process.versions.pnp) { | 
					
						
							| 
									
										
										
										
											2018-05-09 20:00:15 +08:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-06-07 22:34:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	const path = require("path"); | 
					
						
							|  |  |  | 	const fs = require("graceful-fs"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	let dir = __dirname; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do { | 
					
						
							|  |  |  | 		try { | 
					
						
							|  |  |  | 			if ( | 
					
						
							|  |  |  | 				fs.statSync(path.join(dir, "node_modules", packageName)).isDirectory() | 
					
						
							|  |  |  | 			) { | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} catch (_error) { | 
					
						
							|  |  |  | 			// Nothing
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} while (dir !== (dir = path.dirname(dir))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2018-05-15 22:56:15 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-28 19:10:10 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @param {CliOption} cli options | 
					
						
							|  |  |  |  * @returns {void} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | const runCli = cli => { | 
					
						
							|  |  |  | 	const path = require("path"); | 
					
						
							|  |  |  | 	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
 | 
					
						
							|  |  |  | 	require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-15 22:56:15 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @typedef {Object} CliOption | 
					
						
							|  |  |  |  * @property {string} name display name | 
					
						
							|  |  |  |  * @property {string} package npm package name | 
					
						
							| 
									
										
										
										
											2018-06-15 02:39:42 +08:00
										 |  |  |  * @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) { | 
					
						
							| 
									
										
										
										
											2018-02-09 00:01:23 +08:00
										 |  |  | 	const path = require("path"); | 
					
						
							| 
									
										
										
										
											2019-06-11 19:09:42 +08:00
										 |  |  | 	const fs = require("graceful-fs"); | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 	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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 10:58:32 +08:00
										 |  |  | 	let packageManager; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 20:33:05 +08:00
										 |  |  | 	if (fs.existsSync(path.resolve(process.cwd(), "yarn.lock"))) { | 
					
						
							| 
									
										
										
										
											2020-11-07 10:58:32 +08:00
										 |  |  | 		packageManager = "yarn"; | 
					
						
							| 
									
										
										
										
											2020-11-20 20:33:05 +08:00
										 |  |  | 	} else if (fs.existsSync(path.resolve(process.cwd(), "pnpm-lock.yaml"))) { | 
					
						
							| 
									
										
										
										
											2020-11-07 10:58:32 +08:00
										 |  |  | 		packageManager = "pnpm"; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		packageManager = "npm"; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-02-09 00:01:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-20 20:33:05 +08:00
										 |  |  | 	const installOptions = [packageManager === "yarn" ? "add" : "install", "-D"]; | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-15 22:56:15 +08:00
										 |  |  | 	console.error( | 
					
						
							|  |  |  | 		`We will use "${packageManager}" to install the CLI via "${packageManager} ${installOptions.join( | 
					
						
							|  |  |  | 			" " | 
					
						
							| 
									
										
										
										
											2021-01-06 20:31:40 +08:00
										 |  |  | 		)} ${cli.package}".`
 | 
					
						
							| 
									
										
										
										
											2018-05-15 22:56:15 +08:00
										 |  |  | 	); | 
					
						
							| 
									
										
										
										
											2018-02-26 06:17:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-10 16:21:38 +08:00
										 |  |  | 	const question = `Do you want to install 'webpack-cli' (yes/no): `; | 
					
						
							| 
									
										
										
										
											2018-02-26 06:17:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 	const questionInterface = readLine.createInterface({ | 
					
						
							|  |  |  | 		input: process.stdin, | 
					
						
							| 
									
										
										
										
											2018-05-15 22:56:15 +08:00
										 |  |  | 		output: process.stderr | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2020-02-07 02:04:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-10 23:08:16 +08:00
										 |  |  | 	// In certain scenarios (e.g. when STDIN is not in terminal mode), the callback function will not be
 | 
					
						
							|  |  |  | 	// executed. Setting the exit code here to ensure the script exits correctly in those cases. The callback
 | 
					
						
							|  |  |  | 	// function is responsible for clearing the exit code if the user wishes to install webpack-cli.
 | 
					
						
							|  |  |  | 	process.exitCode = 1; | 
					
						
							| 
									
										
										
										
											2018-03-07 04:07:54 +08:00
										 |  |  | 	questionInterface.question(question, answer => { | 
					
						
							| 
									
										
										
										
											2018-03-13 16:36:10 +08:00
										 |  |  | 		questionInterface.close(); | 
					
						
							| 
									
										
										
										
											2018-05-09 20:00:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-29 22:37:41 +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
										 |  |  | 			); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2018-02-08 08:28:38 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-02-10 23:08:16 +08:00
										 |  |  | 		process.exitCode = 0; | 
					
						
							| 
									
										
										
										
											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(() => { | 
					
						
							| 
									
										
										
										
											2020-10-28 19:10:10 +08:00
										 |  |  | 				runCli(cli); | 
					
						
							| 
									
										
										
										
											2018-05-09 20:00:15 +08:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 			.catch(error => { | 
					
						
							|  |  |  | 				console.error(error); | 
					
						
							|  |  |  | 				process.exitCode = 1; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2018-02-09 00:01:23 +08:00
										 |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2019-03-29 05:57:38 +08:00
										 |  |  | } else { | 
					
						
							| 
									
										
										
										
											2020-10-28 19:10:10 +08:00
										 |  |  | 	runCli(cli); | 
					
						
							| 
									
										
										
										
											2017-12-13 18:30:15 +08:00
										 |  |  | } |