From 6284a55fb7b895d1e67efbceef017d1009d382a1 Mon Sep 17 00:00:00 2001 From: Nitin Kumar Date: Sat, 31 Oct 2020 11:08:31 +0530 Subject: [PATCH] fix: --config-name behaviour for fuctional configs --- ...figGroup.test.js => resolveConfig.test.js} | 14 +++--- .../{ConfigGroup.js => resolveConfig.js} | 8 +++- packages/webpack-cli/lib/webpack-cli.js | 2 +- test/config-name/config-name.test.js | 47 +++++++++++++++++++ test/config-name/function-config.js | 29 ++++++++++++ 5 files changed, 90 insertions(+), 10 deletions(-) rename packages/webpack-cli/__tests__/ConfigGroup/{ConfigGroup.test.js => resolveConfig.test.js} (81%) rename packages/webpack-cli/lib/groups/{ConfigGroup.js => resolveConfig.js} (95%) create mode 100644 test/config-name/function-config.js diff --git a/packages/webpack-cli/__tests__/ConfigGroup/ConfigGroup.test.js b/packages/webpack-cli/__tests__/ConfigGroup/resolveConfig.test.js similarity index 81% rename from packages/webpack-cli/__tests__/ConfigGroup/ConfigGroup.test.js rename to packages/webpack-cli/__tests__/ConfigGroup/resolveConfig.test.js index b724ed2b6d8..7262fd74eb2 100644 --- a/packages/webpack-cli/__tests__/ConfigGroup/ConfigGroup.test.js +++ b/packages/webpack-cli/__tests__/ConfigGroup/resolveConfig.test.js @@ -1,13 +1,13 @@ -const ConfigGroup = require('../../lib/groups/ConfigGroup'); +const resolveConfig = require('../../lib/groups/resolveConfig.js'); const { resolve } = require('path'); const config1 = require('./webpack.config1.cjs'); const config2 = require('./webpack.config2.cjs'); const arrayConfig = require('./webpack.config.cjs'); const promiseConfig = require('./webpack.promise.config.cjs'); -describe('ConfigGroup', function () { +describe('resolveConfig', function () { it('should handle merge properly', async () => { - const result = await ConfigGroup({ + const result = await resolveConfig({ merge: true, config: [resolve(__dirname, './webpack.config.cjs')], }); @@ -25,7 +25,7 @@ describe('ConfigGroup', function () { }); it('should return array for multiple config', async () => { - const result = await ConfigGroup({ + const result = await resolveConfig({ config: [resolve(__dirname, './webpack.config1.cjs'), resolve(__dirname, './webpack.config2.cjs')], }); const expectedOptions = [config1, config2]; @@ -34,20 +34,20 @@ describe('ConfigGroup', function () { }); it('should return config object for single config', async () => { - const result = await ConfigGroup({ config: [resolve(__dirname, './webpack.config1.cjs')] }); + const result = await resolveConfig({ config: [resolve(__dirname, './webpack.config1.cjs')] }); expect(result.options).toEqual(config1); expect(result.outputOptions).toEqual({}); }); it('should return resolved config object for promise config', async () => { - const result = await ConfigGroup({ config: [resolve(__dirname, './webpack.promise.config.cjs')] }); + const result = await resolveConfig({ config: [resolve(__dirname, './webpack.promise.config.cjs')] }); const expectedOptions = await promiseConfig(); expect(result.options).toEqual(expectedOptions); expect(result.outputOptions).toEqual({}); }); it('should handle configs returning different types', async () => { - const result = await ConfigGroup({ + const result = await resolveConfig({ config: [resolve(__dirname, './webpack.promise.config.cjs'), resolve(__dirname, './webpack.config.cjs')], }); const resolvedPromiseConfig = await promiseConfig(); diff --git a/packages/webpack-cli/lib/groups/ConfigGroup.js b/packages/webpack-cli/lib/groups/resolveConfig.js similarity index 95% rename from packages/webpack-cli/lib/groups/ConfigGroup.js rename to packages/webpack-cli/lib/groups/resolveConfig.js index beac89662e8..65689645775 100644 --- a/packages/webpack-cli/lib/groups/ConfigGroup.js +++ b/packages/webpack-cli/lib/groups/resolveConfig.js @@ -156,6 +156,8 @@ const finalize = async (moduleObj, args) => { const isMultiCompilerMode = Array.isArray(config); const rawConfigs = isMultiCompilerMode ? config : [config]; + let isFunctionalConfig = false; + let configs = await Promise.all( rawConfigs.map(async (rawConfig) => { const isPromise = typeof rawConfig.then === 'function'; @@ -166,6 +168,7 @@ const finalize = async (moduleObj, args) => { // `Promise` may return `Function` if (typeof rawConfig === 'function') { + isFunctionalConfig = true; // when config is a function, pass the env from args to the config function rawConfig = await rawConfig(env, args); } @@ -176,8 +179,9 @@ const finalize = async (moduleObj, args) => { if (configName) { const foundConfigNames = []; + const configsToFilter = isFunctionalConfig ? configs[0] : configs; - configs = configs.filter((options) => { + configs = configsToFilter.filter((options) => { const found = configName.includes(options.name); if (found) { @@ -204,7 +208,7 @@ const finalize = async (moduleObj, args) => { process.exit(2); } - newOptionsObject['options'] = isMultiCompilerMode ? configs : configs[0]; + newOptionsObject['options'] = isMultiCompilerMode || isFunctionalConfig ? configs : configs[0]; return newOptionsObject; }; diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index 9ae5c1ae010..9d7516dc2db 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -13,7 +13,7 @@ const { options: coloretteOptions } = require('colorette'); const WebpackCLIPlugin = require('./plugins/WebpackCLIPlugin'); // CLI arg resolvers -const handleConfigResolution = require('./groups/ConfigGroup'); +const handleConfigResolution = require('./groups/resolveConfig'); const resolveMode = require('./groups/resolveMode'); const resolveStats = require('./groups/resolveStats'); const resolveOutput = require('./groups/resolveOutput'); diff --git a/test/config-name/config-name.test.js b/test/config-name/config-name.test.js index de2fe509af4..deee81523b7 100644 --- a/test/config-name/config-name.test.js +++ b/test/config-name/config-name.test.js @@ -81,4 +81,51 @@ describe('--config-name flag', () => { expect(stdout).toBeFalsy(); expect(exitCode).toBe(2); }); + + it('should work with config as a function', (done) => { + const { stderr, stdout, exitCode } = run(__dirname, ['--config', 'function-config.js', '--config-name', 'first'], false); + expect(stderr).toBeFalsy(); + expect(stdout).toContain('first'); + expect(stdout).not.toContain('second'); + expect(stdout).not.toContain('third'); + expect(exitCode).toBe(0); + + stat(resolve(__dirname, './dist/dist-first.js'), (err, stats) => { + expect(err).toBe(null); + expect(stats.isFile()).toBe(true); + done(); + }); + }); + + it('should work with multiple values for --config-name when the config is a function', (done) => { + const { stderr, stdout, exitCode } = run( + __dirname, + ['--config', 'function-config.js', '--config-name', 'first', '--config-name', 'third'], + false, + ); + expect(stderr).toBeFalsy(); + expect(stdout).toContain('first'); + expect(stdout).not.toContain('second'); + expect(stdout).toContain('third'); + expect(exitCode).toBe(0); + + stat(resolve(__dirname, './dist/dist-third.js'), (err, stats) => { + expect(err).toBe(null); + expect(stats.isFile()).toBe(true); + + stat(resolve(__dirname, './dist/dist-first.js'), (err, stats) => { + expect(err).toBe(null); + expect(stats.isFile()).toBe(true); + done(); + }); + }); + }); + + it('should log error if invalid config name is provided ', () => { + const { stderr, stdout, exitCode } = run(__dirname, ['--config', 'function-config.js', '--config-name', 'test'], false); + + expect(stderr).toContain('Configuration with name "test" was not found.'); + expect(stdout).toBeFalsy(); + expect(exitCode).toBe(2); + }); }); diff --git a/test/config-name/function-config.js b/test/config-name/function-config.js new file mode 100644 index 00000000000..eeefbbf66bd --- /dev/null +++ b/test/config-name/function-config.js @@ -0,0 +1,29 @@ +module.exports = () => [ + { + output: { + filename: './dist-first.js', + }, + name: 'first', + entry: './src/first.js', + mode: 'development', + stats: 'minimal', + }, + { + output: { + filename: './dist-second.js', + }, + name: 'second', + entry: './src/second.js', + mode: 'production', + stats: 'minimal', + }, + { + output: { + filename: './dist-third.js', + }, + name: 'third', + entry: './src/third.js', + mode: 'none', + stats: 'minimal', + }, +];