diff --git a/bin/process-node-flags.js b/bin/process-node-flags.js new file mode 100644 index 00000000000..e7fdb121033 --- /dev/null +++ b/bin/process-node-flags.js @@ -0,0 +1,47 @@ +const spawn = require("cross-spawn"); +const path = require("path"); +/** + * Lookup for prefixed arguments (node.) + * place them before webpack cli arguments and spawns + * a different process using these V8/Node flags. + * By Doing that, user has the power to provide any node options, e.g --max-old-space-size=1024 + * and these are going to be correctly used. + * + * @param {array} argv - Arguments input by the user directly to CLI + * @returns {Void} void + */ +module.exports = function(argv) { + const args = [path.join(__dirname, "webpack.js")]; + + argv.slice(2).forEach((arg) => { + if (arg.includes("node.")) { + args.unshift(arg.replace("node.", "")); + } else { + args.push(arg); + } + }); + + const webpackCliProcess = spawn(process.execPath, args, { + stdio: "inherit", + }); + + webpackCliProcess.on("exit", (code, signal) => { + process.on("exit", () => { + if (signal) { + process.kill(process.pid, signal); + } else { + process.exit(code); + } + }); + }); + + /** + * Terminate children + * just in case the current one is terminated. + */ + process.on("SIGINT", () => { + webpackCliProcess.kill("SIGINT"); + webpackCliProcess.kill("SIGTERM"); + }); + +}; diff --git a/bin/webpack.js b/bin/webpack.js index c09cb9ddb94..3a902ffe3df 100755 --- a/bin/webpack.js +++ b/bin/webpack.js @@ -32,6 +32,13 @@ "info" ]; + const nodeFlags = process.argv.filter((arg) => arg.includes("node.")); + + if (nodeFlags.length) { + require("./process-node-flags")(process.argv); + return; + } + const NON_COMPILATION_CMD = process.argv.find(arg => { if (arg === "serve") { global.process.argv = global.process.argv.filter(a => a !== "serve"); @@ -261,8 +268,8 @@ For more information, see https://webpack.js.org/api/cli/.`); */ const stdout = argv.silent ? { - write: () => {} - } // eslint-disable-line + write: () => { } + } // eslint-disable-line : process.stdout; function ifArg(name, fn, init) { diff --git a/test/binCases/node-flags/advanced/index.js b/test/binCases/node-flags/advanced/index.js new file mode 100644 index 00000000000..0d24e266fe2 --- /dev/null +++ b/test/binCases/node-flags/advanced/index.js @@ -0,0 +1 @@ +module.exports = "index"; diff --git a/test/binCases/node-flags/advanced/stdin.js b/test/binCases/node-flags/advanced/stdin.js new file mode 100644 index 00000000000..5f0abbea8c5 --- /dev/null +++ b/test/binCases/node-flags/advanced/stdin.js @@ -0,0 +1,9 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + expect(code).toBe(0); + expect(stdout).toEqual(expect.anything()); + expect(stdout[5]).toContain("main.js"); + expect(stdout[7]).toMatch(/index\.js.*\{0\}/); + expect(stderr).toHaveLength(0); +}; diff --git a/test/binCases/node-flags/advanced/test.opts b/test/binCases/node-flags/advanced/test.opts new file mode 100644 index 00000000000..9d73e2a87ab --- /dev/null +++ b/test/binCases/node-flags/advanced/test.opts @@ -0,0 +1,11 @@ +--node.max_old_space_size=1024 +--node.no-warnings +--node.turbo_jt +--display-used-exports +--display-entrypoints +--profile +--bail +--labeled-modules +--optimize-minimize +--mode production +./index.js diff --git a/test/binCases/node-flags/only-node-flags/index.js b/test/binCases/node-flags/only-node-flags/index.js new file mode 100644 index 00000000000..0d24e266fe2 --- /dev/null +++ b/test/binCases/node-flags/only-node-flags/index.js @@ -0,0 +1 @@ +module.exports = "index"; diff --git a/test/binCases/node-flags/only-node-flags/stdin.js b/test/binCases/node-flags/only-node-flags/stdin.js new file mode 100644 index 00000000000..5f0abbea8c5 --- /dev/null +++ b/test/binCases/node-flags/only-node-flags/stdin.js @@ -0,0 +1,9 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + expect(code).toBe(0); + expect(stdout).toEqual(expect.anything()); + expect(stdout[5]).toContain("main.js"); + expect(stdout[7]).toMatch(/index\.js.*\{0\}/); + expect(stderr).toHaveLength(0); +}; diff --git a/test/binCases/node-flags/only-node-flags/test.opts b/test/binCases/node-flags/only-node-flags/test.opts new file mode 100644 index 00000000000..80ea00f48b6 --- /dev/null +++ b/test/binCases/node-flags/only-node-flags/test.opts @@ -0,0 +1,3 @@ +--node.no-deprecation +--node.no-warnings +./index.js diff --git a/test/binCases/node-flags/output/index.js b/test/binCases/node-flags/output/index.js new file mode 100644 index 00000000000..0d24e266fe2 --- /dev/null +++ b/test/binCases/node-flags/output/index.js @@ -0,0 +1 @@ +module.exports = "index"; diff --git a/test/binCases/node-flags/output/stdin.js b/test/binCases/node-flags/output/stdin.js new file mode 100644 index 00000000000..5f0abbea8c5 --- /dev/null +++ b/test/binCases/node-flags/output/stdin.js @@ -0,0 +1,9 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + expect(code).toBe(0); + expect(stdout).toEqual(expect.anything()); + expect(stdout[5]).toContain("main.js"); + expect(stdout[7]).toMatch(/index\.js.*\{0\}/); + expect(stderr).toHaveLength(0); +}; diff --git a/test/binCases/node-flags/output/test.opts b/test/binCases/node-flags/output/test.opts new file mode 100644 index 00000000000..ba8c1bd8345 --- /dev/null +++ b/test/binCases/node-flags/output/test.opts @@ -0,0 +1,6 @@ +--node.no-deprecation +--node.no-warnings +--display-used-exports +--display-entrypoints +--mode production +./index.js