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

feat(custom-webpack): add extract-i18n builder #832

Merged
merged 8 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions packages/custom-webpack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Allow customizing build configuration without ejecting webpack configuration (`n

## Custom Webpack `browser`

Extended `@angular-devkit/build-angular:browser` builder that allows to specify additional webpack configuration (on top of the existing under the hood) and `index.html` tranformations.
Extended `@angular-devkit/build-angular:browser` builder that allows to specify additional webpack configuration (on top of the existing under the hood) and `index.html` transformations.
The builder will run the same build as `@angular-devkit/build-angular:browser` does with extra parameters that are specified in the provided webpack configuration. It will also run transformation on `index.html` if specified.

Builder options:
Expand Down Expand Up @@ -138,7 +138,7 @@ In this example `dev-server` will use `custom-webpack:browser` builder, hence mo

## Custom Webpack `server`

Extended `@angular-devkit/build-angular:server` builder that allows to specify additional webpack configuration (on top of the existing under the hood) and `index.html` tranformations.
Extended `@angular-devkit/build-angular:server` builder that allows to specify additional webpack configuration (on top of the existing under the hood) and `index.html` transformations.
The builder will run the same build as `@angular-devkit/build-angular:server` does with extra parameters that are specified in the provided webpack configuration.

Builder options:
Expand Down Expand Up @@ -172,7 +172,7 @@ Since loaders are evaluated [from right to left](https://webpack.js.org/concepts

## Custom Webpack `karma`

Extended `@angular-devkit/build-angular:karma` builder that allows to specify additional webpack configuration (on top of the existing under the hood) and `index.html` tranformations.
Extended `@angular-devkit/build-angular:karma` builder that allows to specify additional webpack configuration (on top of the existing under the hood) and `index.html` transformations.
The builder will run the same build as `@angular-devkit/build-angular:karma` does with extra parameters that are specified in the provided webpack configuration.

Builder options:
Expand All @@ -198,6 +198,40 @@ Builder options:
}
```

## Custom Webpack `extract-i18n`

Enhanced `@angular-devkit/build-angular:extract-i18n` builder that leverages the custom webpack builder to get webpack configuration.

The builder uses `customWebpackConfiguration` from `browserTarget` to run the extraction process while taking into account changes in your custom webpack config.

Thus, if you use `@angular-builders/custom-webpack:extract-i18n` along with `@angular-builders/custom-webpack:browser`, `ng extract-i18n` will run with custom configuration provided in the latter.

### Example

`angular.json`:

```js
"architect": {
...
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.js"
},
...
}
},
"extract-i18n": {
"builder": "@angular-builders/custom-webpack:extract-i18n",
"options": {
"browserTarget": "my-project:build"
}
}
```

In this example `extract-i18n` will use `custom-webpack:browser` builder, hence modified webpack config, when invoking the extract-i18n target.

# Custom Webpack Config Object

This option defines your custom webpack configuration. If not specified at all, plain Angular build will run.
Expand Down
5 changes: 5 additions & 0 deletions packages/custom-webpack/builders.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
"implementation": "./dist/karma",
"schema": "./dist/karma/schema.json",
"description": "Karma server extended with custom webpack config"
},
"extract-i18n": {
"implementation": "./dist/extract-i18n",
"schema": "./dist/extract-i18n/schema.json",
"description": "Extract i18n extended with custom webpack config"
}
}
}
12 changes: 5 additions & 7 deletions packages/custom-webpack/src/browser/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { BuilderContext, createBuilder } from '@angular-devkit/architect';
import { BrowserBuilderOptions, executeBrowserBuilder } from '@angular-devkit/build-angular';
import { json } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { getTransforms } from '../common';
import { getTransforms } from '../transform-factories';
import { CustomWebpackSchema } from '../custom-webpack-schema';

export type CustomWebpackBrowserSchema = BrowserBuilderOptions & CustomWebpackSchema;

export function buildCustomWebpackBrowser(
export const buildCustomWebpackBrowser = (
options: CustomWebpackBrowserSchema,
context: BuilderContext
): Observable<BuilderOutput> {
return executeBrowserBuilder(options, context, getTransforms(options, context));
}
): ReturnType<typeof executeBrowserBuilder> =>
executeBrowserBuilder(options, context, getTransforms(options, context));

export default createBuilder<json.JsonObject & CustomWebpackBrowserSchema>(
buildCustomWebpackBrowser
Expand Down
33 changes: 5 additions & 28 deletions packages/custom-webpack/src/dev-server/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,7 @@
import { BuilderContext, createBuilder, targetFromTargetString } from '@angular-devkit/architect';
import {
DevServerBuilderOptions,
DevServerBuilderOutput,
executeDevServerBuilder,
} from '@angular-devkit/build-angular';
import { from, Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { getTransforms } from '../common';
import { CustomWebpackSchema } from '../custom-webpack-schema';
import { createBuilder } from '@angular-devkit/architect';
import { DevServerBuilderOptions, executeDevServerBuilder } from '@angular-devkit/build-angular';
import { executeBrowserBasedBuilder } from '../generic-browser-builder';

export const serveCustomWebpackBrowser = (
options: DevServerBuilderOptions,
context: BuilderContext
): Observable<DevServerBuilderOutput> => {
async function setup() {
const browserTarget = targetFromTargetString(options.browserTarget);
return (context.getTargetOptions(browserTarget) as unknown) as CustomWebpackSchema;
}

return from(setup()).pipe(
switchMap(customWebpackOptions =>
executeDevServerBuilder(options, context, getTransforms(customWebpackOptions, context))
)
);
};

export default createBuilder<DevServerBuilderOptions, DevServerBuilderOutput>(
serveCustomWebpackBrowser
export default createBuilder<DevServerBuilderOptions>(
executeBrowserBasedBuilder(executeDevServerBuilder)
);
10 changes: 10 additions & 0 deletions packages/custom-webpack/src/extract-i18n/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createBuilder } from '@angular-devkit/architect';
import {
executeExtractI18nBuilder,
ExtractI18nBuilderOptions,
} from '@angular-devkit/build-angular';
import { executeBrowserBasedBuilder } from '../generic-browser-builder';

export default createBuilder<ExtractI18nBuilderOptions>(
executeBrowserBasedBuilder(executeExtractI18nBuilder)
);
5 changes: 5 additions & 0 deletions packages/custom-webpack/src/extract-i18n/schema.ext.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "Custom webpack extract-i18n schema for Build Facade",
"id": "BuildCustomWebpackExtractI18nSchema",
"description": "Extract i18n target options"
}
44 changes: 44 additions & 0 deletions packages/custom-webpack/src/generic-browser-builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
BuilderContext,
targetFromTargetString,
BuilderHandlerFn,
} from '@angular-devkit/architect';
import { ExecutionTransformer } from '@angular-devkit/build-angular';
import { IndexHtmlTransform } from '@angular-devkit/build-angular/src/angular-cli-files/utilities/index-file/write-index-html';
import { from } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { Configuration } from 'webpack';
import { CustomWebpackSchema } from './custom-webpack-schema';
import { getTransforms } from './transform-factories';
import { json } from '@angular-devkit/core';

export interface BrowserTargetOptions {
browserTarget: string;
}

export type BuilderExecutor<O extends BrowserTargetOptions & json.JsonObject> = (
options: O,
context: BuilderContext,
transforms?: {
webpackConfiguration?: ExecutionTransformer<Configuration>;
indexHtml?: IndexHtmlTransform;
}
) => any;

export const executeBrowserBasedBuilder = <O extends BrowserTargetOptions & json.JsonObject>(
executebBuilder: BuilderExecutor<O>
): BuilderHandlerFn<O> => (
options: O,
context: BuilderContext
): ReturnType<typeof executebBuilder> => {
async function setup() {
const browserTarget = targetFromTargetString(options.browserTarget);
return (context.getTargetOptions(browserTarget) as unknown) as CustomWebpackSchema;
}

return from(setup()).pipe(
switchMap(customWebpackOptions =>
executebBuilder(options, context, getTransforms(customWebpackOptions, context))
)
);
};
2 changes: 1 addition & 1 deletion packages/custom-webpack/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export * from './browser';
export * from './karma';
export * from './server';
export * from './dev-server';
export * from './common';
export * from './transform-factories';
export { TargetOptions } from './type-definition';
12 changes: 5 additions & 7 deletions packages/custom-webpack/src/karma/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@
* Created by Evgeny Barabanov on 05/10/2018.
*/

import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { BuilderContext, createBuilder } from '@angular-devkit/architect';
import { executeKarmaBuilder, KarmaBuilderOptions } from '@angular-devkit/build-angular';
import { json } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { customWebpackConfigTransformFactory } from '../common';
import { customWebpackConfigTransformFactory } from '../transform-factories';
import { CustomWebpackSchema } from '../custom-webpack-schema';

export type CustomWebpackKarmaBuildSchema = KarmaBuilderOptions & CustomWebpackSchema;

export function buildCustomWebpackKarma(
export const buildCustomWebpackKarma = (
options: CustomWebpackKarmaBuildSchema,
context: BuilderContext
): Observable<BuilderOutput> {
return executeKarmaBuilder(options, context, {
): ReturnType<typeof executeKarmaBuilder> =>
executeKarmaBuilder(options, context, {
webpackConfiguration: customWebpackConfigTransformFactory(options, context),
});
}

export default createBuilder<json.JsonObject & CustomWebpackKarmaBuildSchema>(
buildCustomWebpackKarma
Expand Down
10 changes: 6 additions & 4 deletions packages/custom-webpack/src/schemes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ module.exports = [
},
{
originalSchemaPath: '@angular-devkit/build-angular/src/dev-server/schema.json',
schemaExtensionPaths: [
`${__dirname}/dev-server/schema.ext.json`,
`${__dirname}/schema.ext.json`,
],
schemaExtensionPaths: [`${__dirname}/dev-server/schema.ext.json`],
newSchemaPath: `${__dirname}/../dist/dev-server/schema.json`,
},
{
originalSchemaPath: '@angular-devkit/build-angular/src/extract-i18n/schema.json',
schemaExtensionPaths: [`${__dirname}/extract-i18n/schema.ext.json`],
newSchemaPath: `${__dirname}/../dist/extract-i18n/schema.json`,
},
];
9 changes: 4 additions & 5 deletions packages/custom-webpack/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/ar
import { executeServerBuilder, ServerBuilderOptions } from '@angular-devkit/build-angular';
import { json } from '@angular-devkit/core';
import { Observable } from 'rxjs';
import { customWebpackConfigTransformFactory } from '../common';
import { customWebpackConfigTransformFactory } from '../transform-factories';
import { CustomWebpackSchema } from '../custom-webpack-schema';

export type CustomWebpackServerSchema = ServerBuilderOptions & CustomWebpackSchema;

export function buildCustomWebpackServer(
export const buildCustomWebpackServer = (
options: CustomWebpackServerSchema,
context: BuilderContext
): Observable<BuilderOutput> {
return executeServerBuilder(options, context, {
): ReturnType<typeof executeServerBuilder> =>
executeServerBuilder(options, context, {
webpackConfiguration: customWebpackConfigTransformFactory(options, context),
});
}

export default createBuilder<json.JsonObject & CustomWebpackServerSchema>(buildCustomWebpackServer);
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { BuilderContext } from '@angular-devkit/architect';
import { ExecutionTransformer } from '@angular-devkit/build-angular';
import { IndexHtmlTransform } from '@angular-devkit/build-angular/src/angular-cli-files/utilities/index-file/write-index-html';
import { normalize, getSystemPath } from '@angular-devkit/core';

import { getSystemPath, normalize } from '@angular-devkit/core';
import { Configuration } from 'webpack';

import { CustomWebpackBuilder } from './custom-webpack-builder';
import { CustomWebpackSchema } from './custom-webpack-schema';
import { tsNodeRegister } from './utils';

export const customWebpackConfigTransformFactory: (
options: CustomWebpackSchema,
context: BuilderContext
) => ExecutionTransformer<Configuration> = (options, { workspaceRoot, target }) => browserWebpackConfig => {
) => ExecutionTransformer<Configuration> = (
options,
{ workspaceRoot, target }
) => browserWebpackConfig => {
return CustomWebpackBuilder.buildWebpackConfig(
normalize(workspaceRoot),
options.customWebpackConfig,
Expand Down