diff --git a/devtools/tools/defaults.bzl b/devtools/tools/defaults.bzl index 97aa500969f..607ce21ef69 100644 --- a/devtools/tools/defaults.bzl +++ b/devtools/tools/defaults.bzl @@ -1,36 +1,8 @@ # Re-export of Bazel rules with devtools-wide defaults -load("@npm//@angular/build-tooling/bazel/spec-bundling:index.bzl", "spec_bundle") -load("@npm//@angular/build-tooling/bazel/karma:index.bzl", _karma_web_test_suite = "karma_web_test_suite") -load("@npm//@angular/build-tooling/bazel:extract_js_module_output.bzl", "extract_js_module_output") +load("//tools:defaults.bzl", _karma_web_test_suite = "karma_web_test_suite") def karma_web_test_suite(name, **kwargs): - test_deps = kwargs.get("deps", []) - kwargs["deps"] = ["%s_bundle" % name] - - # TODO(ESM): Remove this when devmode & prodmode are combined. - extract_js_module_output( - name = "%s_prodmode_deps" % name, - deps = test_deps, - provider = "JSEcmaScriptModuleInfo", - forward_linker_mappings = True, - include_external_npm_packages = True, - include_default_files = False, - include_declarations = True, - testonly = True, - ) - - spec_bundle( - name = "%s_bundle" % name, - deps = ["%s_prodmode_deps" % name], - platform = "browser", - run_angular_linker = True, - # We consume the Angular framework packages directly from source. The - # placeholders might not be substituted and still use `0.0.0-PLACEHOLDER`. - linker_unknown_declaration_handling = "ignore", - workspace_name = "angular", - ) - # Set up default browsers if no explicit `browsers` have been specified. if not hasattr(kwargs, "browsers"): kwargs["tags"] = ["native"] + kwargs.get("tags", []) @@ -44,8 +16,5 @@ def karma_web_test_suite(name, **kwargs): # Default test suite with all configured browsers. _karma_web_test_suite( name = name, - bootstrap = [ - "@npm//:node_modules/tslib/tslib.js", - ], **kwargs ) diff --git a/devtools/tools/esbuild/BUILD.bazel b/devtools/tools/esbuild/BUILD.bazel index 646c74ae70f..b770354e3e3 100644 --- a/devtools/tools/esbuild/BUILD.bazel +++ b/devtools/tools/esbuild/BUILD.bazel @@ -1,11 +1,16 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//tools:defaults.bzl", "esbuild_config") load(":index.bzl", "create_angular_bundle_targets") package(default_visibility = ["//visibility:public"]) -esbuild_config( +js_library( name = "esbuild_base", - config_file = "esbuild-base.config.mjs", + srcs = ["esbuild-base.config.mjs"], + deps = [ + "//packages/compiler-cli/private", + "@npm//@angular/build-tooling/shared-scripts/angular-optimization:js_lib", + ], ) esbuild_config( @@ -13,7 +18,7 @@ esbuild_config( config_file = "esbuild-esm.config.mjs", deps = [ ":esbuild_base", - "@npm//@angular/build-tooling/shared-scripts/angular-linker:js_lib", + "@npm//@angular/build-tooling/shared-scripts/angular-optimization:js_lib", ], ) @@ -22,9 +27,6 @@ esbuild_config( config_file = "esbuild-esm-prod.config.mjs", deps = [ ":esbuild_base", - "//packages/compiler-cli/private", - "@npm//@angular/build-tooling/shared-scripts/angular-linker:js_lib", - "@npm//@angular/build-tooling/shared-scripts/angular-optimization:js_lib", ], ) @@ -42,7 +44,6 @@ esbuild_config( config_file = "esbuild-spec.config.mjs", deps = [ ":esbuild_base", - "@npm//@angular/build-tooling/shared-scripts/angular-linker:js_lib", ], ) diff --git a/devtools/tools/esbuild/esbuild-base.config.mjs b/devtools/tools/esbuild/esbuild-base.config.mjs index a0baa8d57bd..c33e2b8e5b9 100644 --- a/devtools/tools/esbuild/esbuild-base.config.mjs +++ b/devtools/tools/esbuild/esbuild-base.config.mjs @@ -6,10 +6,57 @@ * found in the LICENSE file at https://angular.io/license */ -export default { - resolveExtensions: ['.mjs', '.js'], - // This ensures that we prioritize ES2020. RxJS would otherwise use the ESM5 output. - mainFields: ['es2020', 'es2015', 'module', 'main'], - // `tslib` sets the `module` condition to resolve to ESM. - conditions: ['es2020', 'es2015', 'module'] -}; +import {createEsbuildAngularOptimizePlugin} from '@angular/build-tooling/shared-scripts/angular-optimization/esbuild-plugin.mjs'; +import {GLOBAL_DEFS_FOR_TERSER_WITH_AOT} from '@angular/compiler-cli/private/tooling.js'; + +/** Converts an object to a string dictionary. */ +function convertObjectToStringDictionary(value) { + return Object.entries(value).reduce((result, [propName, value]) => { + result[propName] = String(value); + return result; + }, {}); +} + +export default async function createConfig({enableLinker, optimize}) { + return { + resolveExtensions: ['.mjs', '.js'], + // This ensures that we prioritize ES2020. RxJS would otherwise use the ESM5 output. + mainFields: ['es2020', 'es2015', 'module', 'main'], + // `tslib` sets the `module` condition to resolve to ESM. + conditions: ['es2020', 'es2015', 'module'], + supported: { + // Downlevel native `async/await` so that ZoneJS can intercept it. + 'async-await': false, + }, + define: optimize ? convertObjectToStringDictionary(GLOBAL_DEFS_FOR_TERSER_WITH_AOT) : undefined, + plugins: [ + await createEsbuildAngularOptimizePlugin({ + optimize: { + isSideEffectFree: null, + }, + downlevelAsyncGeneratorsIfPresent: true, + enableLinker: enableLinker + ? { + ensureNoPartialDeclaration: false, + // Only run the linker on `fesm2020/` bundles. This should not have an effect on + // the bundle output, but helps speeding up ESBuild when it visits other modules. + filterPaths: /fesm2020/, + linkerOptions: { + // DevTools relies on angular framework packages that are consumed, + // locally via bazel. These packages have a version of 0.0.0-PLACEHOLDER. + // DevTools also relies on Angular CDK and Material packages that are consumed via npm. + // Because of this, we set unknownDeclarationVersionHandling to ignore so that we bypass + // selecting a linker for our CDK and Material dependencies based on our local framework + // version (0.0.0-PLACEHOLDER). + // Instead this option defaults to the latest linker version, which should + // be correct, except for the small time interval where we rollout a new + // declaration version and target a material release that hasn't been compiled + // with that version yet. + unknownDeclarationVersionHandling: 'ignore', + }, + } + : undefined, + }), + ], + }; +} diff --git a/devtools/tools/esbuild/esbuild-esm-prod.config.mjs b/devtools/tools/esbuild/esbuild-esm-prod.config.mjs index f335035a538..b156801b4f4 100644 --- a/devtools/tools/esbuild/esbuild-esm-prod.config.mjs +++ b/devtools/tools/esbuild/esbuild-esm-prod.config.mjs @@ -6,42 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import { createLinkerEsbuildPlugin } from '@angular/build-tooling/shared-scripts/angular-linker/esbuild-plugin.mjs'; -import { createEsbuildAngularOptimizePlugin } from '@angular/build-tooling/shared-scripts/angular-optimization/esbuild-plugin.mjs'; -import { GLOBAL_DEFS_FOR_TERSER_WITH_AOT } from '@angular/compiler-cli/private/tooling.js'; -import baseEsbuildConfig from './esbuild-base.config.mjs'; +import createConfig from './esbuild-base.config.mjs'; export default { - ...baseEsbuildConfig, + ...createConfig({enableLinker: true, optimize: true}), format: 'esm', - plugins: [ - // Only run the linker on `fesm2020/` bundles. This should not have an effect on - // the bundle output, but helps speeding up ESBuild when it visits other modules. - await createLinkerEsbuildPlugin( - /fesm2020/, - /* ensureNoPartialDeclaration */ false, - - // DevTools relies on angular framework packages that are consumed, - // locally via bazel. These packages have a version of 0.0.0-PLACEHOLDER. - // DevTools also relies on Angular CDK and Material packages that are consumed via npm. - // Because of this, we set unknownDeclarationVersionHandling to ignore so that we bypass - // selecting a linker for our CDK and Material dependencies based on our local framework - // version (0.0.0-PLACEHOLDER). - // Instead this option defaults to the latest linker version, which should - // be correct, except for the small time interval where we rollout a new - // declaration version and target a material release that hasn't been compiled - // with that version yet. - { unknownDeclarationVersionHandling: 'ignore' } - ), - await createEsbuildAngularOptimizePlugin() - ], - define: convertObjectToStringDictionary(GLOBAL_DEFS_FOR_TERSER_WITH_AOT), }; - -/** Converts an object to a string dictionary. */ -function convertObjectToStringDictionary(value) { - return Object.entries(value).reduce((result, [propName, value]) => { - result[propName] = String(value); - return result; - }, {}); -} diff --git a/devtools/tools/esbuild/esbuild-esm.config.mjs b/devtools/tools/esbuild/esbuild-esm.config.mjs index 42cdce8aa43..a8f0ea7f3e8 100644 --- a/devtools/tools/esbuild/esbuild-esm.config.mjs +++ b/devtools/tools/esbuild/esbuild-esm.config.mjs @@ -6,30 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {createLinkerEsbuildPlugin} from '@angular/build-tooling/shared-scripts/angular-linker/esbuild-plugin.mjs'; -import baseEsbuildConfig from './esbuild-base.config.mjs'; +import createConfig from './esbuild-base.config.mjs'; export default { - ...baseEsbuildConfig, + ...createConfig({enableLinker: true, optimize: false}), format: 'esm', - plugins: [ - // Only run the linker on `fesm2020/` bundles. This should not have an effect on - // the bundle output, but helps speeding up ESBuild when it visits other modules. - await createLinkerEsbuildPlugin( - /fesm2020/, - /* ensureNoPartialDeclaration */ false, - - // DevTools relies on angular framework packages that are consumed, - // locally via bazel. These packages have a version of 0.0.0-PLACEHOLDER. - // DevTools also relies on Angular CDK and Material packages that are consumed via npm. - // Because of this, we set unknownDeclarationVersionHandling to ignore so that we bypass - // selecting a linker for our CDK and Material dependencies based on our local framework - // version (0.0.0-PLACEHOLDER). - // Instead this option defaults to the latest linker version, which should - // be correct, except for the small time interval where we rollout a new - // declaration version and target a material release that hasn't been compiled - // with that version yet. - { unknownDeclarationVersionHandling: 'ignore' } - ), - ], }; diff --git a/devtools/tools/esbuild/esbuild-iife.config.mjs b/devtools/tools/esbuild/esbuild-iife.config.mjs index b603afcbbe2..db01b20c5d6 100644 --- a/devtools/tools/esbuild/esbuild-iife.config.mjs +++ b/devtools/tools/esbuild/esbuild-iife.config.mjs @@ -6,9 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import baseEsbuildConfig from './esbuild-base.config.mjs'; +import createConfig from './esbuild-base.config.mjs'; export default { - ...baseEsbuildConfig, - format: 'iife' + ...createConfig({enableLinker: false, optimize: false}), + format: 'iife', }; diff --git a/devtools/tools/esbuild/esbuild-spec.config.mjs b/devtools/tools/esbuild/esbuild-spec.config.mjs index 5f0d4ad37e4..e5a728ee005 100644 --- a/devtools/tools/esbuild/esbuild-spec.config.mjs +++ b/devtools/tools/esbuild/esbuild-spec.config.mjs @@ -6,46 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import baseEsbuildConfig from './esbuild-base.config.mjs'; - -/** - * Loads and creates the ESBuild linker plugin. - * - * The plugin is not loaded at top-level as not all spec bundle targets rely - * on the linker and this would slow-down bundling. - */ - async function fetchAndCreateLinkerEsbuildPlugin() { - // Note: This needs to be a NPM module path as this ESBuild config is generated and can - // end up in arbitrary Bazel packages or differently-named consumer workspaces. - const {createLinkerEsbuildPlugin} = await import( - '@angular/build-tooling/shared-scripts/angular-linker/esbuild-plugin.mjs' - ); - - return await createLinkerEsbuildPlugin( - /.*/, - /* ensureNoPartialDeclaration */ true, - - // DevTools relies on angular framework packages that are consumed, - // locally via bazel. These packages have a version of 0.0.0-PLACEHOLDER. - // DevTools also relies on Angular CDK and Material packages that are consumed via npm. - // Because of this, we set unknownDeclarationVersionHandling to ignore so that we bypass - // selecting a linker for our CDK and Material dependencies based on our local framework - // version (0.0.0-PLACEHOLDER). - // Instead this option defaults to the latest linker version, which should - // be correct, except for the small time interval where we rollout a new - // declaration version and target a Material release that hasn't been compiled - // with that version yet - { unknownDeclarationVersionHandling: 'ignore' } - ); -} - -// Based on the Bazel action and its substitutions, we run the linker for all inputs. -const plugins = [await fetchAndCreateLinkerEsbuildPlugin()]; +import createConfig from './esbuild-base.config.mjs'; export default { - ...baseEsbuildConfig, + ...createConfig({enableLinker: true, optimize: false}), // Use the `iife` format for the test entry-point as tests should run immediately. // For browser tests which are wrapped in an AMD header and footer, this works as well. format: 'iife', - plugins, }; diff --git a/tools/defaults.bzl b/tools/defaults.bzl index 6b7b95c5b65..5b6992ea0b7 100644 --- a/tools/defaults.bzl +++ b/tools/defaults.bzl @@ -295,7 +295,14 @@ def pkg_npm(name, validate = True, use_prodmode_output = False, **kwargs): visibility = visibility, ) -def karma_web_test_suite(name, external = [], **kwargs): +def karma_web_test_suite( + name, + external = [], + browsers = [ + "@npm//@angular/build-tooling/bazel/browsers/chromium:chromium", + "@npm//@angular/build-tooling/bazel/browsers/firefox:firefox", + ], + **kwargs): """Default values for karma_web_test_suite""" # Default value for bootstrap @@ -322,10 +329,7 @@ def karma_web_test_suite(name, external = [], **kwargs): _karma_web_test_suite( name = name, deps = [":%s_bundle" % name], - browsers = [ - "@npm//@angular/build-tooling/bazel/browsers/chromium:chromium", - "@npm//@angular/build-tooling/bazel/browsers/firefox:firefox", - ], + browsers = browsers, data = data, tags = tags, **kwargs