diff --git a/packages/webpack-cli/lib/groups/ConfigGroup.js b/packages/webpack-cli/lib/groups/ConfigGroup.js index dbeb549fcb7..af9ea8672e5 100644 --- a/packages/webpack-cli/lib/groups/ConfigGroup.js +++ b/packages/webpack-cli/lib/groups/ConfigGroup.js @@ -86,7 +86,7 @@ class ConfigGroup extends GroupHelper { }; } - finalize(moduleObj) { + async finalize(moduleObj) { const newOptionsObject = { outputOptions: {}, options: {}, @@ -100,7 +100,8 @@ class ConfigGroup extends GroupHelper { if (typeof configOptions === 'function') { // when config is a function, pass the env from args to the config function const newOptions = configOptions(this.args.env); - newOptionsObject['options'] = newOptions; + // 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) && !configOptions.length) { newOptionsObject['options'] = {}; @@ -124,7 +125,7 @@ class ConfigGroup extends GroupHelper { return newOptionsObject; } - resolveConfigFiles() { + async resolveConfigFiles() { const { config, mode } = this.args; if (config) { @@ -139,7 +140,7 @@ class ConfigGroup extends GroupHelper { } const foundConfig = configFiles[0]; const resolvedConfig = this.requireConfig(foundConfig); - this.opts = this.finalize(resolvedConfig); + this.opts = await this.finalize(resolvedConfig); return; } @@ -152,16 +153,16 @@ class ConfigGroup extends GroupHelper { if (configFiles.length) { const defaultConfig = configFiles.find((p) => p.path.includes(mode) || p.path.includes(modeAlias[mode])); if (defaultConfig) { - this.opts = this.finalize(defaultConfig); + this.opts = await this.finalize(defaultConfig); return; } const foundConfig = configFiles.pop(); - this.opts = this.finalize(foundConfig); + this.opts = await this.finalize(foundConfig); return; } } - resolveConfigMerging() { + async resolveConfigMerging() { // eslint-disable-next-line no-prototype-builtins if (Object.keys(this.args).some((arg) => arg === 'merge')) { const { merge } = this.args; @@ -178,16 +179,16 @@ class ConfigGroup extends GroupHelper { } const foundConfig = configFiles[0]; const resolvedConfig = this.requireConfig(foundConfig); - const newConfigurationsObject = this.finalize(resolvedConfig); + const newConfigurationsObject = await this.finalize(resolvedConfig); const webpackMerge = require('webpack-merge'); this.opts['options'] = webpackMerge(this.opts['options'], newConfigurationsObject.options); } } } - run() { - this.resolveConfigFiles(); - this.resolveConfigMerging(); + async run() { + await this.resolveConfigFiles(); + await this.resolveConfigMerging(); return this.opts; } } diff --git a/packages/webpack-cli/lib/webpack-cli.js b/packages/webpack-cli/lib/webpack-cli.js index 01ba4e762c4..416e3426b44 100644 --- a/packages/webpack-cli/lib/webpack-cli.js +++ b/packages/webpack-cli/lib/webpack-cli.js @@ -185,9 +185,9 @@ class WebpackCLI extends GroupHelper { * @private * @returns {void} */ - _handleGroupHelper(groupHelper) { + async _handleGroupHelper(groupHelper) { if (groupHelper) { - const result = groupHelper.run(); + const result = await groupHelper.run(); this._mergeOptionsToConfiguration(result.options, groupHelper.strategy); this._mergeOptionsToOutputConfiguration(result.outputOptions); this._mergeProcessingMessageBuffer(result.processingMessageBuffer); diff --git a/test/config/type/promise/promise-config.test.js b/test/config/type/promise/promise-config.test.js index 642d9eef0ee..061bdc92785 100644 --- a/test/config/type/promise/promise-config.test.js +++ b/test/config/type/promise/promise-config.test.js @@ -1,18 +1,13 @@ 'use strict'; const { stat } = require('fs'); -const { resolve, sep } = require('path'); -const { run, extractSummary } = require('../../../utils/test-utils'); +const { resolve } = require('path'); +const { run } = require('../../../utils/test-utils'); describe('promise configuration', () => { - it.skip('is able to understand a configuration file as a promise', (done) => { - const { stdout } = run(__dirname, ['-c', resolve(__dirname, 'webpack.config.js')], false); - const summary = extractSummary(stdout); - const outputDir = 'type/promise/binary'; - const outDirectoryFromCompiler = summary['Output Directory'].split(sep); - const outDirToMatch = outDirectoryFromCompiler - .slice(outDirectoryFromCompiler.length - 3, outDirectoryFromCompiler.length) - .join('/'); - expect(outDirToMatch).toContain(outputDir); + it('is able to understand a configuration file as a promise', (done) => { + const { stdout, stderr } = run(__dirname, ['-c', './webpack.config.js'], false); + expect(stdout).toBeTruthy(); + expect(stderr).toBeFalsy(); stat(resolve(__dirname, './binary/promise.js'), (err, stats) => { expect(err).toBe(null); expect(stats.isFile()).toBe(true);