feat: webpackChain options

Implement { last: true }
This commit is contained in:
Igor Randjelovic
2020-11-25 18:46:25 +01:00
parent d9a93040fe
commit 803958266d
2 changed files with 55 additions and 15 deletions

View File

@ -1,8 +1,11 @@
// @ts-ignore
import Config from 'webpack-chain';
import * as webpack from '../src';
describe('@nativescript/webpack', () => { describe('@nativescript/webpack', () => {
let webpack: typeof import('../src');
beforeEach(() => {
jest.resetModules();
webpack = require('../src');
});
it('exports the public api', () => { it('exports the public api', () => {
expect(webpack.init).toBeInstanceOf(Function); expect(webpack.init).toBeInstanceOf(Function);
expect(webpack.useConfig).toBeInstanceOf(Function); expect(webpack.useConfig).toBeInstanceOf(Function);
@ -27,7 +30,29 @@ describe('@nativescript/webpack', () => {
expect(chainFn).toHaveBeenCalledTimes(1); expect(chainFn).toHaveBeenCalledTimes(1);
expect(chainFn).toHaveBeenCalledWith(config, {}); expect(chainFn).toHaveBeenCalledWith(config, {});
expect(config).toBeInstanceOf(Config); });
it('applies chain configs in the right order', () => {
webpack.useConfig(false);
let lastCalled = false;
// this is registered before chainFnNormal
// however, should be called after chainFnNormal
const chainFnLast = jest.fn((config) => {
lastCalled = true;
expect(config.normal).toBe(true);
});
webpack.chainWebpack(chainFnLast, { last: true });
const chainFnNormal = jest.fn((config) => {
config.normal = true;
// chainFnLast should not have been called yet
expect(lastCalled).toBe(false);
});
webpack.chainWebpack(chainFnNormal);
webpack.resolveChainableConfig();
}); });
it('applies merge configs', () => { it('applies merge configs', () => {

View File

@ -30,7 +30,11 @@ export interface IWebpackEnv {
// todo: add others // todo: add others
} }
let webpackChains: any[] = []; let webpackChains = {
base: [],
normal: [],
last: [],
};
let webpackMerges: any[] = []; let webpackMerges: any[] = [];
let explicitUseConfig = false; let explicitUseConfig = false;
let hasInitialized = false; let hasInitialized = false;
@ -54,7 +58,7 @@ export function init(_env: IWebpackEnv) {
export function useConfig(config: keyof typeof defaultConfigs | false) { export function useConfig(config: keyof typeof defaultConfigs | false) {
explicitUseConfig = true; explicitUseConfig = true;
if (config) { if (config) {
webpackChains.unshift(configs[config]); webpackChains.base.push(configs[config]);
} }
} }
@ -62,8 +66,8 @@ export function chainWebpack(
chainFn: (config: Config, env: IWebpackEnv) => any, chainFn: (config: Config, env: IWebpackEnv) => any,
options?: { last?: boolean } options?: { last?: boolean }
) { ) {
// todo: handle options.last by storing them in a separate array? const type = options?.last ? 'last' : 'normal';
webpackChains.push(chainFn); webpackChains[type].push(chainFn);
} }
export function mergeWebpack( export function mergeWebpack(
@ -75,7 +79,7 @@ export function mergeWebpack(
webpackMerges.push(mergeFn); webpackMerges.push(mergeFn);
} }
export function resolveChainableConfig() { export function resolveChainableConfig(): Config {
const config = new Config(); const config = new Config();
if (!explicitUseConfig) { if (!explicitUseConfig) {
@ -86,10 +90,19 @@ export function resolveChainableConfig() {
// todo: allow opt-out // todo: allow opt-out
applyExternalConfigs(); applyExternalConfigs();
// this applies all chain configs const applyChains = (chains) => {
webpackChains.forEach((chainFn) => { // this applies the chain configs
return chainFn(config, env); chains.forEach((chainFn) => {
}); return chainFn(config, env);
});
};
// first we apply base configs
applyChains(webpackChains.base);
// then regular configs
applyChains(webpackChains.normal);
// finally configs that opted to be called last
applyChains(webpackChains.last);
if (env.verbose) { if (env.verbose) {
info('Resolved chainable config (before merges):'); info('Resolved chainable config (before merges):');
@ -99,7 +112,9 @@ export function resolveChainableConfig() {
return config; return config;
} }
export function resolveConfig(chainableConfig = resolveChainableConfig()) { export function resolveConfig(
chainableConfig = resolveChainableConfig()
): webpack.Configuration {
if (!hasInitialized) { if (!hasInitialized) {
throw error('resolveConfig() must be called after init()'); throw error('resolveConfig() must be called after init()');
} }