Skip to content

Commit

Permalink
feat(@angular-devkit/build-angular): amend polyfills option in all …
Browse files Browse the repository at this point in the history
…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'],
```
  • Loading branch information
alan-agius4 committed Sep 26, 2022
1 parent f393b09 commit c592ec5
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 23 deletions.
4 changes: 2 additions & 2 deletions goldens/public-api/angular_devkit/build_angular/index.md
Expand Up @@ -53,7 +53,7 @@ export interface BrowserBuilderOptions {
outputHashing?: OutputHashing;
outputPath: string;
poll?: number;
polyfills?: string;
polyfills?: Polyfills;
preserveSymlinks?: boolean;
progress?: boolean;
resourcesOutputPath?: string;
Expand Down Expand Up @@ -180,7 +180,7 @@ export interface KarmaBuilderOptions {
karmaConfig: string;
main: string;
poll?: number;
polyfills?: string;
polyfills?: Polyfills_2;
preserveSymlinks?: boolean;
progress?: boolean;
reporters?: string[];
Expand Down
Expand Up @@ -9,6 +9,7 @@
import { BuilderContext } from '@angular-devkit/architect';
import * as path from 'path';
import { normalizeAssetPatterns, normalizeOptimization, normalizeSourceMaps } from '../../utils';
import { normalizePolyfills } from '../../utils/normalize-polyfills';
import { Schema as BrowserBuilderOptions, OutputHashing } from '../browser/schema';

/**
Expand All @@ -33,10 +34,21 @@ export async function normalizeOptions(
workspaceRoot,
(projectMetadata.sourceRoot as string | undefined) ?? 'src',
);

// Normalize options
const mainEntryPoint = path.join(workspaceRoot, options.main);
const polyfillsEntryPoint = options.polyfills && path.join(workspaceRoot, options.polyfills);

// Currently esbuild do not support multiple files per entry-point
const [polyfillsEntryPoint, ...remainingPolyfills] = normalizePolyfills(
options.polyfills,
workspaceRoot,
);

if (remainingPolyfills.length) {
context.logger.warn(
`The 'polyfills' option currently does not support multiple entries by this experimental builder. The first entry will be used.`,
);
}

const tsconfig = path.join(workspaceRoot, options.tsConfig);
const outputPath = path.join(workspaceRoot, options.outputPath);
const optimizationOptions = normalizeOptimization(options.optimization);
Expand Down
Expand Up @@ -17,8 +17,22 @@
"description": "The full path for the main entry point to the app, relative to the current workspace."
},
"polyfills": {
"type": "string",
"description": "The full path for the polyfills file, relative to the current workspace."
"description": "Polyfills to be included in the build.",
"oneOf": [
{
"type": "array",
"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'.",
"items": {
"type": "string",
"uniqueItems": true
},
"default": []
},
{
"type": "string",
"description": "The full path for the polyfills file, relative to the current workspace or a module specifier. Example: 'zone.js'."
}
]
},
"tsConfig": {
"type": "string",
Expand Down
Expand Up @@ -17,8 +17,22 @@
"description": "The full path for the main entry point to the app, relative to the current workspace."
},
"polyfills": {
"type": "string",
"description": "The full path for the polyfills file, relative to the current workspace."
"description": "Polyfills to be included in the build.",
"oneOf": [
{
"type": "array",
"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'.",
"items": {
"type": "string",
"uniqueItems": true
},
"default": []
},
{
"type": "string",
"description": "The full path for the polyfills file, relative to the current workspace or a module specifier. Example: 'zone.js'."
}
]
},
"tsConfig": {
"type": "string",
Expand Down
Expand Up @@ -54,5 +54,16 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {

harness.expectFile('dist/polyfills.js').toNotExist();
});

it('resolves module specifiers in array', async () => {
harness.useTarget('build', {
...BASE_OPTIONS,
polyfills: ['zone.js', 'zone.js/testing'],
});

const { result } = await harness.executeOnce();
expect(result?.success).toBeTrue();
harness.expectFile('dist/polyfills.js').toExist();
});
});
});
Expand Up @@ -17,8 +17,22 @@
"description": "The name of the Karma configuration file."
},
"polyfills": {
"type": "string",
"description": "The name of the polyfills file."
"description": "Polyfills to be included in the build.",
"oneOf": [
{
"type": "array",
"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'.",
"items": {
"type": "string",
"uniqueItems": true
},
"default": []
},
{
"type": "string",
"description": "The full path for the polyfills file, relative to the current workspace or a module specifier. Example: 'zone.js'."
}
]
},
"assets": {
"type": "array",
Expand Down
Expand Up @@ -58,7 +58,7 @@ export interface BuildOptions {
statsJson: boolean;
hmr?: boolean;
main: string;
polyfills?: string;
polyfills: string[];
budgets: Budget[];
assets: AssetPatternClass[];
scripts: ScriptElement[];
Expand Down
Expand Up @@ -20,6 +20,7 @@ import {
normalizeFileReplacements,
} from './normalize-file-replacements';
import { NormalizedOptimizationOptions, normalizeOptimization } from './normalize-optimization';
import { normalizePolyfills } from './normalize-polyfills';
import { normalizeSourceMaps } from './normalize-source-maps';
import { getSupportedBrowsers } from './supported-browsers';

Expand All @@ -32,6 +33,7 @@ export type NormalizedBrowserBuilderSchema = BrowserBuilderSchema &
assets: AssetPatternClass[];
fileReplacements: NormalizedFileReplacement[];
optimization: NormalizedOptimizationOptions;
polyfills: string[];
};

export function normalizeBrowserSchema(
Expand All @@ -42,8 +44,6 @@ export function normalizeBrowserSchema(
metadata: json.JsonObject,
logger: logging.LoggerApi,
): NormalizedBrowserBuilderSchema {
const normalizedSourceMapOptions = normalizeSourceMaps(options.sourceMap || false);

return {
...options,
cache: normalizeCacheOptions(metadata, workspaceRoot),
Expand All @@ -55,7 +55,8 @@ export function normalizeBrowserSchema(
),
fileReplacements: normalizeFileReplacements(options.fileReplacements || [], workspaceRoot),
optimization: normalizeOptimization(options.optimization),
sourceMap: normalizedSourceMapOptions,
sourceMap: normalizeSourceMaps(options.sourceMap || false),
polyfills: normalizePolyfills(options.polyfills, workspaceRoot),
preserveSymlinks:
options.preserveSymlinks === undefined
? process.execArgv.includes('--preserve-symlinks')
Expand Down
@@ -0,0 +1,28 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import { existsSync } from 'fs';
import { resolve } from 'path';

export function normalizePolyfills(
polyfills: string[] | string | undefined,
root: string,
): string[] {
if (!polyfills) {
return [];
}

const polyfillsList = Array.isArray(polyfills) ? polyfills : [polyfills];

return polyfillsList.map((p) => {
const resolvedPath = resolve(root, p);

// If file doesn't exist, let the bundle resolve it using node module resolution.
return existsSync(resolvedPath) ? resolvedPath : p;
});
}
Expand Up @@ -77,7 +77,7 @@ export async function getCommonConfig(wco: WebpackConfigOptions): Promise<Config
const isPlatformServer = buildOptions.platform === 'server';
const extraPlugins: { apply(compiler: Compiler): void }[] = [];
const extraRules: RuleSetRule[] = [];
const entryPoints: { [key: string]: [string, ...string[]] } = {};
const entryPoints: Configuration['entry'] = {};

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

if (!isPlatformServer) {
if (buildOptions.polyfills) {
const projectPolyfills = path.resolve(root, buildOptions.polyfills);
if (entryPoints['polyfills']) {
entryPoints['polyfills'].push(projectPolyfills);
} else {
entryPoints['polyfills'] = [projectPolyfills];
}
if (buildOptions.polyfills.length) {
if (Array.isArray(entryPoints['polyfills'])) {
entryPoints['polyfills'].push(...buildOptions.polyfills);
} else {
entryPoints['polyfills'] = buildOptions.polyfills;
}
}

Expand Down

0 comments on commit c592ec5

Please sign in to comment.