Skip to content

Commit

Permalink
feat(bazel/spec-bundling): support specifying strategy for handling u…
Browse files Browse the repository at this point in the history
…nknown linker declarations

This is necessary to that we can use the spec bundle rule in Angular
itself where Angular packages are using `0.0.0-PLACEHOLDER`.
  • Loading branch information
devversion committed Jun 20, 2022
1 parent 5df32aa commit 04a54cd
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 7 deletions.
12 changes: 11 additions & 1 deletion bazel/spec-bundling/bundle-config.bzl
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
def _spec_bundle_config_file_impl(ctx):
run_angular_linker = ctx.attr.run_angular_linker
linker_unknown_declaration_handling = ctx.attr.linker_unknown_declaration_handling

ctx.actions.expand_template(
template = ctx.file._template,
output = ctx.outputs.output_name,
substitutions = {
"TMPL_RUN_LINKER": "true" if ctx.attr.run_angular_linker else "false",
"TMPL_RUN_LINKER": "true" if run_angular_linker else "false",
"TMPL_LINKER_UNKNOWN_DECLARATION_HANDLING": ("'%s'" % linker_unknown_declaration_handling) if linker_unknown_declaration_handling else "undefined",
},
)

Expand All @@ -19,6 +23,12 @@ spec_bundle_config_file = rule(
mandatory = True,
doc = "Name of the file where the config should be written to.",
),
"linker_unknown_declaration_handling": attr.string(
values = ["ignore", "warn", "error"],
doc = """Controls how unknown declaration versions should be handled by the Angular linker.
https://github.com/angular/angular/blob/f94c6f433dba3924b79f137cfcc49d2dfd4d679c/packages/compiler-cli/linker/src/file_linker/linker_options.ts#L27-L39.
""",
),
"_template": attr.label(
allow_single_file = True,
default = "//bazel/spec-bundling:esbuild.config-tmpl.mjs",
Expand Down
4 changes: 3 additions & 1 deletion bazel/spec-bundling/esbuild.config-tmpl.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ async function fetchAndCreateLinkerEsbuildPlugin() {
const {createLinkerEsbuildPlugin} = await import(
'@angular/dev-infra-private/shared-scripts/angular-linker/esbuild-plugin.mjs'
);
return await createLinkerEsbuildPlugin(/.*/, /* ensureNoPartialDeclaration */ true);
return await createLinkerEsbuildPlugin(/.*/, /* ensureNoPartialDeclaration */ true, {
unknownDeclarationVersionHandling: TMPL_LINKER_UNKNOWN_DECLARATION_HANDLING,
});
}

// Based on the Bazel action and its substitutions, we run the linker for all inputs.
Expand Down
4 changes: 4 additions & 0 deletions bazel/spec-bundling/index.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def spec_bundle(
platform,
bootstrap = [],
run_angular_linker = False,
linker_unknown_declaration_handling = None,
# We cannot use `ES2017` or higher as that would result in `async/await` not being downleveled.
# ZoneJS needs to be able to intercept these as otherwise change detection would not work properly.
target = "es2016",
Expand All @@ -29,6 +30,8 @@ def spec_bundle(
ending with `init.js` are picked up.
target: Target ECMAScript to use for the specs bundle.
run_angular_linker: Whether the Angular linker should process the bundled code.
linker_unknown_declaration_handling: Control how unknown partial declarations should be
treated. This passes through to the `unknownDeclarationVersionHandling` linker plugin option.
external: List of modules/packages which should not be bundled.
workspace_name: Workspace name that needs to be provided for the AMD module name.
"""
Expand All @@ -52,6 +55,7 @@ def spec_bundle(
testonly = True,
output_name = "%s_config.mjs" % name,
run_angular_linker = run_angular_linker,
linker_unknown_declaration_handling = linker_unknown_declaration_handling,
)

esbuild_config(
Expand Down
32 changes: 28 additions & 4 deletions bazel/spec-bundling/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ load("//bazel/spec-bundling:index.bzl", "spec_bundle")
load("//tools:defaults.bzl", "ts_library")

ts_library(
name = "test_lib",
name = "test_lib_apf",
testonly = True,
srcs = glob(["**/*.spec.ts"]),
srcs = ["core_apf_esm.spec.ts"],
deps = [
"@npm//@angular/core",
],
)

ts_library(
name = "test_lib_invalid_linker_declaration",
testonly = True,
srcs = ["core_invalid_linker_decl.spec.ts"],
deps = [
"@npm//@angular/core",
],
Expand All @@ -17,14 +26,22 @@ spec_bundle(
name = "test_bundle",
platform = "node",
run_angular_linker = True,
deps = [":test_lib"],
deps = [":test_lib_apf"],
)

spec_bundle(
name = "test_bundle_legacy_cjs",
platform = "cjs-legacy",
run_angular_linker = True,
deps = [":test_lib"],
deps = [":test_lib_apf"],
)

spec_bundle(
name = "test_bundle_invalid_declaration_linker",
linker_unknown_declaration_handling = "ignore",
platform = "node",
run_angular_linker = True,
deps = [":test_lib_invalid_linker_declaration"],
)

jasmine_node_test(
Expand All @@ -40,3 +57,10 @@ jasmine_node_test(
":test_bundle_legacy_cjs",
],
)

jasmine_node_test(
name = "test_invalid_declaration_linker",
deps = [
":test_bundle_invalid_declaration_linker",
],
)
2 changes: 1 addition & 1 deletion bazel/spec-bundling/test/core_apf_esm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('@angular/core ESM import', () => {
class TestCmp {}
core.ɵɵngDeclareComponent({
version: '0.0.0',
minVersion: '12.0.0',
minVersion: '0.0.0',
type: TestCmp,
selector: 'test',
ngImport: core,
Expand Down
27 changes: 27 additions & 0 deletions bazel/spec-bundling/test/core_invalid_linker_decl.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// This is an ESM import that would usually break within `jasmine_node_test` because it
// consumes devmode CommonJS sources and `rules_nodejs` does not support ESM well yet.
import {VERSION} from '@angular/core';
import * as core from '@angular/core';

describe('@angular/core ESM import', () => {
it('should work', () => {
expect(VERSION.major).toBeGreaterThanOrEqual(13);
});

it('should have run the linker', () => {
expect(() => {
class TestCmp {}
core.ɵɵngDeclareComponent({
version: '0.0.0',
// use a high version that would cause the linking process to fail due to
// an unknown version. We expect the bundling to still work though since
// we set the handling to `ignore` using `linker_unknown_declaration_handling`.
minVersion: '9999999999999.0.0',
type: TestCmp,
selector: 'test',
ngImport: core,
template: `<span>Test template</span>`,
} as any);
}).not.toThrow();
});
});

0 comments on commit 04a54cd

Please sign in to comment.