File tree

1 file changed

+52
-13
lines changed
  • packages/angular_devkit/build_angular/src/builders/browser-esbuild

1 file changed

+52
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,7 @@ function createCodeBundleOptions(
253253
entryNames: outputNames.bundles,
254254
assetNames: outputNames.media,
255255
target,
256-
supported: {
257-
// Native async/await is not supported with Zone.js. Disabling support here will cause
258-
// esbuild to downlevel async/await and for await...of to a Zone.js supported form. However, esbuild
259-
// does not currently support downleveling async generators. Instead babel is used within the JS/TS
260-
// loader to perform the downlevel transformation.
261-
// NOTE: If esbuild adds support in the future, the babel support for async generators can be disabled.
262-
'async-await': false,
263-
// V8 currently has a performance defect involving object spread operations that can cause signficant
264-
// degradation in runtime performance. By not supporting the language feature here, a downlevel form
265-
// will be used instead which provides a workaround for the performance issue.
266-
// For more details: https://bugs.chromium.org/p/v8/issues/detail?id=11536
267-
'object-rest-spread': false,
268-
},
256+
supported: getFeatureSupport(target),
269257
mainFields: ['es2020', 'browser', 'module', 'main'],
270258
conditions: ['es2020', 'es2015', 'module'],
271259
resolveExtensions: ['.ts', '.tsx', '.mjs', '.js'],
@@ -314,6 +302,57 @@ function createCodeBundleOptions(
314302
};
315303
}
316304

305+
/**
306+
* Generates a syntax feature object map for Angular applications based on a list of targets.
307+
* A full set of feature names can be found here: https://esbuild..io/api/#supported
308+
* @param target An array of browser/engine targets in the format accepted by the esbuild `target` option.
309+
* @returns An object that can be used with the esbuild build `supported` option.
310+
*/
311+
function getFeatureSupport(target: string[]): BuildOptions['supported'] {
312+
const supported: Record<string, boolean> = {
313+
// Native async/await is not supported with Zone.js. Disabling support here will cause
314+
// esbuild to downlevel async/await and for await...of to a Zone.js supported form. However, esbuild
315+
// does not currently support downleveling async generators. Instead babel is used within the JS/TS
316+
// loader to perform the downlevel transformation.
317+
// NOTE: If esbuild adds support in the future, the babel support for async generators can be disabled.
318+
'async-await': false,
319+
// V8 currently has a performance defect involving object spread operations that can cause signficant
320+
// degradation in runtime performance. By not supporting the language feature here, a downlevel form
321+
// will be used instead which provides a workaround for the performance issue.
322+
// For more details: https://bugs.chromium.org/p/v8/issues/detail?id=11536
323+
'object-rest-spread': false,
324+
};
325+
326+
// Detect Safari browser versions that have a class field behavior bug
327+
// See: https://.com/angular/angular-cli/issues/24355#issuecomment-1333477033
328+
// See: https://.com/WebKit/WebKit/commit/e8788a34b3d5f5b4edd7ff6450b80936bff396f2
329+
let safariClassFieldScopeBug = false;
330+
for (const browser of target) {
331+
let majorVersion;
332+
if (browser.startsWith('ios')) {
333+
majorVersion = Number(browser.slice(3, 5));
334+
} else if (browser.startsWith('safari')) {
335+
majorVersion = Number(browser.slice(6, 8));
336+
} else {
337+
continue;
338+
}
339+
// Technically, 14.0 is not broken but rather does not have support. However, the behavior
340+
// is identical since it would be set to false by esbuild if present as a target.
341+
if (majorVersion === 14 || majorVersion === 15) {
342+
safariClassFieldScopeBug = true;
343+
break;
344+
}
345+
}
346+
// If class field support cannot be used set to false; otherwise leave undefined to allow
347+
// esbuild to use `target` to determine support.
348+
if (safariClassFieldScopeBug) {
349+
supported['class-field'] = false;
350+
supported['class-static-field'] = false;
351+
}
352+
353+
return supported;
354+
}
355+
317356
function createGlobalStylesBundleOptions(
318357
options: NormalizedBrowserOptions,
319358
target: string[],

0 commit comments

Comments
 (0)