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

fix: --config-name behaviour for fuctional configs #2006

Merged
merged 9 commits into from Nov 3, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
@@ -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')],
});
Expand All @@ -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];
Expand All @@ -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();
Expand All @@ -57,7 +57,7 @@ describe('ConfigGroup', function () {
});

it('should handle different env formats', async () => {
const result = await ConfigGroup({
const result = await resolveConfig({
env: { test: true, name: 'Hisoka' },
config: [resolve(__dirname, './env.webpack.config.cjs')],
});
Expand Down
Expand Up @@ -156,7 +156,9 @@ const finalize = async (moduleObj, args) => {
const isMultiCompilerMode = Array.isArray(config);
const rawConfigs = isMultiCompilerMode ? config : [config];

let configs = await Promise.all(
let configs = [];

const allConfigs = await Promise.all(
rawConfigs.map(async (rawConfig) => {
const isPromise = typeof rawConfig.then === 'function';

Expand All @@ -174,6 +176,14 @@ const finalize = async (moduleObj, args) => {
}),
);

for (const singleConfig of allConfigs) {
if (Array.isArray(singleConfig)) {
configs.push(...singleConfig);
} else {
configs.push(singleConfig);
}
}

if (configName) {
const foundConfigNames = [];

Expand Down Expand Up @@ -204,7 +214,7 @@ const finalize = async (moduleObj, args) => {
process.exit(2);
}

newOptionsObject['options'] = isMultiCompilerMode ? configs : configs[0];
newOptionsObject['options'] = configs.length > 1 ? configs : configs[0];

return newOptionsObject;
};
Expand Down
2 changes: 1 addition & 1 deletion packages/webpack-cli/lib/webpack-cli.js
Expand Up @@ -11,7 +11,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');
Expand Down
47 changes: 47 additions & 0 deletions test/config-name/config-name.test.js
Expand Up @@ -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);
});
});
26 changes: 26 additions & 0 deletions test/config-name/function-config.js
@@ -0,0 +1,26 @@
module.exports = () => [
{
output: {
filename: './dist-first.js',
},
name: 'first',
entry: './src/first.js',
mode: 'development',
},
{
output: {
filename: './dist-second.js',
},
name: 'second',
entry: './src/second.js',
mode: 'production',
},
{
output: {
filename: './dist-third.js',
},
name: 'third',
entry: './src/third.js',
mode: 'none',
},
];
2 changes: 0 additions & 2 deletions test/config-name/webpack.config.js
Expand Up @@ -6,7 +6,6 @@ module.exports = [
name: 'first',
entry: './src/first.js',
mode: 'development',
stats: 'minimal',
},
{
output: {
Expand All @@ -15,7 +14,6 @@ module.exports = [
name: 'second',
entry: './src/second.js',
mode: 'production',
stats: 'minimal',
},
{
output: {
Expand Down
40 changes: 40 additions & 0 deletions test/config/function/functional-config.test.js
@@ -0,0 +1,40 @@
'use strict';
const { resolve } = require('path');
const { stat } = require('fs');
const { run } = require('../../utils/test-utils');

describe('functional config', () => {
it('should work as expected in case of single config', (done) => {
const { stderr, stdout, exitCode } = run(__dirname, ['--config', resolve(__dirname, 'single-webpack.config.js')]);

expect(stderr).toBeFalsy();
expect(stdout).toContain('./src/index.js');
expect(exitCode).toBe(0);

stat(resolve(__dirname, './bin/dist-single.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
done();
});
});

it('should work as expected in case of multiple config', (done) => {
const { stderr, stdout, exitCode } = run(__dirname, ['--config', resolve(__dirname, 'multi-webpack.config.js')]);

expect(stderr).toBeFalsy();
expect(stdout).toContain('first');
expect(stdout).toContain('second');
expect(exitCode).toBe(0);

stat(resolve(__dirname, './bin/dist-first.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
done();
});
stat(resolve(__dirname, './bin/dist-second.js'), (err, stats) => {
expect(err).toBe(null);
expect(stats.isFile()).toBe(true);
done();
});
});
});
20 changes: 20 additions & 0 deletions test/config/function/multi-webpack.config.js
@@ -0,0 +1,20 @@
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',
},
];
9 changes: 9 additions & 0 deletions test/config/function/single-webpack.config.js
@@ -0,0 +1,9 @@
module.exports = () => {
return {
output: {
filename: './dist-single.js',
},
name: 'single',
mode: 'development',
};
};
1 change: 1 addition & 0 deletions test/config/function/src/first.js
@@ -0,0 +1 @@
console.log('first entry');
1 change: 1 addition & 0 deletions test/config/function/src/index.js
@@ -0,0 +1 @@
console.log('default index');
1 change: 1 addition & 0 deletions test/config/function/src/second.js
@@ -0,0 +1 @@
console.log('second entry');