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

feat(webpack-cli): import flags from webpack core #1630

Merged
merged 21 commits into from Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion jest.config.js
@@ -1,5 +1,10 @@
const { cli } = require('webpack');

//ignore core-flags test for webpack@4
const ignorePattern = typeof cli !== 'undefined' ? ['<rootDir>/node_modules/'] : ['<rootDir>/node_modules/', '<rootDir>/test/core-flags'];

module.exports = {
testPathIgnorePatterns: ['<rootDir>/node_modules/'],
testPathIgnorePatterns: ignorePattern,
// transformIgnorePatterns: ['<rootDir>.*(node_modules)(?!.*webpack-cli.*).*$'],
testEnvironment: 'node',
collectCoverage: true,
Expand Down
614 changes: 610 additions & 4 deletions packages/webpack-cli/README.md

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion packages/webpack-cli/lib/bootstrap.js
Expand Up @@ -4,7 +4,6 @@ const logger = require('./utils/logger');
const cliExecuter = require('./utils/cli-executer');
const argParser = require('./utils/arg-parser');
require('./utils/process-log');

process.title = 'webpack-cli';

const isCommandUsed = (commands) =>
Expand Down
1 change: 0 additions & 1 deletion packages/webpack-cli/lib/utils/arg-parser.js
Expand Up @@ -99,7 +99,6 @@ function argParser(options, args, argsOnly = false, name = '', helpFunction = un
const opts = result.opts();

const unknownArgs = result.args;

args.forEach((arg) => {
const flagName = arg.slice(5);
const option = options.find((opt) => opt.name === flagName);
Expand Down
33 changes: 33 additions & 0 deletions packages/webpack-cli/lib/utils/cli-flags.js
@@ -1,3 +1,5 @@
const { cli } = require('webpack');

const HELP_GROUP = 'help';
const CONFIG_GROUP = 'config';
const BASIC_GROUP = 'basic';
Expand All @@ -6,6 +8,35 @@ const ADVANCED_GROUP = 'advanced';
const DISPLAY_GROUP = 'stats';
const ZERO_CONFIG_GROUP = 'zero-config';

// Extract all the flages being exported from core. A list of cli flags generated by core
jamesgeorge007 marked this conversation as resolved.
Show resolved Hide resolved
// can be found here https://github.com/webpack/webpack/blob/master/test/__snapshots__/Cli.test.js.snap
let flagsFromCore =
typeof cli !== 'undefined'
? Object.entries(cli.getArguments()).map(([flag, meta]) => {
if (meta.simpleType === 'string') {
meta.type = String;
meta.usage = `--${flag} <value>`;
} else if (meta.simpleType === 'number') {
meta.type = Number;
meta.usage = `--${flag} <value>`;
} else {
meta.type = Boolean;
meta.negative = true;
meta.usage = `--${flag}`;
}
return {
...meta,
name: flag,
group: 'core',
};
})
: [];

// duplicate flags
const duplicateFlags = ['entry', 'mode', 'stats', 'watch', 'target'];

flagsFromCore = flagsFromCore.filter((flag) => !duplicateFlags.includes(flag.name));

module.exports = {
groups: {
HELP_GROUP,
Expand Down Expand Up @@ -227,6 +258,7 @@ module.exports = {
group: CONFIG_GROUP,
description: 'Environment passed to the configuration when it is a function',
},
...flagsFromCore,
/* {
name: "analyze",
type: Boolean,
Expand All @@ -241,4 +273,5 @@ module.exports = {
group: BASIC_GROUP
} */
],
flagsFromCore: [...flagsFromCore],
snitin315 marked this conversation as resolved.
Show resolved Hide resolved
};
22 changes: 22 additions & 0 deletions packages/webpack-cli/lib/webpack-cli.js
Expand Up @@ -10,6 +10,7 @@ class WebpackCLI extends GroupHelper {
super();
this.groupMap = new Map();
this.groups = [];
this.args = {};
this.processingMessageBuffer = [];
this.compilation = new Compiler();
this.defaultEntry = 'index';
Expand Down Expand Up @@ -42,6 +43,26 @@ class WebpackCLI extends GroupHelper {
}
}

/**
* Responsible for handling flags coming from webpack/webpack
* @private\
* @returns {void}
*/
_handleCoreFlags() {
if (!this.groupMap.has('core')) {
return;
}
const coreFlags = this.groupMap.get('core');

// convert all the flags from map to single object
const coreConfig = coreFlags.reduce((allFlag, curFlag) => ({ ...allFlag, ...curFlag }), {});

const coreCliHelper = require('webpack').cli;
const coreCliArgs = coreCliHelper.getArguments();
// Merge the core flag config with the compilerConfiguration
coreCliHelper.processArguments(coreCliArgs, this.compilerConfiguration, coreConfig);
}

/**
* Expose commander argParser
* @param {...any} args args for argParser
Expand Down Expand Up @@ -222,6 +243,7 @@ class WebpackCLI extends GroupHelper {
.then(() => this._handleDefaultEntry())
.then(() => this._handleGroupHelper(this.configGroup))
.then(() => this._handleGroupHelper(this.outputGroup))
.then(() => this._handleCoreFlags())
.then(() => this._handleGroupHelper(this.basicGroup))
.then(() => this._handleGroupHelper(this.advancedGroup))
.then(() => this._handleGroupHelper(this.statsGroup))
Expand Down
2 changes: 1 addition & 1 deletion scripts/cleanupTest.js
Expand Up @@ -3,7 +3,7 @@ const rimraf = require('rimraf');
const { join } = require('path');
const collectTestFolders = require('./utils');

const outputDirectories = ['bin', 'binary', 'dist', 'test-assets', 'test-plugin', 'test-loader'];
const outputDirectories = ['bin', 'binary', 'dist', 'test', 'test-assets', 'test-plugin', 'test-loader'];

function folderStrategy(stats, file) {
return stats.isDirectory() && outputDirectories.includes(file);
Expand Down
12 changes: 12 additions & 0 deletions test/core-flags/amd-flag.test.js
@@ -0,0 +1,12 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('--no-amd flag', () => {
it('should accept --no-amd', () => {
const { stderr, stdout } = run(__dirname, ['--no-amd']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('amd: false');
});
});
19 changes: 19 additions & 0 deletions test/core-flags/bail-flag.test.js
@@ -0,0 +1,19 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('--bail flag', () => {
it('should set bail to true', () => {
const { stderr, stdout } = run(__dirname, ['--bail']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('bail: true');
});

it('should set bail to false', () => {
const { stderr, stdout } = run(__dirname, ['--no-bail']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('bail: false');
});
});
82 changes: 82 additions & 0 deletions test/core-flags/cache-flags.test.js
@@ -0,0 +1,82 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('cache related flags from core', () => {
it('should be successful with --cache ', () => {
const { stderr, stdout } = run(__dirname, ['--cache']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`type: 'memory'`);
});

it('should be successful with --no-cache ', () => {
const { stderr, stdout } = run(__dirname, ['--no-cache']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('cache: false');
});

it('should set cache.type', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`type: 'filesystem'`);
});

it('should set cache.cacheDirectory with --cache-cache-directory', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '--cache-cache-directory', '/test-cache-path']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('test-cache-path');
});

it('should set cache.cacheLocation with --cache-cache-locations', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '--cache-cache-location', '/test-locate-cache']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('test-locate-cache');
});

it('should set cache.hashAlgorithm with --cache-hash-algorithm', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '--cache-hash-algorithm', 'sha256']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`hashAlgorithm: 'sha256'`);
});

it('should set cache.managedPaths with --cache-managed-paths', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'memory', '--cache-managed-paths', '/test-manage-path']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('test-manage-path');
});

it('should reset cache.managedPaths with --cache-managed-paths-reset', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '--cache-managed-paths-reset']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`managedPaths: []`);
});

it('should set cache.name with --cache-name', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '--cache-name', 'cli-test']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`name: 'cli-test'`);
});

it('should set cache.store with --cache-store', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '--cache-store', 'pack']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`store: 'pack'`);
});

it('should set cache.version with --cache-version', () => {
const { stderr, stdout } = run(__dirname, ['--cache-type', 'filesystem', '--cache-version', '1.1.3']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`version: '1.1.3'`);
});
});
12 changes: 12 additions & 0 deletions test/core-flags/context-flag.test.js
@@ -0,0 +1,12 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('--context flag', () => {
it('should allow to set context', () => {
const { stderr, stdout } = run(__dirname, ['--context', '/test-context-path']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('test-context-path');
});
});
19 changes: 19 additions & 0 deletions test/core-flags/dependencies-flag.test.js
@@ -0,0 +1,19 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('--dependencies and related flags', () => {
it('should allow to set dependencies option', () => {
const { stderr, stdout } = run(__dirname, ['--dependencies', 'lodash']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`dependencies: [ 'lodash' ]`);
});

it('should reset dependencies option', () => {
const { stderr, stdout } = run(__dirname, ['--dependencies-reset']);

expect(stderr).toBeFalsy();
expect(stdout).toContain('dependencies: []');
});
});
18 changes: 18 additions & 0 deletions test/core-flags/devtool-flag.test.js
@@ -0,0 +1,18 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('--devtool flag', () => {
it('should set devtool option', () => {
const { stderr, stdout } = run(__dirname, ['--devtool', 'source-map']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`devtool: 'source-map'`);
});

it('should throw error for invalid config', () => {
const { stderr } = run(__dirname, ['--devtool', 'invalid']);

expect(stderr).toContain('ValidationError: Invalid configuration object');
});
});
26 changes: 26 additions & 0 deletions test/core-flags/experiments-flag.test.js
@@ -0,0 +1,26 @@
'use strict';

const { run, hyphenToUpperCase } = require('../utils/test-utils');
const { flagsFromCore } = require('../../packages/webpack-cli/lib/utils/cli-flags');

const experimentsFlags = flagsFromCore.filter(({ name }) => name.startsWith('experiments-'));

describe('experiments option related flag', () => {
experimentsFlags.forEach((flag) => {
// extract property name from flag name
const property = flag.name.split('experiments-')[1];
const propName = hyphenToUpperCase(property);

it(`should config ${flag.name} correctly`, () => {
const { stderr, stdout } = run(__dirname, [`--${flag.name}`]);
expect(stderr).toBeFalsy();
expect(stdout).toContain(`${propName}: true`);
});

it(`should config --no-${flag.name} correctly`, () => {
const { stderr, stdout } = run(__dirname, [`--no-${flag.name}`]);
expect(stderr).toBeFalsy();
expect(stdout).toContain(`${propName}: false`);
});
});
});
33 changes: 33 additions & 0 deletions test/core-flags/externals-flags.test.js
@@ -0,0 +1,33 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('externals related flag', () => {
it('should set externals properly', () => {
const { stderr, stdout } = run(__dirname, ['--externals', './main.js']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`externals: [ './main.js' ]`);
});

it('should set externalsType properly', () => {
const { stderr, stdout } = run(__dirname, ['--externals', 'var']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`externalsType: 'var'`);
});

it('should accept --external-type values', () => {
const { stderr, stdout } = run(__dirname, ['--externals-type', 'var']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`externalsType: 'var'`);
});

it('should reset externals', () => {
const { stderr, stdout } = run(__dirname, ['--externals-reset']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`externals: []`);
});
});
26 changes: 26 additions & 0 deletions test/core-flags/infrastructure-logging.test.js
@@ -0,0 +1,26 @@
'use strict';

const { run } = require('../utils/test-utils');

describe('externals related flag', () => {
it('should set infrastructureLogging.debug properly', () => {
const { stderr, stdout } = run(__dirname, ['--infrastructure-logging-debug', 'myPlugin']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`debug: [ 'myPlugin' ]`);
});

it('should reset infrastructureLogging.debug to []', () => {
const { stderr, stdout } = run(__dirname, ['--infrastructure-logging-debug-reset']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`debug: []`);
});

it('should set infrastructureLogging.level properly', () => {
const { stderr, stdout } = run(__dirname, ['--infrastructure-logging-level', 'log']);

expect(stderr).toBeFalsy();
expect(stdout).toContain(`level: 'log'`);
});
});
1 change: 1 addition & 0 deletions test/core-flags/main.js
@@ -0,0 +1 @@
console.log('core-flags tests');