Skip to content

Commit

Permalink
Merge branch 'next' into rechoir-default
Browse files Browse the repository at this point in the history
  • Loading branch information
anshumanv committed Aug 19, 2020
2 parents 1c6a342 + d3ed19a commit 76e2320
Show file tree
Hide file tree
Showing 43 changed files with 352 additions and 318 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [Utilities](#utilities)
- [Getting started](#getting-started)
- [webpack CLI Scaffolds](#webpack-cli-scaffolds)
- [Exit codes and their meanings](#exit-codes-and-their-meanings)
- [Contributing and Internal Documentation](#contributing-and-internal-documentation)
- [Open Collective](#open-collective)

Expand Down Expand Up @@ -96,6 +97,14 @@ With v3 of webpack CLI, we introduced scaffolding as an integral part of the CLI

You can read more about [Scaffolding](https://webpack.js.org/guides/scaffolding), learn [How to compose a webpack-scaffold?](https://webpack.js.org/contribute/writing-a-scaffold) or generate one with [webpack-scaffold-starter](https://github.com/rishabh3112/webpack-scaffold-starter).

## Exit codes and their meanings

| Exit Code | Description |
| --------- | -------------------------------------------------- |
| `0` | Success |
| `1` | Warnings/Errors from webpack |
| `2` | Configuration/options problem or an internal error |

## Contributing and Internal Documentation

The webpack family welcomes any contributor, small or big. We are happy to elaborate, guide you through the source code and find issues you might want to work on! To get started have a look at our [documentation on contributing](./.github/CONTRIBUTING.md).
Expand Down
2 changes: 1 addition & 1 deletion packages/package-utils/__tests__/packageUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ describe('packageUtils', () => {
// runCommand should not be called, because the installation is not confirmed
expect((runCommand as jest.Mock).mock.calls.length).toEqual(0);
expect((prompt as jest.Mock).mock.calls[0][0][0].message).toMatch(/Would you like to install test-package\?/);
expect(process.exitCode).toEqual(-1);
expect(process.exitCode).toEqual(2);
});
});
});
2 changes: 1 addition & 1 deletion packages/package-utils/src/packageUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,5 @@ export async function promptInstallation(packageName: string, preMessage?: Funct
return exports.packageExists(packageName);
}
// eslint-disable-next-line require-atomic-updates
process.exitCode = -1;
process.exitCode = 2;
}
8 changes: 6 additions & 2 deletions packages/serve/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@
"webpack-dev-server": "3.10.3"
},
"peerDependencies": {
"webpack-cli": "4.x.x",
"webpack-dev-server": "3.x.x || 4.x.x"
"webpack-cli": "4.x.x"
},
"peerDependenciesMeta": {
"webpack-dev-server": {
"optional": true
}
},
"gitHead": "fb50f766851f500ca12867a2aa9de81fa6e368f9"
}
9 changes: 7 additions & 2 deletions packages/serve/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { devServer } from 'webpack-dev-server/bin/cli-flags';
import WebpackCLI from 'webpack-cli';
import logger from 'webpack-cli/lib/utils/logger';
import startDevServer from './startDevServer';
Expand All @@ -11,10 +10,16 @@ import startDevServer from './startDevServer';
* @returns {Function} invokes the devServer API
*/
export default function serve(...args: string[]): void {
let devServerFlags: object[];
try {
devServerFlags = require('webpack-dev-server/bin/cli-flags').devServer;
} catch (err) {
throw new Error(`You need to install 'webpack-dev-server' for running 'webpack serve'.\n${err}`);
}
const cli = new WebpackCLI();
const core = cli.getCoreFlags();

const parsedDevServerArgs = cli.argParser(devServer, args, true);
const parsedDevServerArgs = cli.argParser(devServerFlags, args, true);
const devServerArgs = parsedDevServerArgs.opts;
const parsedWebpackArgs = cli.argParser(core, parsedDevServerArgs.unknownArgs, true, process.title);
const webpackArgs = parsedWebpackArgs.opts;
Expand Down
4 changes: 2 additions & 2 deletions packages/serve/src/startDevServer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import Server from 'webpack-dev-server/lib/Server';

/**
*
* Starts the devServer
Expand All @@ -10,6 +8,8 @@ import Server from 'webpack-dev-server/lib/Server';
* @returns {Void}
*/
export default function startDevServer(compiler, options): void {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Server = require('webpack-dev-server/lib/Server');
const firstWpOpt = compiler.compilers ? compiler.compilers[0].options : compiler.options;
const devServerOptions = firstWpOpt.devServer || {};

Expand Down
6 changes: 3 additions & 3 deletions packages/utils/src/modify-config-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function modifyHelperUtil(
} catch (err) {
console.error(red('\nYour package.json was incorrectly formatted.\n'));
Error.stackTraceLimit = 0;
process.exitCode = -1;
process.exitCode = 2;
}

env.registerStub(generator, generatorName);
Expand All @@ -108,7 +108,7 @@ export function modifyHelperUtil(
red("\nPlease make sure to use 'this.config.set('configuration', this.configuration);' at the end of the generator.\n"),
);
Error.stackTraceLimit = 0;
process.exitCode = -1;
process.exitCode = 2;
}
try {
// the configuration stored in .yo-rc.json should already be in the correct
Expand All @@ -126,7 +126,7 @@ export function modifyHelperUtil(
red('\nYour yeoman configuration file (.yo-rc.json) was incorrectly formatted. Deleting it may fix the problem.\n'),
);
Error.stackTraceLimit = 0;
process.exitCode = -1;
process.exitCode = 2;
}

const transformConfig = Object.assign(
Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/npm-packages-exists.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function npmPackagesExists(pkg: string[]): void {
.catch((err: Error): void => {
console.error(err.stack || err);
// eslint-disable-next-line no-process-exit
process.exit(0);
process.exit(2);
})
.then(resolvePackagesIfReady);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/webpack-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ yarn add webpack-cli --dev
```
--entry string[] The entry point(s) of your application.
-c, --config string Provide path to a webpack configuration file
--config-name string[] Name of the configuration to use
-m, --merge string Merge a configuration file using webpack-merge
--progress Print compilation progress during build
--color Enables colors on console
Expand All @@ -54,7 +55,6 @@ yarn add webpack-cli --dev
-j, --json Prints result as JSON
--mode string Defines the mode to pass to webpack
-v, --version Get current version
--node-args string[] NodeJS flags
--stats string It instructs webpack on how to treat the stats
--no-stats Disables stats output
```
Expand Down
8 changes: 0 additions & 8 deletions packages/webpack-cli/__tests__/ZeroConfigGroup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,4 @@ describe('ZeroConfigGroup', function () {
expect(result.options).toMatchObject({ mode: 'none' });
expect(result.options.mode).toEqual('none');
});

it('should set mode=production by default', () => {
const group = new ZeroConfigGroup([{}]);

const result = group.run();
// ensure no other properties are added
expect(result.options).toMatchObject({ mode: 'production' });
});
});
12 changes: 6 additions & 6 deletions packages/webpack-cli/__tests__/cli-executer.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
jest.mock('../lib/runner');
jest.mock('../lib/bootstrap');
jest.mock('enquirer');

const runner = require('../lib/runner');
runner.mockImplementation(() => {});
const runCLI = require('../lib/bootstrap');
runCLI.mockImplementation(() => {});

describe('CLI Executer', () => {
let cliExecuter = null;
Expand Down Expand Up @@ -47,9 +47,9 @@ describe('CLI Executer', () => {
it('runs enquirer options then runs webpack', async () => {
await cliExecuter();

// ensure that the webpack runner is called
expect(runner.mock.calls.length).toEqual(1);
expect(runner.mock.calls[0]).toEqual([[], ['--config', 'test1', '--entry', 'test2', '--progress']]);
// ensure that the webpack runCLI is called
expect(runCLI.mock.calls.length).toEqual(1);
expect(runCLI.mock.calls[0][0]).toEqual(['--config', 'test1', '--entry', 'test2', '--progress']);

// check that webpack options are actually being displayed that
// the user can select from
Expand Down
1 change: 1 addition & 0 deletions packages/webpack-cli/__tests__/serve/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('hello world');
27 changes: 27 additions & 0 deletions packages/webpack-cli/__tests__/serve/serve.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const { runServe } = require('../../../../test/utils/test-utils');

describe('Serve', () => {
const isWindows = process.platform === 'win32';

// TODO fix me on windows
if (isWindows) {
it('TODO: Fix on windows', () => {
expect(true).toBe(true);
});
return;
}

it('should run with cli', async () => {
const { stdout, stderr } = await runServe([], __dirname);
expect(stdout).toContain('main.js');
expect(stdout).not.toContain('hot/dev-server.js');
expect(stderr).toHaveLength(0);
});

it('should work with flags', async () => {
const { stdout, stderr } = await runServe(['--hot'], __dirname);
expect(stdout).toContain('main.js');
expect(stdout).toContain('hot/dev-server.js');
expect(stderr).toHaveLength(0);
});
});
4 changes: 4 additions & 0 deletions packages/webpack-cli/__tests__/serve/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
mode: 'development',
devtool: false,
};
6 changes: 2 additions & 4 deletions packages/webpack-cli/bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
'use strict';
require('v8-compile-cache');
const importLocal = require('import-local');
const parseNodeArgs = require('../lib/utils/parse-node-args');
const runner = require('../lib/runner');
const runCLI = require('../lib/bootstrap');

// Prefer the local installation of webpack-cli
if (importLocal(__filename)) {
Expand All @@ -13,6 +12,5 @@ if (importLocal(__filename)) {
process.title = 'webpack';

const [, , ...rawArgs] = process.argv;
const { cliArgs, nodeArgs } = parseNodeArgs(rawArgs);

runner(nodeArgs, cliArgs);
runCLI(rawArgs);
31 changes: 17 additions & 14 deletions packages/webpack-cli/lib/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@ const argParser = require('./utils/arg-parser');
require('./utils/process-log');
process.title = 'webpack-cli';

const isCommandUsed = (commands) =>
// Create a new instance of the CLI object
const cli = new WebpackCLI();

const isCommandUsed = (args) =>
commands.find((cmd) => {
return process.argv.includes(cmd.name) || process.argv.includes(cmd.alias);
return args.includes(cmd.name) || args.includes(cmd.alias);
});

async function runCLI(cli, commandIsUsed) {
async function runCLI(cliArgs) {
let args;

const commandIsUsed = isCommandUsed(cliArgs);
const runVersion = () => {
cli.runVersion(process.argv, commandIsUsed);
cli.runVersion(cliArgs, commandIsUsed);
};
const parsedArgs = argParser(core, process.argv, false, process.title, cli.runHelp, runVersion, commands);
const parsedArgs = argParser(core, cliArgs, true, process.title, cli.runHelp, runVersion, commands);

if (parsedArgs.unknownArgs.includes('help')) {
cli.runHelp(process.argv);
cli.runHelp(cliArgs);
process.exit(0);
}

Expand Down Expand Up @@ -55,7 +60,7 @@ async function runCLI(cli, commandIsUsed) {
parsedArgs.unknownArgs.forEach((unknown) => {
logger.warn(`Unknown argument: ${unknown}`);
});
cliExecuter();
await cliExecuter();
return;
}
const parsedArgsOpts = parsedArgs.opts;
Expand All @@ -77,10 +82,10 @@ async function runCLI(cli, commandIsUsed) {
} else if (err.name === 'ALREADY_SET') {
const argsMap = {};
const keysToDelete = [];
process.argv.forEach((arg, idx) => {
cliArgs.forEach((arg, idx) => {
const oldMapValue = argsMap[arg];
argsMap[arg] = {
value: process.argv[idx],
value: cliArgs[idx],
pos: idx,
};
// Swap idx of overridden value
Expand All @@ -92,8 +97,8 @@ async function runCLI(cli, commandIsUsed) {
// Filter out the value for the overridden key
const newArgKeys = Object.keys(argsMap).filter((arg) => !keysToDelete.includes(argsMap[arg].pos));
// eslint-disable-next-line require-atomic-updates
process.argv = newArgKeys;
args = argParser('', core, process.argv);
cliArgs = newArgKeys;
args = argParser('', core, cliArgs);
await cli.run(args.opts, core);
process.stdout.write('\n');
logger.warn('Duplicate flags found, defaulting to last set value');
Expand All @@ -104,6 +109,4 @@ async function runCLI(cli, commandIsUsed) {
}
}

const commandIsUsed = isCommandUsed(commands);
const cli = new WebpackCLI();
runCLI(cli, commandIsUsed);
module.exports = runCLI;
11 changes: 11 additions & 0 deletions packages/webpack-cli/lib/groups/ConfigGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const { extensions, jsVariants } = require('interpret');
const GroupHelper = require('../utils/GroupHelper');
const rechoir = require('rechoir');
const MergeError = require('../utils/errors/MergeError');
const logger = require('../utils/logger');

// Order defines the priority, in increasing order
// example - config file lookup will be in order of .webpack/webpack.config.development.js -> webpack.config.development.js -> webpack.config.js
Expand Down Expand Up @@ -108,6 +109,16 @@ class ConfigGroup extends GroupHelper {
const newOptions = configOptions(formattedEnv, argv);
// When config function returns a promise, resolve it, if not it's resolved by default
newOptionsObject['options'] = await Promise.resolve(newOptions);
} else if (Array.isArray(configOptions) && this.args.configName) {
// In case of exporting multiple configurations, If you pass a name to --config-name flag,
// webpack will only build that specific configuration.
const namedOptions = configOptions.filter((opt) => this.args.configName.includes(opt.name));
if (namedOptions.length === 0) {
logger.error(`Configuration with name "${this.args.configName}" was not found.`);
process.exit(2);
} else {
newOptionsObject['options'] = namedOptions;
}
} else {
if (Array.isArray(configOptions) && !configOptions.length) {
newOptionsObject['options'] = {};
Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-cli/lib/groups/HelpGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ class HelpGroup {
}
} catch (e) {
logger.error('Error: External package not found.');
process.exitCode = 1;
process.exit(2);
}
}

if (commandsUsed.length > 1) {
logger.error('You provided multiple commands. Please use only one command at a time.\n');
process.exit(1);
process.exit(2);
}

if (invalidArgs.length > 0) {
Expand Down
7 changes: 0 additions & 7 deletions packages/webpack-cli/lib/groups/ZeroConfigGroup.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
const GroupHelper = require('../utils/GroupHelper');
const logger = require('../utils/logger');

const PRODUCTION = 'production';
const DEVELOPMENT = 'development';
const NONE = 'none';
/**
* ZeroConfigGroup creates a zero configuration based on the environment
*/
Expand All @@ -21,13 +19,8 @@ class ZeroConfigGroup extends GroupHelper {
return process.env.NODE_ENV;
} else {
if (this.args.mode) {
if (this.args.mode !== PRODUCTION && this.args.mode !== DEVELOPMENT && this.args.mode !== NONE) {
logger.warn('You provided an invalid value for "mode" option. Using "production" by default');
return PRODUCTION;
}
return this.args.mode;
}
return PRODUCTION;
}
}

Expand Down
10 changes: 0 additions & 10 deletions packages/webpack-cli/lib/runner.js

This file was deleted.

Loading

0 comments on commit 76e2320

Please sign in to comment.