From 450b4525397349ff8e078053374e9906ddde6bd8 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 16 Dec 2020 10:44:42 -0500 Subject: [PATCH 1/3] feat(@angular-devkit/build-angular): integrate Angular compiler linker The newly introduced library linker mode that removes the need for ngcc is integrated into the Angular CLI's build system. This allows libraries that are built in linker mode to be used when building an application. --- .../build_angular/src/babel/babel-loader.d.ts | 24 ++++ .../src/babel/presets/application.ts | 41 +++++- .../build_angular/src/babel/webpack-loader.ts | 120 ++++++++++++++++++ .../src/webpack/configs/common.ts | 38 ++---- 4 files changed, 195 insertions(+), 28 deletions(-) create mode 100644 packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts create mode 100644 packages/angular_devkit/build_angular/src/babel/webpack-loader.ts diff --git a/packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts b/packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts new file mode 100644 index 000000000000..5a408783788d --- /dev/null +++ b/packages/angular_devkit/build_angular/src/babel/babel-loader.d.ts @@ -0,0 +1,24 @@ +/** + * @license + * Copyright Google Inc. 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 + */ +declare module 'babel-loader' { + type BabelLoaderCustomizer = ( + babel: typeof import('@babel/core'), + ) => { + customOptions?( + this: import('webpack').loader.LoaderContext, + loaderOptions: Record, + loaderArguments: { source: string; map?: unknown }, + ): Promise<{ custom?: T; loader: Record }>; + config?( + this: import('webpack').loader.LoaderContext, + configuration: import('@babel/core').PartialConfig, + loaderArguments: { source: string; map?: unknown; customOptions: T }, + ): import('@babel/core').TransformOptions; + }; + function custom(customizer: BabelLoaderCustomizer): import('webpack').loader.Loader; +} diff --git a/packages/angular_devkit/build_angular/src/babel/presets/application.ts b/packages/angular_devkit/build_angular/src/babel/presets/application.ts index 71bc698a5767..f0e12ec93a9e 100644 --- a/packages/angular_devkit/build_angular/src/babel/presets/application.ts +++ b/packages/angular_devkit/build_angular/src/babel/presets/application.ts @@ -5,9 +5,10 @@ * 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 * as fs from 'fs'; import * as path from 'path'; -export type DiagnosticReporter = (type: 'error' | 'warning', message: string) => void; +export type DiagnosticReporter = (type: 'error' | 'warning' | 'info', message: string) => void; export interface ApplicationPresetOptions { i18n?: { locale: string; @@ -15,6 +16,8 @@ export interface ApplicationPresetOptions { translation?: unknown; }; + angularLinker?: boolean; + forceES5?: boolean; forceAsyncTransformation?: boolean; @@ -98,11 +101,47 @@ function createI18nPlugins( return plugins; } +function createNgtscLogger( + reporter: DiagnosticReporter | undefined, +): import('@angular/compiler-cli/src/ngtsc/logging').Logger { + return { + level: 1, // Info level + debug(...args: string[]) {}, + info(...args: string[]) { + reporter?.('info', args.join()); + }, + warn(...args: string[]) { + reporter?.('warning', args.join()); + }, + error(...args: string[]) { + reporter?.('error', args.join()); + }, + }; +} + export default function (api: unknown, options: ApplicationPresetOptions) { const presets = []; const plugins = []; let needRuntimeTransform = false; + if (options.angularLinker) { + // Babel currently is synchronous so import cannot be used + const { + createEs2015LinkerPlugin, + } = require('@angular/compiler-cli/linker/babel'); + + plugins.push(createEs2015LinkerPlugin({ + logger: createNgtscLogger(options.diagnosticReporter), + fileSystem: { + resolve: path.resolve, + exists: fs.existsSync, + dirname: path.dirname, + relative: path.relative, + readFile: fs.readFileSync, + }, + })); + } + if (options.forceES5) { presets.push([ require('@babel/preset-env').default, diff --git a/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts b/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts new file mode 100644 index 000000000000..8dfe97b1481f --- /dev/null +++ b/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts @@ -0,0 +1,120 @@ +/** + * @license + * Copyright Google Inc. 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 { custom } from 'babel-loader'; + +interface AngularCustomOptions { + forceES5: boolean; + shouldLink: boolean; +} + +/** + * Cached linker check utility function + * + * If undefined, not yet been imported + * If null, attempted import failed and no linker support + * If function, import succeeded and linker supported + */ +let needsLinking: undefined | null | typeof import('@angular/compiler-cli/linker').needsLinking; + +async function checkLinking( + path: string, + source: string, +): Promise<{ hasLinkerSupport?: boolean; requiresLinking: boolean }> { + // @angular/core and @angular/compiler will cause false positives + if (/[\\\/]@angular[\\\/](?:compiler|core)/.test(path)) { + return { requiresLinking: false }; + } + + if (needsLinking !== null) { + try { + if (needsLinking === undefined) { + needsLinking = (await import('@angular/compiler-cli/linker')).needsLinking; + } + + // If the linker entry point is present then there is linker support + return { hasLinkerSupport: true, requiresLinking: needsLinking(path, source) }; + } catch { + needsLinking = null; + } + } + + // Fallback for Angular versions less than 11.1.0 with no linker support. + // This information is used to issue errors if a partially compiled library is used when unsupported. + return { + hasLinkerSupport: false, + requiresLinking: + source.includes('ɵɵngDeclareDirective') || source.includes('ɵɵngDeclareComponent'), + }; +} + +export default custom(() => { + const baseOptions = Object.freeze({ + babelrc: false, + configFile: false, + compact: false, + cacheCompression: false, + sourceType: 'unambiguous', + }); + + return { + async customOptions({ forceES5, ...loaderOptions }, { source }) { + let shouldProcess = forceES5; + + let shouldLink = false; + const { hasLinkerSupport, requiresLinking } = await checkLinking(this.resourcePath, source); + if (requiresLinking && !hasLinkerSupport) { + // Cannot link if there is no linker support + this.emitError( + 'File requires the Angular linker. "@angular/compiler-cli" version 11.1.0 or greater is needed.', + ); + } else { + shouldLink = requiresLinking; + } + shouldProcess ||= shouldLink; + + const options: Record = { + ...baseOptions, + ...loaderOptions, + }; + + if (!shouldProcess) { + // Force the current file to be ignored + options.ignore = [() => true]; + } + + return { custom: { forceES5: !!forceES5, shouldLink }, loader: options }; + }, + config(configuration, { customOptions }) { + return { + ...configuration.options, + presets: [ + ...(configuration.options.presets || []), + [ + require('./presets/application').default, + { + angularLinker: customOptions.shouldLink, + forceES5: customOptions.forceES5, + diagnosticReporter: (type, message) => { + switch (type) { + case 'error': + this.emitError(message); + break; + case 'info': + // Webpack does not currently have an informational diagnostic + case 'warning': + this.emitWarning(message); + break; + } + }, + } as import('./presets/application').ApplicationPresetOptions, + ], + ], + }; + }, + }; +}); diff --git a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts index 61f694532a96..b56e6a80bcda 100644 --- a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts +++ b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts @@ -544,35 +544,19 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { sideEffects: true, }, { - test: /\.m?js$/, + test: /\.[cm]?js$/, exclude: [/[\/\\](?:core-js|\@babel|tslib|web-animations-js)[\/\\]/, /(ngfactory|ngstyle)\.js$/], use: [ - ...(wco.supportES2015 - ? [] - : [ - { - loader: require.resolve('babel-loader'), - options: { - babelrc: false, - configFile: false, - compact: false, - cacheCompression: false, - cacheDirectory: findCachePath('babel-webpack'), - cacheIdentifier: JSON.stringify({ - buildAngular: require('../../../package.json').version, - }), - sourceType: 'unambiguous', - presets: [ - [ - require.resolve('../../babel/presets/application'), - { - forceES5: true, - } as import('../../babel/presets/application').ApplicationPresetOptions, - ], - ], - }, - }, - ]), + { + loader: require.resolve('../../babel/webpack-loader'), + options: { + cacheDirectory: findCachePath('babel-webpack'), + cacheIdentifier: JSON.stringify({ + buildAngular: require('../../../package.json').version, + }), + forceES5: !wco.supportES2015, + }, + }, ...buildOptimizerUseRule, ], }, From 1cf2e95c855cd80b86a1a00f0b0d8d45922d24ec Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 6 Jan 2021 10:30:14 -0500 Subject: [PATCH 2/3] test(@angular-devkit/build-angular): add AOT partial compilation E2E test This adds a new E2E test that creates a library, converts it to use partial AOT compilation (linker mode), and integrates the library into an application. This provides a full workflow test of the new method to produce a publishable Angular library. --- .../library/library-consumption-linker.ts | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 tests/legacy-cli/e2e/tests/generate/library/library-consumption-linker.ts diff --git a/tests/legacy-cli/e2e/tests/generate/library/library-consumption-linker.ts b/tests/legacy-cli/e2e/tests/generate/library/library-consumption-linker.ts new file mode 100644 index 000000000000..50ee19927c51 --- /dev/null +++ b/tests/legacy-cli/e2e/tests/generate/library/library-consumption-linker.ts @@ -0,0 +1,108 @@ +import { writeFile } from '../../../utils/fs'; +import { getActivePackageManager } from '../../../utils/packages'; +import { ng, silentYarn } from '../../../utils/process'; +import { updateJsonFile } from '../../../utils/project'; +import { getGlobalVariable } from '../../../utils/env'; + +export default async function () { + if ((getGlobalVariable('argv')['ve'])) { + // Does not apply to ViewEngine + return; + } + + await ng('generate', 'library', 'my-lib'); + + // Ensure webdriver is present for E2E (yarn will remove any downloaded drivers) + if (getActivePackageManager() === 'yarn') { + await silentYarn('run', 'webdriver-update'); + } + + // Enable partial compilation mode (linker) for the library + // Enable ivy for production as well (current schematic disables ivy in production) + await updateJsonFile('projects/my-lib/tsconfig.lib.prod.json', config => { + const { angularCompilerOptions = {} } = config; + angularCompilerOptions.enableIvy = true; + angularCompilerOptions.compilationMode = 'partial'; + config.angularCompilerOptions = angularCompilerOptions; + }); + + await writeFile('./src/app/app.module.ts', ` + import { BrowserModule } from '@angular/platform-browser'; + import { NgModule } from '@angular/core'; + import { MyLibModule } from 'my-lib'; + + import { AppComponent } from './app.component'; + + @NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule, + MyLibModule, + ], + providers: [], + bootstrap: [AppComponent] + }) + export class AppModule { } + `); + + await writeFile('./src/app/app.component.ts', ` + import { Component } from '@angular/core'; + import { MyLibService } from 'my-lib'; + + @Component({ + selector: 'app-root', + template: '' + }) + export class AppComponent { + title = 'app'; + + constructor(myLibService: MyLibService) { + console.log(myLibService); + } + } + `); + + await writeFile('e2e/src/app.e2e-spec.ts', ` + import { browser, logging, element, by } from 'protractor'; + import { AppPage } from './app.po'; + + describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display text from library component', async () => { + await page.navigateTo(); + expect(await element(by.css('lib-my-lib p')).getText()).toEqual('my-lib works!'); + }); + + afterEach(async () => { + // Assert that there are no errors emitted from the browser + const logs = await browser.manage().logs().get(logging.Type.BROWSER); + expect(logs).not.toContain(jasmine.objectContaining({ + level: logging.Level.SEVERE, + })); + }); + }); + `); + + await runLibraryTests(); + await runLibraryTests(true); +} + +async function runLibraryTests(prodMode = false): Promise { + const args = ['build', 'my-lib']; + if (prodMode) { + args.push('--prod'); + } + + await ng(...args); + + // Check that the tests succeeds both with named project, unnamed (should test app), and prod. + await ng('e2e'); + await ng('e2e', 'test-project', '--devServerTarget=test-project:serve:production'); +} From 778f95e413c3a953f6a9068c81fe6f6d31dc3c06 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 7 Jan 2021 12:45:45 -0500 Subject: [PATCH 3/3] build: update development versions of Angular to 11.1.0-next.4 --- package.json | 24 +++---- packages/ngtools/webpack/package.json | 4 +- yarn.lock | 96 +++++++++++++-------------- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/package.json b/package.json index dd9d9e999cb6..1feb3d94afbf 100644 --- a/package.json +++ b/package.json @@ -64,21 +64,21 @@ ] }, "devDependencies": { - "@angular/animations": "11.1.0-next.3", + "@angular/animations": "11.1.0-next.4", "@angular/cdk": "11.0.3", - "@angular/common": "11.1.0-next.3", - "@angular/compiler": "11.1.0-next.3", - "@angular/compiler-cli": "11.1.0-next.3", - "@angular/core": "11.1.0-next.3", + "@angular/common": "11.1.0-next.4", + "@angular/compiler": "11.1.0-next.4", + "@angular/compiler-cli": "11.1.0-next.4", + "@angular/core": "11.1.0-next.4", "@angular/dev-infra-private": "https://github.com/angular/dev-infra-private-builds.git#8cfa1d0e3a36bad2e34ad6c0795cac6bc3816d72", - "@angular/forms": "11.1.0-next.3", - "@angular/localize": "11.1.0-next.3", + "@angular/forms": "11.1.0-next.4", + "@angular/localize": "11.1.0-next.4", "@angular/material": "11.0.3", - "@angular/platform-browser": "11.1.0-next.3", - "@angular/platform-browser-dynamic": "11.1.0-next.3", - "@angular/platform-server": "11.1.0-next.3", - "@angular/router": "11.1.0-next.3", - "@angular/service-worker": "11.1.0-next.3", + "@angular/platform-browser": "11.1.0-next.4", + "@angular/platform-browser-dynamic": "11.1.0-next.4", + "@angular/platform-server": "11.1.0-next.4", + "@angular/router": "11.1.0-next.4", + "@angular/service-worker": "11.1.0-next.4", "@babel/core": "7.12.10", "@babel/generator": "7.12.11", "@babel/plugin-transform-runtime": "7.12.10", diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index e801f8fde6f1..b024d1a60fa0 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -31,8 +31,8 @@ "webpack": "^4.0.0" }, "devDependencies": { - "@angular/compiler": "11.1.0-next.3", - "@angular/compiler-cli": "11.1.0-next.3", + "@angular/compiler": "11.1.0-next.4", + "@angular/compiler-cli": "11.1.0-next.4", "typescript": "4.1.3", "webpack": "4.44.2" } diff --git a/yarn.lock b/yarn.lock index f2b7616153fd..0e22ddc44f16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@angular/animations@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-11.1.0-next.3.tgz#428361bac55260b923b26c82026d2e30c6d6822a" - integrity sha512-urEdMTXc+3gMluZgkAGUa4vL42PITPLSh6CNdBFHVSxA6mCGP+jGtwyYzQgpxn53KnYBRSB0dpWLUOXwyRS1kQ== +"@angular/animations@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-11.1.0-next.4.tgz#dea9d08a3d62c302f9c12c5064ab8adc6f2db228" + integrity sha512-ZwNyimfkhT029JvRSNnmflBGIGU8kR38yQsD1h4u4ypPwdoxYWonvI6mAbnRHAa85WG3qA8Fb8HA3kKuAXYDag== dependencies: tslib "^2.0.0" @@ -26,17 +26,17 @@ optionalDependencies: parse5 "^5.0.0" -"@angular/common@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-11.1.0-next.3.tgz#740db1edadcb03b6a120b41f6533e5b98ff8850a" - integrity sha512-VgMEr2V8lkdRWUYHlQ3sl+hL28IsvSrlfGnEuy7fJFZGGnB6/JSfmRgOi3DQ/51Dz3sp7bBGWlxyg/zYxZa3vg== +"@angular/common@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-11.1.0-next.4.tgz#e5602ac8f1df0eaa0f403383be4921c663765f14" + integrity sha512-O5tFWJl6yr45mvy84onR/gUYfxTqP10Pv2/0MJbLF/L3R1sK5LwBHg69SB6y8mdma/kwOMvemUK3lt9k9SrQQQ== dependencies: tslib "^2.0.0" -"@angular/compiler-cli@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-11.1.0-next.3.tgz#eb883f2d5f94a24f1c22198107a8d1121e7e37b3" - integrity sha512-2czfPRY6cevuprGG8HwPhqG5E4Oc9H2ejYFhNkTfnft27WHbMkekhxMIgay5XBE1e9hAWlyAN1gWkq1TJPqgfg== +"@angular/compiler-cli@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-11.1.0-next.4.tgz#feaada877589cdabbcc687e939ffde4393293605" + integrity sha512-E1/6e0JS3Saj9nG12eo8q0zJJXlbwtPyuWOVK7EK57OJdF6PsYIAf9g93TKk2QA+iimbNklconj/2LQj9cCGMQ== dependencies: "@babel/core" "^7.8.6" "@babel/types" "^7.8.6" @@ -54,10 +54,10 @@ tslib "^2.0.0" yargs "^16.1.1" -"@angular/compiler@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-11.1.0-next.3.tgz#5febc73f6e7eeaf5fd0ec149edb68b3d00fcf9ec" - integrity sha512-9OM3w3iOhDHDD1l3mYDvFGJ7A7y83VBRLn/+/jE/gOU9bOUurhGhXkd7UaGqKp5+jd6O5EliYqcLI2DVmQ36Gg== +"@angular/compiler@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-11.1.0-next.4.tgz#abf575efdec0fcc76cc15205431e460ed4063953" + integrity sha512-RP2kXZsPxtHPfAngYz0TPkGBQlJxD0CIC0+Gn3Ck2axSAWGCwRCuiozK9NVEIOzKT3VNtFZB9+esYzSYawcr2w== dependencies: tslib "^2.0.0" @@ -66,10 +66,10 @@ resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.0.tgz#87e0bef4c369b6cadae07e3a4295778fc93799d5" integrity sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ== -"@angular/core@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-11.1.0-next.3.tgz#64ceb9a6717840f4c83d13d97068a6620e9a2a7e" - integrity sha512-dFJSUx/PyTk0gUIDV0BQ0WOhkHZH1bdK+FeM5E3vzMsvl08P4+fkpc4B60z8X1Nc3m8rsJyCA+oy8qR9LuLwPg== +"@angular/core@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-11.1.0-next.4.tgz#d7bfc8e77f7bddcad40b45d52679d2eec5cbc049" + integrity sha512-2fsArpeyIDiZa2jjhj+FFCS+Rgj2+D3CoRUcAXNly+SVEL+yR8fZSCsBsFHFbReQnrAE/XvU0N63Q2jD3m56Yw== dependencies: tslib "^2.0.0" @@ -117,17 +117,17 @@ yaml "^1.10.0" yargs "^16.1.1" -"@angular/forms@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-11.1.0-next.3.tgz#aa174476c91cf8f0e55d597c5f05ceca56f98489" - integrity sha512-LPI+Yti6zi4kgAIgTopQeCSN7Q3cXGWai/CRnkAGHm0glaXo16N8imUdNNwOS9S6mi2Nb+vU6VU9MfjtA/C4uQ== +"@angular/forms@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-11.1.0-next.4.tgz#c5a4b516aeadf6c3672c33595b66b04ae1050b4f" + integrity sha512-ZkW8bsYPL8C10RjhwdU1G07TVWyxxfHzzlLORFZ3CQgXoZtXBNTh0P7VDw44ZDLHmfwuksxryYVHTTrCeGQPew== dependencies: tslib "^2.0.0" -"@angular/localize@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-11.1.0-next.3.tgz#9ebc26c8dc55d62c7c4f2a1e9149aa828244f289" - integrity sha512-7xfusCwQCGK/kzQiNlqS3yzMpF2SGsh4W2ZRultjnZhJ8zZAihEai7Lp7nfWViUNGNsGTeIOTQOQH2sP9G7t2Q== +"@angular/localize@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-11.1.0-next.4.tgz#124671437a4b43a1d70e824abedb04c9fe64d656" + integrity sha512-PCV+gzszB3OMHyWhAgDy9QSZCXlTXmhUYWy/4FGvc37LzRTFj+6U74y7mFIt3AXX547a3WbBU5/VLQw+ykhHBQ== dependencies: "@babel/core" "7.8.3" glob "7.1.2" @@ -140,40 +140,40 @@ dependencies: tslib "^2.0.0" -"@angular/platform-browser-dynamic@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-11.1.0-next.3.tgz#ab88416f8e5e413d60a57b701d0e35c2bbd125b1" - integrity sha512-3pomuouEluaVQDICrbdtC0tSlawpwIb6fAqMutx+5PobTkMfjXx938A7P1RmVIKuIyj0HTLKqpnMrSESnDRKrw== +"@angular/platform-browser-dynamic@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-11.1.0-next.4.tgz#b77709cd540affe41b23b38f941c75b9f3efda9d" + integrity sha512-RyLrIKFbSBxtERnZkZ1nOn4912JmuFjOdU83b+j22DWBmMJVi4+aWYZcjJPSnjLTrKMwvpDIGwS95+GcNL8Gww== dependencies: tslib "^2.0.0" -"@angular/platform-browser@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-11.1.0-next.3.tgz#8125367ef37f69b28503b51dd6420ab34cb171f9" - integrity sha512-HFtDSe8y3rBOZAk1xSyB290rLRFry63an6i2lK7Cr5njqGp9SP61Zqgt2AjXASj2zYRYAuK45xYUJ3YAiZfckA== +"@angular/platform-browser@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-11.1.0-next.4.tgz#dbf902fb7034bd89b77369c28ac76dfd800d45af" + integrity sha512-y8rvqieQHXTgXtrJcjsYLIVYE5wAxSpLZ66M5/pbnO/cxtl+UUQRfUVpNOFO8ZvCZyzF/6cgcUw2/bm7GxdW8A== dependencies: tslib "^2.0.0" -"@angular/platform-server@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-11.1.0-next.3.tgz#c086342be68f1247af0f74bfe9352726079dafc3" - integrity sha512-aMgJGrO4JGc2L99leXW+juBvQfjin9E/6sF9CY87qrznoAVz/pImyhAfoGLNptZsJseArYBYKXnDQvlFShk46g== +"@angular/platform-server@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-11.1.0-next.4.tgz#ea1f25c0034e970bc74a0b1b26c59e7a4cefb143" + integrity sha512-RSYx2D/g4Pn33JUQIdGEmXDWYiztZH+tqes2408msWiq9PNXd4JHdmamHNS/dnCB/OMoxtFG2N++jz10bbhEqQ== dependencies: domino "^2.1.2" tslib "^2.0.0" xhr2 "^0.2.0" -"@angular/router@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-11.1.0-next.3.tgz#19967c8f0ed696c98ff553ae57cc3434ac2d92af" - integrity sha512-uGhVVyEYKuWFOnbsbi5hki3JxHSFTfwU3UEEco8OPHPBcO6XNYPbYVq8JOs1/5btwFGGygJsKKAVXBDOeCPyAg== +"@angular/router@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-11.1.0-next.4.tgz#1204848b79f97503da6f4a2cfe0dd6f9bd0046db" + integrity sha512-l4LW1/BHTBihV9+d2KYOmvTJZUS75JdXziB7iNCGp7ZBRD51YDr8rbBHQnQTYVE8lFi5y6uzZonkrHVEm9CKWQ== dependencies: tslib "^2.0.0" -"@angular/service-worker@11.1.0-next.3": - version "11.1.0-next.3" - resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-11.1.0-next.3.tgz#9d0a0be09655cc47537d74a51b2014c95384745d" - integrity sha512-O5TAAzBDCXWgsAx4m8vN6eL0kSXzSgQii9Vm1XXm3gTyoua3Xs7XJfvChSiYX2OT75p1aY5hwyh1ncp2IMyPvQ== +"@angular/service-worker@11.1.0-next.4": + version "11.1.0-next.4" + resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-11.1.0-next.4.tgz#58af6e3e47866d718ec8ad710bb4ff55833ec3f5" + integrity sha512-fpL6bXGc5QAIx3tphkgXntYB4OHSUek7zlAJTM8MPgiVrdCErpjLUufATYII+34X0blgZ1AarpWwpI/MOZUMiA== dependencies: tslib "^2.0.0"