Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to pass flags to node.js #1195

Merged
merged 6 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ language: node_js
node_js:
- "12"
- "10"
- "8"
cache:
directories:
- ~/.npm
Expand All @@ -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
Expand Down
4 changes: 1 addition & 3 deletions azure-pipelines-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
15 changes: 15 additions & 0 deletions lib/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
/* 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');
const logger = require('./utils/logger');
const parseArgs = require('./utils/parse-args');

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));
Expand Down Expand Up @@ -45,13 +48,25 @@ async function runCLI(cli, commandIsUsed) {
let args;
const helpFlagExists = isFlagPresent(process.argv, 'help');
const versionFlagExists = isFlagPresent(process.argv, 'version');
const nodeArgsExists = process.argv.find(arg => arg.includes('--node-args'));

if (helpFlagExists) {
cli.runHelp(process.argv);
return;
} else if (versionFlagExists) {
cli.runVersion();
return;
} else if (nodeArgsExists) {
const [, , ...rawArgs] = process.argv;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gosh this is lovely! <3

const { cliArgs, nodeArgs } = parseArgs(rawArgs);

try {
const childProcess = execa('node', [...nodeArgs, cliPath, ...cliArgs], { stdio: 'inherit' });
smelukov marked this conversation as resolved.
Show resolved Hide resolved
await childProcess;
process.exit();
} catch (e) {
process.exit(e.exitCode);
}
}

if (commandIsUsed) {
Expand Down
8 changes: 8 additions & 0 deletions lib/utils/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
29 changes: 29 additions & 0 deletions lib/utils/parse-args.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* 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 (value.startsWith('--node-args=')) {
const [, argValue] = value.match(/^--node-args="?(.+?)"?$/);
nodeArgs.push(argValue);
} else if (isNodeArg) {
isNodeArg = false;
nodeArgs.push(...value.split(' '));
} else {
cliArgs.push(value);
}
}

return { cliArgs, nodeArgs };
};
28 changes: 7 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"main": "cli.js",
"engines": {
"node": ">=8.0.0"
"node": ">=10.13.0"
},
"keywords": [
"webpack",
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down
1 change: 1 addition & 0 deletions test/help/__snapshots__/help-single-arg.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
`;
1 change: 1 addition & 0 deletions test/node/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'a.js';
1 change: 1 addition & 0 deletions test/node/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('---from bootstrap.js---');
1 change: 1 addition & 0 deletions test/node/bootstrap2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('---from bootstrap2.js---');
47 changes: 47 additions & 0 deletions test/node/node.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';
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('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', '--name3 value3', '--node-args', '-k v'],
expectedCliArgs: [],
expectedNodeArgs: ['--name1=value1', '--name2="value2"', '--name3', 'value3', '-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---');
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();
});
});
});
9 changes: 9 additions & 0 deletions test/node/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const { resolve } = require('path');

module.exports = {
entry: './a.js',
output: {
path: resolve(__dirname, 'binary'),
filename: 'a.bundle.js',
},
};