build: fix AIO local e2e examples picking up incorrect dependencies (#49293)

Whenever we run example tests using the local framework packages, the
e2e tests will have the local framework packages symlinked in the
`node_modules`.

This works well in general, but due to NodeJS by default resolving
symlinks to the target location, NodeJS will end up looking for
transitive dependencies in the `bazel-bin` instead of in the example
`node_modules` folder. This means that we end up incorrectly resolving
older versions of `@angular/core` that end up existing in the main
project dependencies. This causes errors like:

```
Error: ../../home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/bin/packages/common/npm_package/http/testing/index.d.ts:12:21 - error TS2307: Cannot find module '@angular/common/http' or its corresponding type declarations.

12 import * as i1 from '@angular/common/http';
                       ~~~~~~~~~~~~~~~~~~~~~~

Error: ../../home/circleci/.cache/bazel/_bazel_circleci/9ce5c2144ecf75d11717c0aa41e45a8d/execroot/angular/bazel-out/k8-fastbuild/bin/packages/common/npm_package/index.d.ts:1630:18 - error TS2707: Generic type 'ɵɵDirectiveDeclaration' requires between 6 and 8 type arguments.

1630     static ɵdir: i0.ɵɵDirectiveDeclaration<NgClass, "[ngClass]", never, { "klass": "class"; "ngClass": "ngClass"; }, {}, never, never, true, never>;
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

We can fix this by properly ensuring that NodeJS does not resolve
symlinks, but rather preserves them.

In the error above, the e2e tests end up accidentally resolving
`@angular/core` v14 that comes from `@angular/benchpress`. Angular
Benchpress is installed via `@angular/build-tooling` in the project
root.

PR Close #49293
This commit is contained in:
Paul Gschwendtner
2023-03-03 13:55:27 +00:00
committed by Jessica Janiuk
parent 55c37db78f
commit da1504fec4
+11 -14
View File
@@ -132,11 +132,13 @@ function pointBinSymlinksToLocalPackages(linkedNodeModules, exampleDepsNodeModul
});
}
// When local packages are symlinked in, node has trouble resolving some peer deps. Setting
// preserveSymlinks in relevant files fixes this. This isn't required without local packages
// because in the worst case we would leak into the original Bazel repository and it would
// still find a node_modules folder for resolution. Add the preserveSymlinks options to various
// files that are used by the cli and systemjs tests (and sometimes both).
/**
* When local packages are symlinked in, node will by default resolve local packages to
* their output location in the `bazel-bin`. This will then cause transitive dependencies
* to be incorrectly resolved from `bazel-bin`, instead of from within the example sandbox.
*
* Setting `preserveSymlinks` in relevant files fixes this.
*/
function preserveSymlinksWhenUsingLocalPackages(LOCAL_PACKAGES, appDir) {
if (Object.keys(LOCAL_PACKAGES).length === 0) {
return;
@@ -145,19 +147,16 @@ function preserveSymlinksWhenUsingLocalPackages(LOCAL_PACKAGES, appDir) {
// Set preserveSymlinks in angular.json
const angularJsonPath = path.join(appDir, 'angular.json');
if (fs.existsSync(angularJsonPath)) {
const angularJson = jsonc.load(angularJsonPath, {
encoding: 'utf-8'
});
const angularJson = jsonc.load(angularJsonPath, {encoding: 'utf-8'});
angularJson.projects['angular.io-example'].architect.build.options.preserveSymlinks = true;
angularJson.projects['angular.io-example'].architect.test.options.preserveSymlinks = true;
fs.writeFileSync(angularJsonPath, JSON.stringify(angularJson, undefined, 2));
}
// Set preserveSymlinks in any tsconfig.json files
const tsConfigPaths = globbySync([path.join(appDir, 'tsconfig*.json')]);
for (const tsConfigPath of tsConfigPaths) {
const tsConfig = jsonc.load(tsConfigPath, {
encoding: 'utf-8'
});
const tsConfig = jsonc.load(tsConfigPath, {encoding: 'utf-8'});
const isRootConfig = !tsConfig.extends;
if (isRootConfig) {
tsConfig.compilerOptions.preserveSymlinks = true;
@@ -167,9 +166,7 @@ function preserveSymlinksWhenUsingLocalPackages(LOCAL_PACKAGES, appDir) {
// Call rollup with --preserveSymlinks
const packageJsonPath = path.join(appDir, 'package.json');
const packageJson = jsonc.load(packageJsonPath, {
encoding: 'utf-8'
});
const packageJson = jsonc.load(packageJsonPath, {encoding: 'utf-8'});
if ('rollup' in packageJson.dependencies || 'rollup' in packageJson.devDependencies) {
packageJson.scripts.rollup = 'rollup --preserveSymlinks';
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, undefined, 2));