Skip to content

Commit

Permalink
refactor(@angular-devkit/build-angular): remove deprecated ES5 support
Browse files Browse the repository at this point in the history
Remove deprecated support for ES5 output.

BREAKING CHANGE: Producing ES5 output is no longer possible. This was needed for Internet Explorer which is no longer supported. All browsers that Angular supports work with ES2015+
  • Loading branch information
alan-agius4 authored and dgp1130 committed Sep 16, 2022
1 parent 1c21e47 commit 12931ba
Show file tree
Hide file tree
Showing 22 changed files with 268 additions and 589 deletions.
Expand Up @@ -11,7 +11,6 @@ import type {
DiagnosticHandlingStrategy,
Diagnostics,
makeEs2015TranslatePlugin,
makeEs5TranslatePlugin,
makeLocalePlugin,
} from '@angular/localize/tools';
import { strict as assert } from 'assert';
Expand All @@ -28,7 +27,6 @@ export type DiagnosticReporter = (type: 'error' | 'warning' | 'info', message: s
*/
export interface I18nPluginCreators {
makeEs2015TranslatePlugin: typeof makeEs2015TranslatePlugin;
makeEs5TranslatePlugin: typeof makeEs5TranslatePlugin;
makeLocalePlugin: typeof makeLocalePlugin;
}

Expand Down Expand Up @@ -117,20 +115,14 @@ function createI18nPlugins(
const diagnostics = createI18nDiagnostics(diagnosticReporter);
const plugins = [];

const { makeEs5TranslatePlugin, makeEs2015TranslatePlugin, makeLocalePlugin } = pluginCreators;
const { makeEs2015TranslatePlugin, makeLocalePlugin } = pluginCreators;

if (translation) {
plugins.push(
makeEs2015TranslatePlugin(diagnostics, translation, {
missingTranslation: missingTranslationBehavior,
}),
);

plugins.push(
makeEs5TranslatePlugin(diagnostics, translation, {
missingTranslation: missingTranslationBehavior,
}),
);
}

plugins.push(makeLocalePlugin(locale));
Expand Down
Expand Up @@ -117,15 +117,7 @@ export default custom<ApplicationPresetOptions>(() => {
const esTarget = scriptTarget as ScriptTarget | undefined;
const isJsFile = /\.[cm]?js$/.test(this.resourcePath);

// The below should be dropped when we no longer support ES5 TypeScript output.
if (esTarget === ScriptTarget.ES5) {
// This is needed because when target is ES5 we change the TypeScript target to ES2015
// because it simplifies build-optimization passes.
// @see https://github.com/angular/angular-cli/blob/22af6520834171d01413d4c7e4a9f13fb752252e/packages/angular_devkit/build_angular/src/webpack/plugins/typescript.ts#L51-L56
customOptions.forcePresetEnv = true;
// Comparable behavior to tsconfig target of ES5
customOptions.supportedBrowsers = ['IE 9'];
} else if (isJsFile && customOptions.supportedBrowsers?.length) {
if (isJsFile && customOptions.supportedBrowsers?.length) {
// Applications code ES version can be controlled using TypeScript's `target` option.
// However, this doesn't effect libraries and hence we use preset-env to downlevel ES fetaures
// based on the supported browsers in browserlist.
Expand Down
Expand Up @@ -8,12 +8,10 @@

import { BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect';
import { EmittedFiles, WebpackLoggingCallback, runWebpack } from '@angular-devkit/build-webpack';
import { logging } from '@angular-devkit/core';
import * as fs from 'fs';
import * as path from 'path';
import { Observable, from } from 'rxjs';
import { concatMap, map, switchMap } from 'rxjs/operators';
import { ScriptTarget } from 'typescript';
import webpack from 'webpack';
import { ExecutionTransformer } from '../../transforms';
import {
Expand Down Expand Up @@ -43,7 +41,6 @@ import { generateEntryPoints } from '../../utils/package-chunk-sort';
import { purgeStaleBuildCache } from '../../utils/purge-cache';
import { augmentAppWithServiceWorker } from '../../utils/service-worker';
import { Spinner } from '../../utils/spinner';
import { getSupportedBrowsers } from '../../utils/supported-browsers';
import { assertCompatibleAngularVersion } from '../../utils/version';
import {
generateI18nBrowserWebpackConfigFromContext,
Expand Down Expand Up @@ -98,14 +95,13 @@ async function initialize(
projectRoot: string;
projectSourceRoot?: string;
i18n: I18nOptions;
target: ScriptTarget;
}> {
const originalOutputPath = options.outputPath;

// Assets are processed directly by the builder except when watching
const adjustedOptions = options.watch ? options : { ...options, assets: [] };

const { config, projectRoot, projectSourceRoot, i18n, target } =
const { config, projectRoot, projectSourceRoot, i18n } =
await generateI18nBrowserWebpackConfigFromContext(adjustedOptions, context, (wco) => [
getCommonConfig(wco),
getStylesConfig(wco),
Expand Down Expand Up @@ -135,7 +131,7 @@ async function initialize(
deleteOutputDir(context.workspaceRoot, originalOutputPath);
}

return { config: transformedConfig || config, projectRoot, projectSourceRoot, i18n, target };
return { config: transformedConfig || config, projectRoot, projectSourceRoot, i18n };
}

/**
Expand Down Expand Up @@ -170,9 +166,6 @@ export function buildWebpackBrowser(
// Initialize builder
const initialization = await initialize(options, context, transforms.webpackConfiguration);

// Check and warn about IE browser support
checkInternetExplorerSupport(initialization.projectRoot, context.logger);

// Add index file to watched files.
if (options.watch) {
const indexInputFile = path.join(context.workspaceRoot, getIndexInputFile(options.index));
Expand All @@ -193,7 +186,7 @@ export function buildWebpackBrowser(
}),
switchMap(
// eslint-disable-next-line max-lines-per-function
({ config, projectRoot, projectSourceRoot, i18n, target, cacheOptions }) => {
({ config, projectRoot, projectSourceRoot, i18n, cacheOptions }) => {
const normalizedOptimization = normalizeOptimization(options.optimization);

return runWebpack(config, context, {
Expand Down Expand Up @@ -255,7 +248,6 @@ export function buildWebpackBrowser(
Array.from(outputPaths.values()),
scriptsEntryPointName,
webpackOutputPath,
target <= ScriptTarget.ES5,
options.i18nMissingTranslation,
);
if (!success) {
Expand Down Expand Up @@ -458,15 +450,4 @@ function mapEmittedFilesToFileInfo(files: EmittedFiles[] = []): FileInfo[] {
return filteredFiles;
}

function checkInternetExplorerSupport(projectRoot: string, logger: logging.LoggerApi): void {
const supportedBrowsers = getSupportedBrowsers(projectRoot);
if (supportedBrowsers.some((b) => b === 'ie 9' || b === 'ie 10' || b === 'ie 11')) {
logger.warn(
`Warning: Support was requested for Internet Explorer in the project's browserslist configuration. ` +
'Internet Explorer is no longer officially supported.' +
'\nFor more information, see https://angular.io/guide/browser-support',
);
}
}

export default createBuilder<BrowserBuilderSchema>(buildWebpackBrowser);
Expand Up @@ -29,7 +29,11 @@ describe('Browser Builder allow js', () => {
'src/main.ts': `import { a } from './my-js-file'; console.log(a);`,
});

host.replaceInFile('tsconfig.json', '"target": "es2020"', '"target": "es5", "allowJs": true');
host.replaceInFile(
'tsconfig.json',
'"target": "es2020"',
'"target": "es2020", "allowJs": true',
);

const run = await architect.scheduleTarget(targetSpec);
const output = (await run.result) as BrowserBuilderOutput;
Expand All @@ -39,7 +43,7 @@ describe('Browser Builder allow js', () => {
await host.read(join(normalize(output.outputPath), 'main.js')).toPromise(),
);

expect(content).toContain('var a = 2');
expect(content).toContain('const a = 2');

await run.stop();
});
Expand All @@ -50,7 +54,11 @@ describe('Browser Builder allow js', () => {
'src/main.ts': `import { a } from './my-js-file'; console.log(a);`,
});

host.replaceInFile('tsconfig.json', '"target": "es2020"', '"target": "es5", "allowJs": true');
host.replaceInFile(
'tsconfig.json',
'"target": "es2020"',
'"target": "es2020", "allowJs": true',
);

const overrides = { aot: true };

Expand All @@ -62,7 +70,7 @@ describe('Browser Builder allow js', () => {
await host.read(join(normalize(output.outputPath), 'main.js')).toPromise(),
);

expect(content).toContain('var a = 2');
expect(content).toContain('const a = 2');

await run.stop();
});
Expand All @@ -73,7 +81,11 @@ describe('Browser Builder allow js', () => {
'src/main.ts': `import { a } from './my-js-file'; console.log(a);`,
});

host.replaceInFile('tsconfig.json', '"target": "es2020"', '"target": "es5", "allowJs": true');
host.replaceInFile(
'tsconfig.json',
'"target": "es2020"',
'"target": "es2020", "allowJs": true',
);

const overrides = { watch: true };

Expand All @@ -88,13 +100,13 @@ describe('Browser Builder allow js', () => {

switch (buildCount) {
case 1:
expect(content).toContain('var a = 2');
expect(content).toContain('const a = 2');
host.writeMultipleFiles({
'src/my-js-file.js': `console.log(1); export const a = 1;`,
});
break;
case 2:
expect(content).toContain('var a = 1');
expect(content).toContain('const a = 1');
break;
}

Expand Down

This file was deleted.

Expand Up @@ -26,14 +26,6 @@ describe('Browser Builder optimization level', () => {
expect(await files['main.js']).not.toContain('AppComponent');
});

it('tsconfig target changes optimizations to use es2017', async () => {
host.replaceInFile('tsconfig.json', '"target": "es5"', '"target": "es2017"');

const overrides = { optimization: true };
const { files } = await browserBuild(architect, host, target, overrides);
expect(await files['vendor.js']).toMatch(/class \w{1,3}{constructor\(\){/);
});

it('supports styles only optimizations', async () => {
const overrides = {
optimization: {
Expand Down
Expand Up @@ -30,7 +30,7 @@ describe('Browser Builder resolve json module', () => {
host.replaceInFile(
'tsconfig.json',
'"target": "es2020"',
'"target": "es5", "resolveJsonModule": true',
'"target": "es2020", "resolveJsonModule": true',
);

const overrides = { watch: true };
Expand Down

0 comments on commit 12931ba

Please sign in to comment.