Skip to content

Commit

Permalink
Merge branch 'next' into name-flag
Browse files Browse the repository at this point in the history
  • Loading branch information
anshumanv committed Aug 20, 2020
2 parents df08e4a + d8d5fff commit 6063fa8
Show file tree
Hide file tree
Showing 37 changed files with 296 additions and 95 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -52,3 +52,4 @@ packages/**/*.map

# temporary test files
test-assets/
./lib/
9 changes: 9 additions & 0 deletions README.md
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
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
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;
}
6 changes: 3 additions & 3 deletions packages/utils/src/modify-config-helper.ts
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
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
1 change: 1 addition & 0 deletions packages/webpack-cli/README.md
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 Down
10 changes: 5 additions & 5 deletions packages/webpack-cli/__tests__/cli-executer.test.js
@@ -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 @@ -48,8 +48,8 @@ describe('CLI Executer', () => {
await cliExecuter();

// ensure that the webpack runCLI is called
expect(runner.mock.calls.length).toEqual(1);
expect(runner.mock.calls[0]).toEqual([[], ['--config', 'test1', '--entry', 'test2', '--progress']]);
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
49 changes: 23 additions & 26 deletions packages/webpack-cli/lib/groups/ConfigGroup.js
@@ -1,10 +1,11 @@
const { existsSync } = require('fs');
const { resolve, sep, dirname, parse } = require('path');
const { resolve, sep, dirname, extname } = require('path');
const webpackMerge = require('webpack-merge');
const { extensions, jsVariants } = require('interpret');
const GroupHelper = require('../utils/GroupHelper');
const rechoir = require('rechoir');
const MergeError = require('../utils/errors/MergeError');
const ConfigError = require('../utils/errors/ConfigError');
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 @@ -41,25 +42,16 @@ const getDefaultConfigFiles = () => {
};

const getConfigInfoFromFileName = (filename) => {
const fileMetaData = parse(filename);
// .cjs is not available on interpret side, handle it manually for now
if (filename.endsWith('.cjs')) {
return [
{
path: resolve(filename),
ext: '.cjs',
module: null,
},
];
}
return Object.keys(extensions)
.filter((ext) => ext.includes(fileMetaData.ext))
.filter((ext) => fileMetaData.base.substr(fileMetaData.base.length - ext.length) === ext)
.map((ext) => {
const ext = extname(filename);
// since we support only one config for now
const allFiles = [filename];
// return all the file metadata
return allFiles
.map((file) => {
return {
path: resolve(filename),
path: resolve(file),
ext: ext,
module: extensions[ext],
module: extensions[ext] || null,
};
})
.filter((e) => existsSync(e.path));
Expand Down Expand Up @@ -97,7 +89,6 @@ class ConfigGroup extends GroupHelper {
const newOptionsObject = {
outputOptions: {},
options: {},
processingMessageBuffer: [],
};

if (!moduleObj) {
Expand All @@ -117,6 +108,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 Expand Up @@ -146,11 +147,7 @@ class ConfigGroup extends GroupHelper {
const configPath = resolve(process.cwd(), config);
const configFiles = getConfigInfoFromFileName(configPath);
if (!configFiles.length) {
this.opts.processingMessageBuffer.push({
lvl: 'warn',
msg: `Configuration ${config} not found in ${configPath}`,
});
return;
throw new ConfigError(`The specified config file doesn't exist in ${configPath}`);
}
const foundConfig = configFiles[0];
const resolvedConfig = this.requireConfig(foundConfig);
Expand Down Expand Up @@ -185,7 +182,7 @@ class ConfigGroup extends GroupHelper {
const newConfigPath = this.resolveFilePath(merge);

if (!newConfigPath) {
throw new MergeError("The supplied merge config doesn't exist.");
throw new ConfigError("The supplied merge config doesn't exist.", 'MergeError');
}

const configFiles = getConfigInfoFromFileName(newConfigPath);
Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-cli/lib/groups/HelpGroup.js
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
10 changes: 0 additions & 10 deletions packages/webpack-cli/lib/runner.js

This file was deleted.

26 changes: 13 additions & 13 deletions packages/webpack-cli/lib/utils/Compiler.js
Expand Up @@ -68,7 +68,7 @@ class Compiler {
}
}

compilerCallback(err, stats, lastHash, options, outputOptions, processingMessageBuffer) {
compilerCallback(err, stats, lastHash, options, outputOptions) {
const statsErrors = [];

if (!outputOptions.watch || err) {
Expand All @@ -80,6 +80,9 @@ class Compiler {
logger.error(err.stack || err);
process.exit(1); // eslint-disable-line
}
if (!outputOptions.watch && (stats.hasErrors() || stats.hasWarnings())) {
process.exitCode = 1;
}
if (outputOptions.json) {
process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + '\n');
} else if (stats.hash !== lastHash) {
Expand All @@ -91,26 +94,23 @@ class Compiler {
statsErrors.push({ name: statErr.message, loc: errLoc });
});
}
return this.generateOutput(outputOptions, stats, statsErrors, processingMessageBuffer);
}
if (!outputOptions.watch && stats.hasErrors()) {
process.exitCode = 2;
return this.generateOutput(outputOptions, stats, statsErrors);
}
}

async invokeCompilerInstance(lastHash, options, outputOptions, processingMessageBuffer) {
async invokeCompilerInstance(lastHash, options, outputOptions) {
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve) => {
await this.compiler.run((err, stats) => {
const content = this.compilerCallback(err, stats, lastHash, options, outputOptions, processingMessageBuffer);
const content = this.compilerCallback(err, stats, lastHash, options, outputOptions);
resolve(content);
});
});
}

async invokeWatchInstance(lastHash, options, outputOptions, watchOptions, processingMessageBuffer) {
async invokeWatchInstance(lastHash, options, outputOptions, watchOptions) {
return this.compiler.watch(watchOptions, (err, stats) => {
return this.compilerCallback(err, stats, lastHash, options, outputOptions, processingMessageBuffer);
return this.compilerCallback(err, stats, lastHash, options, outputOptions);
});
}

Expand All @@ -131,7 +131,7 @@ class Compiler {
}

async webpackInstance(opts) {
const { outputOptions, processingMessageBuffer, options } = opts;
const { outputOptions, options } = opts;
const lastHash = null;

const { ProgressPlugin } = webpack;
Expand All @@ -141,7 +141,7 @@ class Compiler {

if (outputOptions.interactive) {
const interactive = require('./interactive');
return interactive(options, outputOptions, processingMessageBuffer);
return interactive(options, outputOptions);
}

if (this.compiler.compilers) {
Expand All @@ -160,9 +160,9 @@ class Compiler {
});
process.stdin.resume();
}
await this.invokeWatchInstance(lastHash, options, outputOptions, watchOptions, processingMessageBuffer);
await this.invokeWatchInstance(lastHash, options, outputOptions, watchOptions);
} else {
return await this.invokeCompilerInstance(lastHash, options, outputOptions, processingMessageBuffer);
return await this.invokeCompilerInstance(lastHash, options, outputOptions);
}
}
}
Expand Down
1 change: 0 additions & 1 deletion packages/webpack-cli/lib/utils/GroupHelper.js
Expand Up @@ -7,7 +7,6 @@ class GroupHelper {
this.opts = {
outputOptions: {},
options: {},
processingMessageBuffer: [],
};
this.strategy = undefined;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/webpack-cli/lib/utils/cli-executer.js
Expand Up @@ -2,7 +2,7 @@ const { MultiSelect, Input } = require('enquirer');
const { cyan } = require('colorette');
const logger = require('./logger');
const cliArgs = require('./cli-flags').core;
const runner = require('../runner');
const runCLI = require('../bootstrap');

async function prompter() {
const args = [];
Expand Down Expand Up @@ -56,7 +56,7 @@ async function run() {
const args = await prompter();
process.stdout.write('\n');
logger.info('Executing CLI\n');
await runner([], args);
await runCLI(args);
} catch (err) {
logger.error(`Action Interrupted, use ${cyan('webpack-cli help')} to see possible options.`);
}
Expand Down
8 changes: 8 additions & 0 deletions packages/webpack-cli/lib/utils/cli-flags.js
Expand Up @@ -124,6 +124,14 @@ module.exports = {
description: 'Provide path to a webpack configuration file e.g. ./webpack.config.js',
link: 'https://webpack.js.org/configuration/',
},
{
name: 'config-name',
usage: '--config-name <name of config>',
type: String,
multiple: true,
group: CONFIG_GROUP,
description: 'Name of the configuration to use',
},
{
name: 'color',
usage: '--color',
Expand Down
11 changes: 11 additions & 0 deletions packages/webpack-cli/lib/utils/errors/ConfigError.js
@@ -0,0 +1,11 @@
class ConfigError extends Error {
constructor(message, name) {
super(message);
this.name = name || 'ConfigError';
// No need to show stack trace for known errors
this.stack = '';
process.exitCode = 2;
}
}

module.exports = ConfigError;
10 changes: 0 additions & 10 deletions packages/webpack-cli/lib/utils/errors/MergeError.js

This file was deleted.

0 comments on commit 6063fa8

Please sign in to comment.