Skip to content

Commit 1e5082d

Browse files
authoredMar 21, 2025
fix(cdk/overlay): ensure re-exported transitive Dir directive can be imported (#30679)
This is a follow-up to cb3b0a8 which did miss this transitive re-export of the `Dir` directive. The compiler will try the last module import, so even if e.g. `./scrolling` re-exported `Dir` as of the initial commit, the compiler would try importing via `@angular/cdk/overlay`. This commit fixes this remaining instance, and updates the new testing infrastructure to import/test every module in isolation. The tests didn't notice that issue because the compiler discovered the `Dir` directive/"Reference" already via another import that "worked". Fixes #30663.
1 parent 76472bc commit 1e5082d

File tree

4 files changed

+57
-35
lines changed

4 files changed

+57
-35
lines changed
 

‎integration/module-tests/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module_test(
2020
"//src/cdk:npm_package": "src/cdk/npm_package",
2121
"//src/material:npm_package": "src/material/npm_package",
2222
},
23+
shard_count = 4,
2324
skipped_entry_points = [
2425
# This entry-point is JIT and would fail the AOT test.
2526
"@angular/material/dialog/testing",

‎integration/module-tests/index.bzl

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
load("@aspect_rules_js//js:defs.bzl", "js_test")
22
load("@bazel_skylib//rules:write_file.bzl", "write_file")
33

4-
def module_test(name, npm_packages, skipped_entry_points = [], additional_deps = []):
4+
def module_test(name, npm_packages, skipped_entry_points = [], additional_deps = [], **kwargs):
55
write_file(
66
name = "%s_config" % name,
77
out = "%s_config.json" % name,
@@ -21,4 +21,5 @@ def module_test(name, npm_packages, skipped_entry_points = [], additional_deps =
2121
] + additional_deps + [pkg[0] for pkg in npm_packages.items()],
2222
entry_point = ":index.mjs",
2323
fixed_args = ["$(rootpath :%s_config)" % name],
24+
**kwargs
2425
)

‎integration/module-tests/index.mts

+53-34
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,38 @@ async function main() {
1717
config.packages.map(pkgPath => findAllEntryPointsAndExportedModules(pkgPath)),
1818
);
1919

20-
const exports = packages
20+
const allExports = packages
2121
.map(p => p.moduleExports)
2222
.flat()
23-
.filter(e => !config.skipEntryPoints.includes(e.importPath));
23+
.filter(e => !config.skipEntryPoints.includes(e.importPath))
24+
.sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
2425

25-
const testFile = `
26-
import {NgModule, Component} from '@angular/core';
27-
${exports.map(e => `import {${e.symbolName}} from '${e.importPath}';`).join('\n')}
26+
// Distribute the exports based on the current test shard.
27+
// Controlled via Bazel's `shard_count` attribute. See:
28+
// https://bazel.build/reference/test-encyclopedia#initial-conditions.
29+
const testShardIndex =
30+
process.env['TEST_SHARD_INDEX'] !== undefined ? Number(process.env['TEST_SHARD_INDEX']) : 0;
31+
const testMaxShards =
32+
process.env['TEST_TOTAL_SHARDS'] !== undefined ? Number(process.env['TEST_TOTAL_SHARDS']) : 1;
33+
const testChunkSize = Math.ceil(allExports.length / testMaxShards);
34+
const testChunkStart = testChunkSize * testShardIndex;
35+
const shardExports = allExports.slice(testChunkStart, testChunkStart + testChunkSize);
2836

29-
@NgModule({
30-
exports: [
31-
${exports.map(e => e.symbolName).join(', ')}
32-
]
33-
})
34-
export class TestModule {}
37+
const testFiles = shardExports.map(e => ({
38+
content: `
39+
import {NgModule, Component} from '@angular/core';
40+
import {${e.symbolName}} from '${e.importPath}';
3541
36-
@Component({imports: [TestModule], template: ''})
37-
export class TestComponent {}
38-
`;
42+
@NgModule({
43+
exports: [${e.symbolName}]
44+
})
45+
export class TestModule {}
3946
40-
await fs.writeFile(path.join(tmpDir, 'test.ts'), testFile);
47+
@Component({imports: [TestModule], template: ''})
48+
export class TestComponent {}
49+
`,
50+
path: path.join(tmpDir, `${e.symbolName.toLowerCase()}.ts`),
51+
}));
4152

4253
// Prepare node modules to resolve e.g. `@angular/core`
4354
await fs.symlink(path.resolve('./node_modules'), path.join(tmpDir, 'node_modules'));
@@ -47,26 +58,34 @@ async function main() {
4758
await fs.symlink(path.resolve(packagePath), `./node_modules/${name}`);
4859
}
4960

50-
const result = performCompilation({
51-
options: {
52-
rootDir: tmpDir,
53-
skipLibCheck: true,
54-
noEmit: true,
55-
module: ts.ModuleKind.ESNext,
56-
moduleResolution: ts.ModuleResolutionKind.Bundler,
57-
strictTemplates: true,
58-
preserveSymlinks: true,
59-
strict: true,
60-
// Note: HMR is needed as it will disable the Angular compiler's tree-shaking of used
61-
// directives/components. This is critical for this test as it allows us to simply all
62-
// modules and automatically validate that all symbols are reachable/importable.
63-
_enableHmr: true,
64-
},
65-
rootNames: [path.join(tmpDir, 'test.ts')],
66-
});
61+
const diagnostics: ts.Diagnostic[] = [];
62+
63+
for (const testFile of testFiles) {
64+
await fs.writeFile(testFile.path, testFile.content);
65+
66+
const result = performCompilation({
67+
options: {
68+
rootDir: tmpDir,
69+
skipLibCheck: true,
70+
noEmit: true,
71+
module: ts.ModuleKind.ESNext,
72+
moduleResolution: ts.ModuleResolutionKind.Bundler,
73+
strictTemplates: true,
74+
preserveSymlinks: true,
75+
strict: true,
76+
// Note: HMR is needed as it will disable the Angular compiler's tree-shaking of used
77+
// directives/components. This is critical for this test as it allows us to simply all
78+
// modules and automatically validate that all symbols are reachable/importable.
79+
_enableHmr: true,
80+
},
81+
rootNames: [testFile.path],
82+
});
83+
84+
diagnostics.push(...result.diagnostics);
85+
}
6786

6887
console.error(
69-
ts.formatDiagnosticsWithColorAndContext(result.diagnostics, {
88+
ts.formatDiagnosticsWithColorAndContext(diagnostics, {
7089
getCanonicalFileName: f => f,
7190
getCurrentDirectory: () => '/',
7291
getNewLine: () => '\n',
@@ -75,7 +94,7 @@ async function main() {
7594

7695
await fs.rm(tmpDir, {recursive: true, force: true, maxRetries: 2});
7796

78-
if (result.diagnostics.length > 0) {
97+
if (diagnostics.length > 0) {
7998
process.exitCode = 1;
8099
}
81100
}

‎src/cdk/overlay/overlay-module.ts

+1
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ export {
3636
CdkVirtualScrollableWindow as ɵɵCdkVirtualScrollableWindow,
3737
CdkVirtualScrollableElement as ɵɵCdkVirtualScrollableElement,
3838
} from '../scrolling';
39+
export {Dir as ɵɵDir} from '../bidi';

0 commit comments

Comments
 (0)
Failed to load comments.