Skip to content

Commit

Permalink
feat(custom-webpack): pass target options to custom webpack config fu…
Browse files Browse the repository at this point in the history
…nction (#721)

* closes #683
  • Loading branch information
gdoerr authored Apr 15, 2020
1 parent 53115f0 commit 7a44528
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 15 deletions.
10 changes: 6 additions & 4 deletions packages/custom-webpack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,9 @@ In this case, the behavior will be the same as when exporting a plain object —
If `customWebpackConfig.path` file exports a function, the behaviour of the builder changes : no more automatic merge is applied, instead the function
is called with the base Webpack configuration and must return the new configuration.
The function is called with the base config and the builder options as parameters.
The function is called with the base config the builder options and the target options as parameters.
`TargetOptions` follows `target` definition from [this](https://github.com/angular/angular-cli/blob/master/packages/angular_devkit/architect/src/input-schema.json) schema
and can be used to manipulate your build based on the build target.
In this case, `mergeStrategies` and `replaceDuplicatePlugins` options have no effect.
Expand All @@ -301,7 +303,7 @@ In this case, `mergeStrategies` and `replaceDuplicatePlugins` options have no ef
const webpack = require('webpack');
const pkg = require('./package.json');

module.exports = (config, options) => {
module.exports = (config, options, targetOptions) => {
config.plugins.push(
new webpack.DefinePlugin({
APP_VERSION: JSON.stringify(pkg.version),
Expand All @@ -315,11 +317,11 @@ module.exports = (config, options) => {
Alternatively, using TypeScript:
```ts
import { CustomWebpackBrowserSchema } from '@angular-builders/custom-webpack';
import { CustomWebpackBrowserSchema, TargetOptions } from '@angular-builders/custom-webpack';
import * as webpack from 'webpack';
import * as pkg from './package.json';

export default (config: webpack.Configuration, options: CustomWebpackBrowserSchema) => {
export default (config: webpack.Configuration, options: CustomWebpackBrowserSchema, targetOptions: TargetOptions) => {
config.plugins.push(
new webpack.DefinePlugin({
APP_VERSION: JSON.stringify(pkg.version),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Configuration } from 'webpack';
import { CustomWebpackBrowserSchema } from '@angular-builders/custom-webpack';
import { CustomWebpackBrowserSchema, TargetOptions } from '@angular-builders/custom-webpack';
import * as HtmlWebpackPlugin from 'html-webpack-plugin';

/**
* This is where you define a function that modifies your webpack config
*/
export default (cfg: Configuration, opts: CustomWebpackBrowserSchema) => {
export default (cfg: Configuration, opts: CustomWebpackBrowserSchema, targetOptions: TargetOptions) => {
cfg.plugins.push(
new HtmlWebpackPlugin({
filename: 'footer.html',
Expand Down
5 changes: 3 additions & 2 deletions packages/custom-webpack/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ import { tsNodeRegister } from './utils';
export const customWebpackConfigTransformFactory: (
options: CustomWebpackSchema,
context: BuilderContext
) => ExecutionTransformer<Configuration> = (options, { workspaceRoot }) => browserWebpackConfig => {
) => ExecutionTransformer<Configuration> = (options, { workspaceRoot, target }) => browserWebpackConfig => {
return CustomWebpackBuilder.buildWebpackConfig(
normalize(workspaceRoot),
options.customWebpackConfig,
browserWebpackConfig,
options //TODO: pass Target options as well (configuration option in particular)
options,
target
);
};

Expand Down
20 changes: 17 additions & 3 deletions packages/custom-webpack/src/custom-webpack-builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ const buildOptions = {
env: 'prod',
};

const targetOptions = {
project: 'application',
configuration: 'production',
target: 'serve'
};

const customWebpackConfig = {
module: {
rules: [
Expand Down Expand Up @@ -62,6 +68,7 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
null,
baseWebpackConfig,
{},
{}
);

Expand All @@ -71,7 +78,7 @@ describe('CustomWebpackBuilder', () => {
it('should load webpack.config.js if no path specified', async () => {
const spy = jest.spyOn(webpackConfigMerger, 'mergeConfigs');
createConfigFile(defaultWebpackConfigPath, customWebpackConfig);
await CustomWebpackBuilder.buildWebpackConfig(__dirname as Path, {}, baseWebpackConfig, {});
await CustomWebpackBuilder.buildWebpackConfig(__dirname as Path, {}, baseWebpackConfig, {}, {});

try {
expect(spy).toHaveBeenCalledWith(
Expand All @@ -94,6 +101,7 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
{ path: fileName },
baseWebpackConfig,
{},
{}
);

Expand All @@ -118,6 +126,7 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
{ mergeStrategies },
baseWebpackConfig,
{},
{}
);

Expand All @@ -141,6 +150,7 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
{ replaceDuplicatePlugins: true },
baseWebpackConfig,
{},
{}
);

Expand All @@ -158,9 +168,10 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
{},
baseWebpackConfig,
buildOptions
buildOptions,
targetOptions
);
expect(spy).toHaveBeenCalledWith(baseWebpackConfig, buildOptions);
expect(spy).toHaveBeenCalledWith(baseWebpackConfig, buildOptions, targetOptions);
});

it('should apply custom function on configuration', async () => {
Expand All @@ -170,6 +181,7 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
{},
baseWebpackConfig,
{},
{}
);

Expand All @@ -193,6 +205,7 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
{},
baseWebpackConfig,
{},
{}
);

Expand Down Expand Up @@ -221,6 +234,7 @@ describe('CustomWebpackBuilder', () => {
__dirname as Path,
{},
baseWebpackConfig,
{},
{}
);

Expand Down
11 changes: 7 additions & 4 deletions packages/custom-webpack/src/custom-webpack-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@ import { Configuration } from 'webpack';
import { mergeConfigs } from './webpack-config-merger';
import { CustomWebpackBuilderConfig } from './custom-webpack-builder-config';
import { tsNodeRegister } from './utils';
import {TargetOptions} from "./type-definition";
import {CustomWebpackBrowserSchema} from "./browser";

export const defaultWebpackConfigPath = 'webpack.config.js';

type CustomWebpackConfig =
| Configuration
| Promise<Configuration>
| ((baseWebpackConfig: Configuration, buildOptions: any) => Configuration)
| ((baseWebpackConfig: Configuration, buildOptions: any) => Promise<Configuration>);
| ((baseWebpackConfig: Configuration, buildOptions: CustomWebpackBrowserSchema, targetOptions: TargetOptions) => Configuration)
| ((baseWebpackConfig: Configuration, buildOptions: CustomWebpackBrowserSchema, targetOptions: TargetOptions) => Promise<Configuration>);

export class CustomWebpackBuilder {
static async buildWebpackConfig(
root: Path,
config: CustomWebpackBuilderConfig,
baseWebpackConfig: Configuration,
buildOptions: any
buildOptions: any,
targetOptions: TargetOptions
): Promise<Configuration> {
if (!config) {
return baseWebpackConfig;
Expand All @@ -32,7 +35,7 @@ export class CustomWebpackBuilder {
// That exported function can be synchronous either
// asynchronous. Given the following example:
// `module.exports = async (config) => { ... }`
return configOrFactoryOrPromise(baseWebpackConfig, buildOptions);
return configOrFactoryOrPromise(baseWebpackConfig, buildOptions, targetOptions);
}

// The user can also export a `Promise` that resolves `Configuration`
Expand Down

0 comments on commit 7a44528

Please sign in to comment.