source: frontend/node_modules/webpack/bin/webpack.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 4.5 KB
Line 
1#!/usr/bin/env node
2
3"use strict";
4
5/**
6 * @param {string} command process to run
7 * @param {string[]} args command line arguments
8 * @returns {Promise<void>} promise
9 */
10const runCommand = (command, args) => {
11 const cp = require("child_process");
12
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 */
37const isInstalled = (packageName) => {
38 if (process.versions.pnp) {
39 return true;
40 }
41
42 const path = require("path");
43 const fs = require("graceful-fs");
44
45 let dir = __dirname;
46
47 do {
48 try {
49 if (
50 fs.statSync(path.join(dir, "node_modules", packageName)).isDirectory()
51 ) {
52 return true;
53 }
54 } catch (_error) {
55 // Nothing
56 }
57 } while (dir !== (dir = path.dirname(dir)));
58
59 // https://github.com/nodejs/node/blob/v18.9.1/lib/internal/modules/cjs/loader.js#L1274
60 const { globalPaths } =
61 /** @type {typeof import("module") & { globalPaths: string[] }} */
62 (require("module"));
63
64 for (const internalPath of globalPaths) {
65 try {
66 if (fs.statSync(path.join(internalPath, packageName)).isDirectory()) {
67 return true;
68 }
69 } catch (_error) {
70 // Nothing
71 }
72 }
73
74 return false;
75};
76
77/**
78 * @param {CliOption} cli options
79 * @returns {void}
80 */
81const runCli = (cli) => {
82 const path = require("path");
83
84 const pkgPath = require.resolve(`${cli.package}/package.json`);
85
86 /** @type {Record<string, EXPECTED_ANY> & { type: string, bin: Record<string, string> }} */
87 const pkg = require(pkgPath);
88
89 if (pkg.type === "module" || /\.mjs/i.test(pkg.bin[cli.binName])) {
90 import(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName])).catch(
91 (err) => {
92 console.error(err);
93 process.exitCode = 1;
94 }
95 );
96 } else {
97 require(path.resolve(path.dirname(pkgPath), pkg.bin[cli.binName]));
98 }
99};
100
101/**
102 * @typedef {object} CliOption
103 * @property {string} name display name
104 * @property {string} package npm package name
105 * @property {string} binName name of the executable file
106 * @property {boolean} installed currently installed?
107 * @property {string} url homepage
108 */
109
110/** @type {CliOption} */
111const cli = {
112 name: "webpack-cli",
113 package: "webpack-cli",
114 binName: "webpack-cli",
115 installed: isInstalled("webpack-cli"),
116 url: "https://github.com/webpack/webpack-cli"
117};
118
119if (!cli.installed) {
120 const path = require("path");
121 const fs = require("graceful-fs");
122 const readLine = require("readline");
123
124 const notify = `CLI for webpack must be installed.\n ${cli.name} (${cli.url})\n`;
125
126 console.error(notify);
127
128 /** @type {string | undefined} */
129 let packageManager;
130
131 if (fs.existsSync(path.resolve(process.cwd(), "yarn.lock"))) {
132 packageManager = "yarn";
133 } else if (fs.existsSync(path.resolve(process.cwd(), "pnpm-lock.yaml"))) {
134 packageManager = "pnpm";
135 } else {
136 packageManager = "npm";
137 }
138
139 const installOptions = [packageManager === "yarn" ? "add" : "install", "-D"];
140
141 console.error(
142 `We will use "${packageManager}" to install the CLI via "${packageManager} ${installOptions.join(
143 " "
144 )} ${cli.package}".`
145 );
146
147 const question = "Do you want to install 'webpack-cli' (yes/no): ";
148
149 const questionInterface = readLine.createInterface({
150 input: process.stdin,
151 output: process.stderr
152 });
153
154 // In certain scenarios (e.g. when STDIN is not in terminal mode), the callback function will not be
155 // executed. Setting the exit code here to ensure the script exits correctly in those cases. The callback
156 // function is responsible for clearing the exit code if the user wishes to install webpack-cli.
157 process.exitCode = 1;
158 questionInterface.question(question, (answer) => {
159 questionInterface.close();
160
161 const normalizedAnswer = answer.toLowerCase().startsWith("y");
162
163 if (!normalizedAnswer) {
164 console.error(
165 "You need to install 'webpack-cli' to use webpack via CLI.\n" +
166 "You can also install the CLI manually."
167 );
168
169 return;
170 }
171 process.exitCode = 0;
172
173 console.log(
174 `Installing '${
175 cli.package
176 }' (running '${packageManager} ${installOptions.join(" ")} ${
177 cli.package
178 }')...`
179 );
180
181 runCommand(
182 /** @type {string} */
183 (packageManager),
184 [...installOptions, cli.package]
185 )
186 .then(() => {
187 runCli(cli);
188 })
189 .catch((err) => {
190 console.error(err);
191 process.exitCode = 1;
192 });
193 });
194} else {
195 runCli(cli);
196}
Note: See TracBrowser for help on using the repository browser.