From feb06753d59f782c6ad8fd59a60537863094f498 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 30 Aug 2022 09:34:29 -0400 Subject: [PATCH] perf(@angular-devkit/build-angular): use esbuild-based builder to directly downlevel for await...of esbuild 0.15.6 now supports transforming `for await..of` syntax and will now be used instead of babel when the syntax is found within code that will be bundled. Zone.js requires that all async/await related code be downleveled to properly hook promise callbacks. esbuild does not yet support transforming async generators and so babel is still used when async generator syntax is detected in an input file. esbuild 0.15.6 also adjusted the `supported` option to imply that all dependent features of a disabled feature are disabled as well. For the CLI, this allows only needing to specify that `async-await` is disabled in the esbuild options. --- .../src/builders/browser-esbuild/compiler-plugin.ts | 5 ++--- .../src/builders/browser-esbuild/index.ts | 12 ++++-------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/browser-esbuild/compiler-plugin.ts b/packages/angular_devkit/build_angular/src/builders/browser-esbuild/compiler-plugin.ts index 40fbe0129d98..30b5e829ada5 100644 --- a/packages/angular_devkit/build_angular/src/builders/browser-esbuild/compiler-plugin.ts +++ b/packages/angular_devkit/build_angular/src/builders/browser-esbuild/compiler-plugin.ts @@ -342,7 +342,7 @@ export function createCompilerPlugin( } const data = typescriptResult.content ?? ''; - const forceAsyncTransformation = /for\s+await\s*\(|async\s+function\s*\*/.test(data); + const forceAsyncTransformation = /async\s+function\s*\*/.test(data); const useInputSourcemap = pluginOptions.sourcemap && (!!pluginOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(args.path)); @@ -388,8 +388,7 @@ export function createCompilerPlugin( build.onLoad({ filter: /\.[cm]?js$/ }, async (args) => { const data = await fs.readFile(args.path, 'utf-8'); const forceAsyncTransformation = - !/[\\/][_f]?esm2015[\\/]/.test(args.path) && - /for\s+await\s*\(|async\s+function\s*\*/.test(data); + !/[\\/][_f]?esm2015[\\/]/.test(args.path) && /async\s+function\s*\*/.test(data); const shouldLink = await requiresLinking(args.path, data); const useInputSourcemap = pluginOptions.sourcemap && diff --git a/packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts b/packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts index 2a2395337d4e..cf87992d5d76 100644 --- a/packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts @@ -259,15 +259,11 @@ async function bundleCode( target: 'es2020', supported: { // Native async/await is not supported with Zone.js. Disabling support here will cause - // esbuild to downlevel async/await to a Zone.js supported form. + // esbuild to downlevel async/await and for await...of to a Zone.js supported form. However, esbuild + // does not currently support downleveling async generators. Instead babel is used within the JS/TS + // loader to perform the downlevel transformation. + // NOTE: If esbuild adds support in the future, the babel support for async generators can be disabled. 'async-await': false, - // Zone.js also does not support async generators or async iterators. However, esbuild does - // not currently support downleveling either of them. Instead babel is used within the JS/TS - // loader to perform the downlevel transformation. They are both disabled here to allow - // esbuild to handle them in the future if support is ever added. - // NOTE: If esbuild adds support in the future, the babel support for these can be disabled. - 'async-generator': false, - 'for-await': false, }, mainFields: ['es2020', 'browser', 'module', 'main'], conditions: ['es2020', 'es2015', 'module'],