From 49db9de1e357dc1028baba8576df0d27b5893c28 Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Wed, 29 Jan 2020 17:07:34 +0300 Subject: [PATCH 1/6] feat(cli): allow to pass flags to node.js closes #1084 closes #289 --- lib/bootstrap.js | 28 ++++++++++++++++++++++++++++ lib/utils/cli-flags.js | 8 ++++++++ package-lock.json | 28 +++++++--------------------- package.json | 2 +- test/node/a.js | 1 + test/node/bootstrap.js | 1 + test/node/bootstrap2.js | 1 + test/node/node.test.js | 23 +++++++++++++++++++++++ test/node/webpack.config.js | 9 +++++++++ 9 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 test/node/a.js create mode 100644 test/node/bootstrap.js create mode 100644 test/node/bootstrap2.js create mode 100644 test/node/node.test.js create mode 100644 test/node/webpack.config.js diff --git a/lib/bootstrap.js b/lib/bootstrap.js index a18995bee1f..72da794ea81 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ +const execa = require('execa'); const WebpackCLI = require('./webpack-cli'); const { core, commands } = require('./utils/cli-flags'); const cmdArgs = require('command-line-args'); @@ -6,6 +7,7 @@ const logger = require('./utils/logger'); require('./utils/process-log'); +const cliPath = require.resolve('../cli.js'); const isFlagPresent = (args, flag) => args.find(arg => [flag, `--${flag}`].includes(arg)); const isArgCommandName = (arg, cmd) => arg === cmd.name || arg === cmd.alias; const removeCmdFromArgs = (args, cmd) => args.filter(arg => !isArgCommandName(arg, cmd)); @@ -45,6 +47,7 @@ async function runCLI(cli, commandIsUsed) { let args; const helpFlagExists = isFlagPresent(process.argv, 'help'); const versionFlagExists = isFlagPresent(process.argv, 'version'); + const nodeArgsExists = isFlagPresent(process.argv, 'node-args'); if (helpFlagExists) { cli.runHelp(process.argv); @@ -52,6 +55,31 @@ async function runCLI(cli, commandIsUsed) { } else if (versionFlagExists) { cli.runVersion(); return; + } else if (nodeArgsExists) { + args = cmdArgs(core, { stopAtFirstUnknown: false, partial: true }); + const [, , ...rawArgs] = process.argv; + const cliArgs = []; + const nodeArgs = []; + let isNodsArg = false; + + for (const value of rawArgs) { + if (value === '--node-args') { + isNodsArg = true; + } else if (isNodsArg) { + isNodsArg = false; + nodeArgs.push(...value.split(' ')); + } else { + cliArgs.push(value); + } + } + + try { + const childProcess = execa('node', [...nodeArgs, cliPath, ...cliArgs], { stdio: 'inherit' }); + await childProcess; + process.exit(); + } catch (e) { + process.exit(e.exitCode); + } } if (commandIsUsed) { diff --git a/lib/utils/cli-flags.js b/lib/utils/cli-flags.js index c0b77a10b50..2ee462aa4f2 100644 --- a/lib/utils/cli-flags.js +++ b/lib/utils/cli-flags.js @@ -273,6 +273,14 @@ module.exports = { group: BASIC_GROUP, description: 'Get current version', }, + { + name: 'node-args', + usage: '--node-args "--max-old-space-size=1024"', + type: String, + multiple: true, + group: BASIC_GROUP, + description: 'NodeJS flags', + }, /* { name: "analyze", type: Boolean, diff --git a/package-lock.json b/package-lock.json index b19ff49e39c..4532ef4bf7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6466,7 +6466,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/execa/-/execa-3.3.0.tgz", "integrity": "sha512-j5Vit5WZR/cbHlqU97+qcnw9WHRCIL4V1SVe75VcHcD1JRBdt8fv0zw89b7CQHQdUHTt2VjuhcF5ibAgVOxqpg==", - "dev": true, "requires": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -6484,7 +6483,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6495,7 +6493,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -6503,20 +6500,17 @@ "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "npm-run-path": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.0.tgz", "integrity": "sha512-8eyAOAH+bYXFPSnNnKr3J+yoybe8O87Is5rtAQ8qRczJz1ajcsjg8l2oZqP+Ppx15Ii3S1vUTjQN2h4YO2tWWQ==", - "dev": true, "requires": { "path-key": "^3.0.0" } @@ -6525,7 +6519,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -6533,20 +6526,17 @@ "p-finally": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" }, "path-key": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz", - "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==", - "dev": true + "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==" }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -6554,14 +6544,12 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "which": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz", "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -8600,8 +8588,7 @@ "human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" }, "humanize-ms": { "version": "1.2.1", @@ -14111,8 +14098,7 @@ "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, "strip-indent": { "version": "2.0.0", diff --git a/package.json b/package.json index dcfece0d599..3f0f3d24771 100644 --- a/package.json +++ b/package.json @@ -119,6 +119,7 @@ "cli-table3": "^0.5.1", "command-line-args": "^5.1.1", "command-line-usage": "^6.1.0", + "execa": "^3.2.0", "import-local": "^3.0.2", "interpret": "^2.0.0", "terser-webpack-plugin": "^2.3.2", @@ -144,7 +145,6 @@ "eslint-config-prettier": "^6.5.0", "eslint-plugin-node": "^10.0.0", "eslint-plugin-prettier": "^3.1.1", - "execa": "^3.2.0", "husky": "^3.0.9", "jest": "^24.9.0", "jest-cli": "^24.9.0", diff --git a/test/node/a.js b/test/node/a.js new file mode 100644 index 00000000000..735d820f253 --- /dev/null +++ b/test/node/a.js @@ -0,0 +1 @@ +module.exports = 'a.js'; diff --git a/test/node/bootstrap.js b/test/node/bootstrap.js new file mode 100644 index 00000000000..0980f54d442 --- /dev/null +++ b/test/node/bootstrap.js @@ -0,0 +1 @@ +console.log('---from bootstrap.js---'); diff --git a/test/node/bootstrap2.js b/test/node/bootstrap2.js new file mode 100644 index 00000000000..5105ea40c01 --- /dev/null +++ b/test/node/bootstrap2.js @@ -0,0 +1 @@ +console.log('---from bootstrap2.js---'); diff --git a/test/node/node.test.js b/test/node/node.test.js new file mode 100644 index 00000000000..0daa6eef88f --- /dev/null +++ b/test/node/node.test.js @@ -0,0 +1,23 @@ +'use strict'; +const { stat } = require('fs'); +const { resolve, sep } = require('path'); +const { run, extractSummary } = require('../utils/test-utils'); + +describe('node flags', () => { + it('is able to options flags to node js', done => { + const { stdout, stderr } = run(__dirname, ['--node-args', `--require=${resolve(__dirname, 'bootstrap.js')}`, '--node-args', `-r ${resolve(__dirname, 'bootstrap2.js')}`, '--output', './bin/[name].bundle.js'], false); + expect(stderr).toContain(''); + expect(stdout).toContain('---from bootstrap.js---'); + expect(stdout).toContain('---from bootstrap2.js---'); + const summary = extractSummary(stdout); + const outputDir = 'node/bin'; + const outDirectoryFromCompiler = summary['Output Directory'].split(sep); + const outDirToMatch = outDirectoryFromCompiler.slice(outDirectoryFromCompiler.length - 2, outDirectoryFromCompiler.length).join('/'); + expect(outDirToMatch).toContain(outputDir); + stat(resolve(__dirname, './bin/main.bundle.js'), (err, stats) => { + expect(err).toBe(null); + expect(stats.isFile()).toBe(true); + done(); + }); + }); +}); diff --git a/test/node/webpack.config.js b/test/node/webpack.config.js new file mode 100644 index 00000000000..b58f8a91f0d --- /dev/null +++ b/test/node/webpack.config.js @@ -0,0 +1,9 @@ +const { resolve } = require('path'); + +module.exports = { + entry: './a.js', + output: { + path: resolve(__dirname, 'binary'), + filename: 'a.bundle.js', + }, +}; From d853b79f8ebc0cb41fb47c354b7ab85ac972bd3c Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Wed, 29 Jan 2020 17:27:41 +0300 Subject: [PATCH 2/6] chore(cli): fix snapshot --- test/help/__snapshots__/help-single-arg.test.js.snap | 1 + 1 file changed, 1 insertion(+) diff --git a/test/help/__snapshots__/help-single-arg.test.js.snap b/test/help/__snapshots__/help-single-arg.test.js.snap index 4d120ade45d..e983d7fb240 100644 --- a/test/help/__snapshots__/help-single-arg.test.js.snap +++ b/test/help/__snapshots__/help-single-arg.test.js.snap @@ -44,6 +44,7 @@ Options -d, --dev Run development build -p, --prod Run production build --version Get current version + --node-args string[] NodeJS flags Made with ♥️ by the webpack team " `; From a0e80369823fc347b1c30b31aba649dc8b4bf01e Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Wed, 29 Jan 2020 17:50:29 +0300 Subject: [PATCH 3/6] chore(cli): drop nodejs 8 from ci --- .travis.yml | 4 ---- azure-pipelines-template.yml | 4 +--- package.json | 2 +- test/node/node.test.js | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 51d18a6c9ef..405134e68cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,6 @@ language: node_js node_js: - "12" - "10" - - "8" cache: directories: - ~/.npm @@ -20,9 +19,6 @@ matrix: - os: linux node_js: "10" env: JOB_PART=integration - - os: linux - node_js: "8" - env: JOB_PART=integration before_install: - "[[ $(node -v) =~ ^v9.*$ ]] || npm install -g npm@latest" # skipped when using node 9 diff --git a/azure-pipelines-template.yml b/azure-pipelines-template.yml index e752c32868e..96d81cc753d 100644 --- a/azure-pipelines-template.yml +++ b/azure-pipelines-template.yml @@ -8,9 +8,7 @@ jobs: node-12: node_version: ^12.0.0 node-10: - node_version: ^10.10.0 - node-8: - node_version: ^8.12.0 + node_version: ^10.13.0 steps: - task: NodeTool@0 inputs: diff --git a/package.json b/package.json index 3f0f3d24771..2ae43b85a48 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "main": "cli.js", "engines": { - "node": ">=8.0.0" + "node": ">=10.13.0" }, "keywords": [ "webpack", diff --git a/test/node/node.test.js b/test/node/node.test.js index 0daa6eef88f..eafa74dc2b9 100644 --- a/test/node/node.test.js +++ b/test/node/node.test.js @@ -6,7 +6,7 @@ const { run, extractSummary } = require('../utils/test-utils'); describe('node flags', () => { it('is able to options flags to node js', done => { const { stdout, stderr } = run(__dirname, ['--node-args', `--require=${resolve(__dirname, 'bootstrap.js')}`, '--node-args', `-r ${resolve(__dirname, 'bootstrap2.js')}`, '--output', './bin/[name].bundle.js'], false); - expect(stderr).toContain(''); + expect(stderr).toBe(''); expect(stdout).toContain('---from bootstrap.js---'); expect(stdout).toContain('---from bootstrap2.js---'); const summary = extractSummary(stdout); From c7fd491054eb840faa1dc899669b04c42307f686 Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Wed, 29 Jan 2020 18:03:24 +0300 Subject: [PATCH 4/6] chore(cli): fix test --- test/node/node.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/node/node.test.js b/test/node/node.test.js index eafa74dc2b9..073d79d1134 100644 --- a/test/node/node.test.js +++ b/test/node/node.test.js @@ -5,8 +5,7 @@ const { run, extractSummary } = require('../utils/test-utils'); describe('node flags', () => { it('is able to options flags to node js', done => { - const { stdout, stderr } = run(__dirname, ['--node-args', `--require=${resolve(__dirname, 'bootstrap.js')}`, '--node-args', `-r ${resolve(__dirname, 'bootstrap2.js')}`, '--output', './bin/[name].bundle.js'], false); - expect(stderr).toBe(''); + const { stdout } = run(__dirname, ['--node-args', `--require=${resolve(__dirname, 'bootstrap.js')}`, '--node-args', `-r ${resolve(__dirname, 'bootstrap2.js')}`, '--output', './bin/[name].bundle.js'], false); expect(stdout).toContain('---from bootstrap.js---'); expect(stdout).toContain('---from bootstrap2.js---'); const summary = extractSummary(stdout); From 4bfff9cac57b141ba29e4138d31b32f2cbec4374 Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Wed, 29 Jan 2020 21:07:40 +0300 Subject: [PATCH 5/6] feat(cli): add parseArgs helper --- lib/bootstrap.js | 17 ++--------------- lib/utils/parse-args.js | 26 ++++++++++++++++++++++++++ test/node/node.test.js | 27 ++++++++++++++++++++++++++- 3 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 lib/utils/parse-args.js diff --git a/lib/bootstrap.js b/lib/bootstrap.js index 72da794ea81..87234a5ac81 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -4,6 +4,7 @@ const WebpackCLI = require('./webpack-cli'); const { core, commands } = require('./utils/cli-flags'); const cmdArgs = require('command-line-args'); const logger = require('./utils/logger'); +const parseArgs = require('./utils/parse-args'); require('./utils/process-log'); @@ -56,22 +57,8 @@ async function runCLI(cli, commandIsUsed) { cli.runVersion(); return; } else if (nodeArgsExists) { - args = cmdArgs(core, { stopAtFirstUnknown: false, partial: true }); const [, , ...rawArgs] = process.argv; - const cliArgs = []; - const nodeArgs = []; - let isNodsArg = false; - - for (const value of rawArgs) { - if (value === '--node-args') { - isNodsArg = true; - } else if (isNodsArg) { - isNodsArg = false; - nodeArgs.push(...value.split(' ')); - } else { - cliArgs.push(value); - } - } + const { cliArgs, nodeArgs } = parseArgs(rawArgs); try { const childProcess = execa('node', [...nodeArgs, cliPath, ...cliArgs], { stdio: 'inherit' }); diff --git a/lib/utils/parse-args.js b/lib/utils/parse-args.js new file mode 100644 index 00000000000..d504c14e614 --- /dev/null +++ b/lib/utils/parse-args.js @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ + +/** + * Parse cli args and split these to args for node js and the rest + * + * @param {string[]} rawArgs raw cli args + * @returns {{cliArgs: string[], nodeArgs: string[]}} cli and nodejs args + */ +module.exports = rawArgs => { + const cliArgs = []; + const nodeArgs = []; + let isNodeArg = false; + + for (const value of rawArgs) { + if (value === '--node-args') { + isNodeArg = true; + } else if (isNodeArg) { + isNodeArg = false; + nodeArgs.push(...value.split(' ')); + } else { + cliArgs.push(value); + } + } + + return { cliArgs, nodeArgs }; +}; diff --git a/test/node/node.test.js b/test/node/node.test.js index 073d79d1134..469268affcd 100644 --- a/test/node/node.test.js +++ b/test/node/node.test.js @@ -2,9 +2,34 @@ const { stat } = require('fs'); const { resolve, sep } = require('path'); const { run, extractSummary } = require('../utils/test-utils'); +const parseArgs = require('../../lib/utils/parse-args'); describe('node flags', () => { - it('is able to options flags to node js', done => { + it('parseArgs helper must work correctly', () => { + [ + { + rawArgs: ['--foo', '--bar', '--baz=quux'], + expectedCliArgs: ['--foo', '--bar', '--baz=quux'], + expectedNodeArgs: [], + }, + { + rawArgs: ['--foo', '--bar', '--baz=quux', '--node-args', '--name1=value1', '--node-args', '--name2 value2'], + expectedCliArgs: ['--foo', '--bar', '--baz=quux'], + expectedNodeArgs: ['--name1=value1', '--name2', 'value2'], + }, + { + rawArgs: ['--node-args', '--name1=value1', '--node-args', '--name2 value2', '--node-args', '-n=v', '--node-args', '-k v'], + expectedCliArgs: [], + expectedNodeArgs: ['--name1=value1', '--name2', 'value2', '-n=v', '-k', 'v'], + }, + ].map(({ rawArgs, expectedNodeArgs, expectedCliArgs }) => { + const { nodeArgs, cliArgs } = parseArgs(rawArgs); + expect(nodeArgs).toEqual(expectedNodeArgs); + expect(cliArgs).toEqual(expectedCliArgs); + }); + }); + + it('is able to pass the options flags to node js', done => { const { stdout } = run(__dirname, ['--node-args', `--require=${resolve(__dirname, 'bootstrap.js')}`, '--node-args', `-r ${resolve(__dirname, 'bootstrap2.js')}`, '--output', './bin/[name].bundle.js'], false); expect(stdout).toContain('---from bootstrap.js---'); expect(stdout).toContain('---from bootstrap2.js---'); From 69d6202b1aa6b07c896040fc2cf36719f1ea213d Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Thu, 30 Jan 2020 03:41:17 +0300 Subject: [PATCH 6/6] feat(cli): parseArgs now supports --node-args="..." syntax --- lib/bootstrap.js | 2 +- lib/utils/parse-args.js | 3 +++ test/node/node.test.js | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/bootstrap.js b/lib/bootstrap.js index 87234a5ac81..7ccbcfe3860 100644 --- a/lib/bootstrap.js +++ b/lib/bootstrap.js @@ -48,7 +48,7 @@ async function runCLI(cli, commandIsUsed) { let args; const helpFlagExists = isFlagPresent(process.argv, 'help'); const versionFlagExists = isFlagPresent(process.argv, 'version'); - const nodeArgsExists = isFlagPresent(process.argv, 'node-args'); + const nodeArgsExists = process.argv.find(arg => arg.includes('--node-args')); if (helpFlagExists) { cli.runHelp(process.argv); diff --git a/lib/utils/parse-args.js b/lib/utils/parse-args.js index d504c14e614..3285410ae70 100644 --- a/lib/utils/parse-args.js +++ b/lib/utils/parse-args.js @@ -14,6 +14,9 @@ module.exports = rawArgs => { for (const value of rawArgs) { if (value === '--node-args') { isNodeArg = true; + } else if (value.startsWith('--node-args=')) { + const [, argValue] = value.match(/^--node-args="?(.+?)"?$/); + nodeArgs.push(argValue); } else if (isNodeArg) { isNodeArg = false; nodeArgs.push(...value.split(' ')); diff --git a/test/node/node.test.js b/test/node/node.test.js index 469268affcd..d2396935b37 100644 --- a/test/node/node.test.js +++ b/test/node/node.test.js @@ -18,9 +18,9 @@ describe('node flags', () => { expectedNodeArgs: ['--name1=value1', '--name2', 'value2'], }, { - rawArgs: ['--node-args', '--name1=value1', '--node-args', '--name2 value2', '--node-args', '-n=v', '--node-args', '-k v'], + rawArgs: ['--node-args', '--name1=value1', '--node-args', '--name2="value2"', '--node-args', '--name3 value3', '--node-args', '-k v'], expectedCliArgs: [], - expectedNodeArgs: ['--name1=value1', '--name2', 'value2', '-n=v', '-k', 'v'], + expectedNodeArgs: ['--name1=value1', '--name2="value2"', '--name3', 'value3', '-k', 'v'], }, ].map(({ rawArgs, expectedNodeArgs, expectedCliArgs }) => { const { nodeArgs, cliArgs } = parseArgs(rawArgs);