Skip to content

Commit c592ec5

Browse files
committed
feat(@angular-devkit/build-angular): amend polyfills option in all builders to support an array of module specifiers
This is the ground work to be able to remove the `polyfills.ts` file which today is primarily used to add `zone.js`. Usage examples: ```js polyfills: ['zone.js'], polyfills: ['zone.js', 'zone.js/testing', 'src/polyfills.ts'], ```
1 parent f393b09 commit c592ec5

File tree

10 files changed

+114
-23
lines changed

10 files changed

+114
-23
lines changed

goldens/public-api/angular_devkit/build_angular/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export interface BrowserBuilderOptions {
5353
outputHashing?: OutputHashing;
5454
outputPath: string;
5555
poll?: number;
56-
polyfills?: string;
56+
polyfills?: Polyfills;
5757
preserveSymlinks?: boolean;
5858
progress?: boolean;
5959
resourcesOutputPath?: string;
@@ -180,7 +180,7 @@ export interface KarmaBuilderOptions {
180180
karmaConfig: string;
181181
main: string;
182182
poll?: number;
183-
polyfills?: string;
183+
polyfills?: Polyfills_2;
184184
preserveSymlinks?: boolean;
185185
progress?: boolean;
186186
reporters?: string[];

packages/angular_devkit/build_angular/src/builders/browser-esbuild/options.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import { BuilderContext } from '@angular-devkit/architect';
1010
import * as path from 'path';
1111
import { normalizeAssetPatterns, normalizeOptimization, normalizeSourceMaps } from '../../utils';
12+
import { normalizePolyfills } from '../../utils/normalize-polyfills';
1213
import { Schema as BrowserBuilderOptions, OutputHashing } from '../browser/schema';
1314

1415
/**
@@ -33,10 +34,21 @@ export async function normalizeOptions(
3334
workspaceRoot,
3435
(projectMetadata.sourceRoot as string | undefined) ?? 'src',
3536
);
36-
3737
// Normalize options
3838
const mainEntryPoint = path.join(workspaceRoot, options.main);
39-
const polyfillsEntryPoint = options.polyfills && path.join(workspaceRoot, options.polyfills);
39+
40+
// Currently esbuild do not support multiple files per entry-point
41+
const [polyfillsEntryPoint, ...remainingPolyfills] = normalizePolyfills(
42+
options.polyfills,
43+
workspaceRoot,
44+
);
45+
46+
if (remainingPolyfills.length) {
47+
context.logger.warn(
48+
`The 'polyfills' option currently does not support multiple entries by this experimental builder. The first entry will be used.`,
49+
);
50+
}
51+
4052
const tsconfig = path.join(workspaceRoot, options.tsConfig);
4153
const outputPath = path.join(workspaceRoot, options.outputPath);
4254
const optimizationOptions = normalizeOptimization(options.optimization);

packages/angular_devkit/build_angular/src/builders/browser-esbuild/schema.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,22 @@
1717
"description": "The full path for the main entry point to the app, relative to the current workspace."
1818
},
1919
"polyfills": {
20-
"type": "string",
21-
"description": "The full path for the polyfills file, relative to the current workspace."
20+
"description": "Polyfills to be included in the build.",
21+
"oneOf": [
22+
{
23+
"type": "array",
24+
"description": "A list of polyfills to include in the build. Can be a full path for a file, relative to the current workspace or module specifier. Example: 'zone.js'.",
25+
"items": {
26+
"type": "string",
27+
"uniqueItems": true
28+
},
29+
"default": []
30+
},
31+
{
32+
"type": "string",
33+
"description": "The full path for the polyfills file, relative to the current workspace or a module specifier. Example: 'zone.js'."
34+
}
35+
]
2236
},
2337
"tsConfig": {
2438
"type": "string",

packages/angular_devkit/build_angular/src/builders/browser/schema.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,22 @@
1717
"description": "The full path for the main entry point to the app, relative to the current workspace."
1818
},
1919
"polyfills": {
20-
"type": "string",
21-
"description": "The full path for the polyfills file, relative to the current workspace."
20+
"description": "Polyfills to be included in the build.",
21+
"oneOf": [
22+
{
23+
"type": "array",
24+
"description": "A list of polyfills to include in the build. Can be a full path for a file, relative to the current workspace or module specifier. Example: 'zone.js'.",
25+
"items": {
26+
"type": "string",
27+
"uniqueItems": true
28+
},
29+
"default": []
30+
},
31+
{
32+
"type": "string",
33+
"description": "The full path for the polyfills file, relative to the current workspace or a module specifier. Example: 'zone.js'."
34+
}
35+
]
2236
},
2337
"tsConfig": {
2438
"type": "string",

packages/angular_devkit/build_angular/src/builders/browser/tests/options/polyfills_spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,16 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
5454

5555
harness.expectFile('dist/polyfills.js').toNotExist();
5656
});
57+
58+
it('resolves module specifiers in array', async () => {
59+
harness.useTarget('build', {
60+
...BASE_OPTIONS,
61+
polyfills: ['zone.js', 'zone.js/testing'],
62+
});
63+
64+
const { result } = await harness.executeOnce();
65+
expect(result?.success).toBeTrue();
66+
harness.expectFile('dist/polyfills.js').toExist();
67+
});
5768
});
5869
});

packages/angular_devkit/build_angular/src/builders/karma/schema.json

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,22 @@
1717
"description": "The name of the Karma configuration file."
1818
},
1919
"polyfills": {
20-
"type": "string",
21-
"description": "The name of the polyfills file."
20+
"description": "Polyfills to be included in the build.",
21+
"oneOf": [
22+
{
23+
"type": "array",
24+
"description": "A list of polyfills to include in the build. Can be a full path for a file, relative to the current workspace or module specifier. Example: 'zone.js'.",
25+
"items": {
26+
"type": "string",
27+
"uniqueItems": true
28+
},
29+
"default": []
30+
},
31+
{
32+
"type": "string",
33+
"description": "The full path for the polyfills file, relative to the current workspace or a module specifier. Example: 'zone.js'."
34+
}
35+
]
2236
},
2337
"assets": {
2438
"type": "array",

packages/angular_devkit/build_angular/src/utils/build-options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export interface BuildOptions {
5858
statsJson: boolean;
5959
hmr?: boolean;
6060
main: string;
61-
polyfills?: string;
61+
polyfills: string[];
6262
budgets: Budget[];
6363
assets: AssetPatternClass[];
6464
scripts: ScriptElement[];

packages/angular_devkit/build_angular/src/utils/normalize-builder-schema.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
normalizeFileReplacements,
2121
} from './normalize-file-replacements';
2222
import { NormalizedOptimizationOptions, normalizeOptimization } from './normalize-optimization';
23+
import { normalizePolyfills } from './normalize-polyfills';
2324
import { normalizeSourceMaps } from './normalize-source-maps';
2425
import { getSupportedBrowsers } from './supported-browsers';
2526

@@ -32,6 +33,7 @@ export type NormalizedBrowserBuilderSchema = BrowserBuilderSchema &
3233
assets: AssetPatternClass[];
3334
fileReplacements: NormalizedFileReplacement[];
3435
optimization: NormalizedOptimizationOptions;
36+
polyfills: string[];
3537
};
3638

3739
export function normalizeBrowserSchema(
@@ -42,8 +44,6 @@ export function normalizeBrowserSchema(
4244
metadata: json.JsonObject,
4345
logger: logging.LoggerApi,
4446
): NormalizedBrowserBuilderSchema {
45-
const normalizedSourceMapOptions = normalizeSourceMaps(options.sourceMap || false);
46-
4747
return {
4848
...options,
4949
cache: normalizeCacheOptions(metadata, workspaceRoot),
@@ -55,7 +55,8 @@ export function normalizeBrowserSchema(
5555
),
5656
fileReplacements: normalizeFileReplacements(options.fileReplacements || [], workspaceRoot),
5757
optimization: normalizeOptimization(options.optimization),
58-
sourceMap: normalizedSourceMapOptions,
58+
sourceMap: normalizeSourceMaps(options.sourceMap || false),
59+
polyfills: normalizePolyfills(options.polyfills, workspaceRoot),
5960
preserveSymlinks:
6061
options.preserveSymlinks === undefined
6162
? process.execArgv.includes('--preserve-symlinks')
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { existsSync } from 'fs';
10+
import { resolve } from 'path';
11+
12+
export function normalizePolyfills(
13+
polyfills: string[] | string | undefined,
14+
root: string,
15+
): string[] {
16+
if (!polyfills) {
17+
return [];
18+
}
19+
20+
const polyfillsList = Array.isArray(polyfills) ? polyfills : [polyfills];
21+
22+
return polyfillsList.map((p) => {
23+
const resolvedPath = resolve(root, p);
24+
25+
// If file doesn't exist, let the bundle resolve it using node module resolution.
26+
return existsSync(resolvedPath) ? resolvedPath : p;
27+
});
28+
}

packages/angular_devkit/build_angular/src/webpack/configs/common.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export async function getCommonConfig(wco: WebpackConfigOptions): Promise<Config
7777
const isPlatformServer = buildOptions.platform === 'server';
7878
const extraPlugins: { apply(compiler: Compiler): void }[] = [];
7979
const extraRules: RuleSetRule[] = [];
80-
const entryPoints: { [key: string]: [string, ...string[]] } = {};
80+
const entryPoints: Configuration['entry'] = {};
8181

8282
// Load ESM `@angular/compiler-cli` using the TypeScript dynamic import workaround.
8383
// Once TypeScript provides support for keeping the dynamic import this workaround can be
@@ -105,14 +105,11 @@ export async function getCommonConfig(wco: WebpackConfigOptions): Promise<Config
105105
extraPlugins.push(new ContextReplacementPlugin(/@?hapi|express[\\/]/));
106106
}
107107

108-
if (!isPlatformServer) {
109-
if (buildOptions.polyfills) {
110-
const projectPolyfills = path.resolve(root, buildOptions.polyfills);
111-
if (entryPoints['polyfills']) {
112-
entryPoints['polyfills'].push(projectPolyfills);
113-
} else {
114-
entryPoints['polyfills'] = [projectPolyfills];
115-
}
108+
if (buildOptions.polyfills.length) {
109+
if (Array.isArray(entryPoints['polyfills'])) {
110+
entryPoints['polyfills'].push(...buildOptions.polyfills);
111+
} else {
112+
entryPoints['polyfills'] = buildOptions.polyfills;
116113
}
117114
}
118115

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy