Skip to content
This repository has been archived by the owner on May 15, 2024. It is now read-only.

Commit

Permalink
feat(extendWebpackConfig): added merge plugin feature (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
akcorp2003 authored Apr 27, 2021
1 parent ece0528 commit 3cdf5af
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
* or implied. See the License for the specific language governing permissions and limitations
* under the License.
*/
const webpack = require('webpack');
const HolocronModuleRegisterPlugin = require('holocron-module-register-webpack-plugin');

const extendWebpackConfig = require('../../utils/extendWebpackConfig');
const getConfigOptions = require('../../utils/getConfigOptions');
const getCliOptions = require('../../utils/getCliOptions');

const mockOverridingHolocronModuleRegisterPlugin = () => new HolocronModuleRegisterPlugin('my-new-holocron-module');
const mockOverridingWebpackDefinePlugin = () => new webpack.DefinePlugin({ 'global.BROWSER': JSON.stringify(true) });

jest.mock('read-pkg-up', () => ({
sync: jest.fn(() => ({ pkg: { name: 'test-module', version: '1.0.0' } })),
}));
Expand All @@ -34,6 +39,7 @@ jest.mock('/path/webpack.client.config.js', () => ({
{ test: /\.js$/, use: 'my-super-cool-client-loader' },
],
},
plugins: [mockOverridingHolocronModuleRegisterPlugin()],
}), { virtual: true });

jest.mock('/path/webpack.server.config.js', () => ({
Expand All @@ -42,6 +48,7 @@ jest.mock('/path/webpack.server.config.js', () => ({
{ test: /\.js$/, use: 'my-super-cool-server-loader' },
],
},
plugins: [mockOverridingWebpackDefinePlugin()],
}), { virtual: true });

jest.mock('../../utils/getConfigOptions', () => jest.fn(() => ({})));
Expand Down Expand Up @@ -72,6 +79,7 @@ describe('extendWebpackConfig', () => {
},
],
},
plugins: [new HolocronModuleRegisterPlugin('default-holocron-module')],
};
});

Expand All @@ -88,19 +96,68 @@ describe('extendWebpackConfig', () => {
it('should apply a client webpack config', () => {
getConfigOptions.mockReturnValueOnce({ webpackClientConfigPath: 'webpack.client.config.js' });
const result = extendWebpackConfig(originalWebpackConfig, 'client');
const { plugins } = result;
const { rules } = result.module;
const lastRule = rules[rules.length - 1];
expect(rules.length).toBe(originalWebpackConfig.module.rules.length + 1);
expect(lastRule.use).toBe('my-super-cool-client-loader');
expect(plugins.length).toBe(1);
expect(plugins[0].moduleName).toBe('my-new-holocron-module');
});

it('should apply a server webpack config', () => {
const serverWebpackConfig = {
...originalWebpackConfig,
plugins: [],
};
getConfigOptions.mockReturnValueOnce({ webpackServerConfigPath: 'webpack.server.config.js' });
const result = extendWebpackConfig(originalWebpackConfig, 'server');
const result = extendWebpackConfig(serverWebpackConfig, 'server');
const { plugins } = result;
const { rules } = result.module;
const lastRule = rules[rules.length - 1];
expect(rules.length).toBe(originalWebpackConfig.module.rules.length + 1);
expect(rules.length).toBe(serverWebpackConfig.module.rules.length + 1);
expect(lastRule.use).toBe('my-super-cool-server-loader');
expect(plugins.length).toBe(1);
expect(plugins[0].definitions).toEqual({
'global.BROWSER': 'true',
});
});

describe('merging plugins', () => {
it('should add a plugin if there is none in the original webpack configuration', () => {
const originalConfigWithNoPlugins = {
...originalWebpackConfig,
plugins: [],
};
getConfigOptions.mockReturnValueOnce({ webpackClientConfigPath: 'webpack.client.config.js' });
const result = extendWebpackConfig(originalConfigWithNoPlugins, 'client');
const { plugins } = result;
expect(plugins.length).toBe(1);
expect(plugins[0].moduleName).toBe('my-new-holocron-module');
});

it('should add a new plugin if the original webpack configuration does not have it', () => {
const originalConfigWithNoPlugins = {
...originalWebpackConfig,
plugins: [mockOverridingWebpackDefinePlugin()],
};
getConfigOptions.mockReturnValueOnce({ webpackClientConfigPath: 'webpack.client.config.js' });
const result = extendWebpackConfig(originalConfigWithNoPlugins, 'client');
const { plugins } = result;
expect(plugins.length).toBe(2);
expect(plugins[0].moduleName).toBe('my-new-holocron-module');
expect(plugins[1].definitions).toEqual({
'global.BROWSER': 'true',
});
});

it('should replace an existing plugin if the same name is in the original webpack configuration', () => {
getConfigOptions.mockReturnValueOnce({ webpackClientConfigPath: 'webpack.client.config.js' });
const result = extendWebpackConfig(originalWebpackConfig, 'client');
const { plugins } = result;
expect(plugins.length).toBe(1);
expect(plugins[0].moduleName).toBe('my-new-holocron-module');
});
});

it('should bundle requiredExternals designated by providedExternals', () => {
Expand Down
13 changes: 12 additions & 1 deletion packages/one-app-bundler/utils/extendWebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

const path = require('path');
const merge = require('webpack-merge');
const uniqBy = require('lodash/uniqBy');
const getConfigOptions = require('./getConfigOptions');
const getCliOptions = require('./getCliOptions');
const createResolver = require('../webpack/createResolver');
Expand Down Expand Up @@ -119,7 +120,17 @@ function extendWebpackConfig(webpackConfig, bundleTarget) {
});
}

return merge(webpackConfig, customWebpackConfig);
return merge({
customizeArray(defaultConfig, customConfig, key) {
if (key === 'plugins') {
const merged = [...customConfig, ...defaultConfig];
const unique = uniqBy(merged, (plugin) => plugin.constructor && plugin.constructor.name);
return unique;
}

return undefined;
},
})(webpackConfig, customWebpackConfig);
}

module.exports = extendWebpackConfig;

0 comments on commit 3cdf5af

Please sign in to comment.