Projekt

Obecné

Profil

Stáhnout (4.16 KB) Statistiky
| Větev: | Revize:
1
#!/usr/bin/env node
2

    
3
// @ts-ignore
4
process.exitCode = 0;
5

    
6
/**
7
 * @param {string} command process to run
8
 * @param {string[]} args commandline arguments
9
 * @returns {Promise<void>} promise
10
 */
11
const runCommand = (command, args) => {
12
	const cp = require("child_process");
13
	return new Promise((resolve, reject) => {
14
		const executedCommand = cp.spawn(command, args, {
15
			stdio: "inherit",
16
			shell: true
17
		});
18

    
19
		executedCommand.on("error", error => {
20
			reject(error);
21
		});
22

    
23
		executedCommand.on("exit", code => {
24
			if (code === 0) {
25
				resolve();
26
			} else {
27
				reject();
28
			}
29
		});
30
	});
31
};
32

    
33
/**
34
 * @param {string} packageName name of the package
35
 * @returns {boolean} is the package installed?
36
 */
37
const isInstalled = packageName => {
38
	try {
39
		require.resolve(packageName);
40

    
41
		return true;
42
	} catch (err) {
43
		return false;
44
	}
45
};
46

    
47
/**
48
 * @typedef {Object} CliOption
49
 * @property {string} name display name
50
 * @property {string} package npm package name
51
 * @property {string} binName name of the executable file
52
 * @property {string} alias shortcut for choice
53
 * @property {boolean} installed currently installed?
54
 * @property {boolean} recommended is recommended
55
 * @property {string} url homepage
56
 * @property {string} description description
57
 */
58

    
59
/** @type {CliOption[]} */
60
const CLIs = [
61
	{
62
		name: "webpack-cli",
63
		package: "webpack-cli",
64
		binName: "webpack-cli",
65
		alias: "cli",
66
		installed: isInstalled("webpack-cli"),
67
		recommended: true,
68
		url: "https://github.com/webpack/webpack-cli",
69
		description: "The original webpack full-featured CLI."
70
	},
71
	{
72
		name: "webpack-command",
73
		package: "webpack-command",
74
		binName: "webpack-command",
75
		alias: "command",
76
		installed: isInstalled("webpack-command"),
77
		recommended: false,
78
		url: "https://github.com/webpack-contrib/webpack-command",
79
		description: "A lightweight, opinionated webpack CLI."
80
	}
81
];
82

    
83
const installedClis = CLIs.filter(cli => cli.installed);
84

    
85
if (installedClis.length === 0) {
86
	const path = require("path");
87
	const fs = require("fs");
88
	const readLine = require("readline");
89

    
90
	let notify =
91
		"One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:";
92

    
93
	for (const item of CLIs) {
94
		if (item.recommended) {
95
			notify += `\n - ${item.name} (${item.url})\n   ${item.description}`;
96
		}
97
	}
98

    
99
	console.error(notify);
100

    
101
	const isYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
102

    
103
	const packageManager = isYarn ? "yarn" : "npm";
104
	const installOptions = [isYarn ? "add" : "install", "-D"];
105

    
106
	console.error(
107
		`We will use "${packageManager}" to install the CLI via "${packageManager} ${installOptions.join(
108
			" "
109
		)}".`
110
	);
111

    
112
	const question = `Do you want to install 'webpack-cli' (yes/no): `;
113

    
114
	const questionInterface = readLine.createInterface({
115
		input: process.stdin,
116
		output: process.stderr
117
	});
118
	questionInterface.question(question, answer => {
119
		questionInterface.close();
120

    
121
		const normalizedAnswer = answer.toLowerCase().startsWith("y");
122

    
123
		if (!normalizedAnswer) {
124
			console.error(
125
				"You need to install 'webpack-cli' to use webpack via CLI.\n" +
126
					"You can also install the CLI manually."
127
			);
128
			process.exitCode = 1;
129

    
130
			return;
131
		}
132

    
133
		const packageName = "webpack-cli";
134

    
135
		console.log(
136
			`Installing '${packageName}' (running '${packageManager} ${installOptions.join(
137
				" "
138
			)} ${packageName}')...`
139
		);
140

    
141
		runCommand(packageManager, installOptions.concat(packageName))
142
			.then(() => {
143
				require(packageName); //eslint-disable-line
144
			})
145
			.catch(error => {
146
				console.error(error);
147
				process.exitCode = 1;
148
			});
149
	});
150
} else if (installedClis.length === 1) {
151
	const path = require("path");
152
	const pkgPath = require.resolve(`${installedClis[0].package}/package.json`);
153
	// eslint-disable-next-line node/no-missing-require
154
	const pkg = require(pkgPath);
155
	// eslint-disable-next-line node/no-missing-require
156
	require(path.resolve(
157
		path.dirname(pkgPath),
158
		pkg.bin[installedClis[0].binName]
159
	));
160
} else {
161
	console.warn(
162
		`You have installed ${installedClis
163
			.map(item => item.name)
164
			.join(
165
				" and "
166
			)} 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.`
167
	);
168

    
169
	// @ts-ignore
170
	process.exitCode = 1;
171
}
    (1-1/1)