Skip to content

Commit ac2e52c

Browse files
authored
feat(webpack-cli): allow multiple entry files (#1619)
1 parent 1a4947b commit ac2e52c

File tree

15 files changed

+94
-21
lines changed

15 files changed

+94
-21
lines changed

packages/webpack-cli/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Available Commands
3535
3636
Options
3737
38-
--entry string The entry point of your application.
38+
--entry string[] The entry point(s) of your application.
3939
-c, --config string Provide path to a webpack configuration file
4040
-m, --merge string Merge a configuration file using webpack-merge
4141
--progress Print compilation progress during build

packages/webpack-cli/__tests__/arg-parser.test.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ const basicOptions = [
5151
},
5252
description: 'custom type flag',
5353
},
54+
{
55+
name: 'multi-flag',
56+
usage: '--multi-flag <value>',
57+
type: String,
58+
multiple: true,
59+
description: 'multi flag',
60+
},
5461
];
5562

5663
const helpAndVersionOptions = basicOptions.slice(0);
@@ -163,6 +170,16 @@ describe('arg-parser', () => {
163170
expect(warnMock.mock.calls.length).toEqual(0);
164171
});
165172

173+
it('handles multiple same args', () => {
174+
const res = argParser(basicOptions, ['--multi-flag', 'a.js', '--multi-flag', 'b.js'], true);
175+
expect(res.unknownArgs.length).toEqual(0);
176+
expect(res.opts).toEqual({
177+
multiFlag: ['a.js', 'b.js'],
178+
stringFlagWithDefault: 'default-value',
179+
});
180+
expect(warnMock.mock.calls.length).toEqual(0);
181+
});
182+
166183
it('handles additional node args from argv', () => {
167184
const res = argParser(basicOptions, ['node', 'index.js', '--bool-flag', '--string-flag', 'val'], false);
168185
expect(res.unknownArgs.length).toEqual(0);
@@ -210,7 +227,7 @@ describe('arg-parser', () => {
210227
it('parses webpack args', () => {
211228
const res = argParser(core, ['--entry', 'test.js', '--hot', '-o', './dist/'], true);
212229
expect(res.unknownArgs.length).toEqual(0);
213-
expect(res.opts.entry).toEqual('test.js');
230+
expect(res.opts.entry).toEqual(['test.js']);
214231
expect(res.opts.hot).toBeTruthy();
215232
expect(res.opts.output).toEqual('./dist/');
216233
expect(warnMock.mock.calls.length).toEqual(0);

packages/webpack-cli/lib/bootstrap.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,21 @@ async function runCLI(cli, commandIsUsed) {
4949
// if the unknown arg starts with a '-', it will be considered
5050
// an unknown flag rather than an entry
5151
let entry;
52-
if (parsedArgs.unknownArgs.length === 1 && !parsedArgs.unknownArgs[0].startsWith('-')) {
53-
entry = parsedArgs.unknownArgs[0];
54-
} else if (parsedArgs.unknownArgs.length > 0) {
55-
parsedArgs.unknownArgs
56-
.filter((e) => e)
57-
.forEach((unknown) => {
58-
logger.warn('Unknown argument:', unknown);
52+
if (parsedArgs.unknownArgs.length > 0 && !parsedArgs.unknownArgs[0].startsWith('-')) {
53+
if (parsedArgs.unknownArgs.length === 1) {
54+
entry = parsedArgs.unknownArgs[0];
55+
} else {
56+
entry = [];
57+
parsedArgs.unknownArgs.forEach((unknown) => {
58+
if (!unknown.startsWith('-')) {
59+
entry.push(unknown);
60+
}
5961
});
62+
}
63+
} else if (parsedArgs.unknownArgs.length > 0) {
64+
parsedArgs.unknownArgs.forEach((unknown) => {
65+
logger.warn('Unknown argument:', unknown);
66+
});
6067
cliExecuter();
6168
return;
6269
}

packages/webpack-cli/lib/groups/BasicGroup.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const GroupHelper = require('../utils/GroupHelper');
2+
const chalk = require('chalk');
23
const { core, groups } = require('../utils/cli-flags');
34

45
class BasicGroup extends GroupHelper {
@@ -35,6 +36,9 @@ class BasicGroup extends GroupHelper {
3536
}
3637
if (arg === 'entry') {
3738
options[arg] = this.resolveFilePath(args[arg], 'index.js');
39+
if (options[arg].length === 0) {
40+
process.stdout.write(chalk.red('\nError: you provided an invalid entry point.\n'));
41+
}
3842
}
3943
});
4044
if (outputOptions['dev']) {

packages/webpack-cli/lib/utils/arg-parser.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ function argParser(options, args, argsOnly = false, name = '', helpFunction = un
3939
const flags = option.alias ? `-${option.alias}, --${option.name}` : `--${option.name}`;
4040
const flagsWithType = option.type !== Boolean ? flags + ' <value>' : flags;
4141
if (option.type === Boolean || option.type === String) {
42-
parserInstance.option(flagsWithType, option.description, option.defaultValue);
42+
if (!option.multiple) {
43+
parserInstance.option(flagsWithType, option.description, option.defaultValue);
44+
} else {
45+
const multiArg = (value, previous = []) => previous.concat([value]);
46+
parserInstance.option(flagsWithType, option.description, multiArg, option.defaultValue);
47+
}
4348
} else {
4449
// in this case the type is a parsing function
4550
parserInstance.option(flagsWithType, option.description, option.type, option.defaultValue);

packages/webpack-cli/lib/utils/cli-flags.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ module.exports = {
7272
core: [
7373
{
7474
name: 'entry',
75-
usage: '--entry <path to entry file>',
75+
usage: '--entry <path to entry file> | --entry <path> --entry <path>',
7676
type: String,
77+
multiple: true,
7778
defaultOption: true,
7879
group: BASIC_GROUP,
79-
description: 'The entry point of your application e.g. ./src/main.js',
80+
description: 'The entry point(s) of your application e.g. ./src/main.js',
8081
link: 'https://webpack.js.org/concepts/#entry',
8182
},
8283
{

test/entry/flag-entry/entry-with-flag.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('entry flag', () => {
4141

4242
it('should throw error for invalid entry file', () => {
4343
const { stderr, stdout } = run(__dirname, ['--entry', './src/test.js']);
44-
expect(stderr).toBeFalsy();
45-
expect(stdout).toContain('not found');
44+
expect(stderr).toBeTruthy();
45+
expect(stdout).toContain('Error: you provided an invalid entry point.');
4646
});
4747
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const { run } = require('../../utils/test-utils');
4+
const { stat, readFile } = require('fs');
5+
const { resolve } = require('path');
6+
7+
describe(' multiple entries', () => {
8+
it('should allow multiple entry files', (done) => {
9+
const { stderr, stdout } = run(__dirname, ['./src/a.js', './src/b.js']);
10+
expect(stderr).toBeFalsy();
11+
expect(stdout).toBeTruthy();
12+
13+
stat(resolve(__dirname, './bin/main.js'), (err, stats) => {
14+
expect(err).toBe(null);
15+
expect(stats.isFile()).toBe(true);
16+
done();
17+
});
18+
readFile(resolve(__dirname, './bin/main.js'), 'utf-8', (err, data) => {
19+
expect(err).toBe(null);
20+
expect(data).toContain('Hello from a.js');
21+
expect(data).toContain('Hello from b.js');
22+
done();
23+
});
24+
});
25+
26+
it('should allow multiple entry flags', (done) => {
27+
const { stderr, stdout } = run(__dirname, ['--entry', 'src/a.js', '--entry', 'src/b.js']);
28+
expect(stderr).toBeFalsy();
29+
expect(stdout).toBeTruthy();
30+
31+
stat(resolve(__dirname, './bin/main.js'), (err, stats) => {
32+
expect(err).toBe(null);
33+
expect(stats.isFile()).toBe(true);
34+
done();
35+
});
36+
readFile(resolve(__dirname, './bin/main.js'), 'utf-8', (err, data) => {
37+
expect(err).toBe(null);
38+
expect(data).toContain('Hello from a.js');
39+
expect(data).toContain('Hello from b.js');
40+
done();
41+
});
42+
});
43+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('Hello from a.js');
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('Hello from b.js');

0 commit comments

Comments
 (0)