As part of the Bazel toolchain migration we noticed that implicit types
generated by the TypeScript compiler sometimes end up referencing types
from other packages (i.e. cross-package imports).
These imports currently work just because the Bazel `ts_library` and
`ng_module` rules automatically inserted a `<amd-module
name="@angular/x" />` into `.d.ts` of packages. This helped TS figure
out how to import a given file. Notably this is custom logic that is not
occuring in vanilla TS or Angular compilations—so we will drop this
magic as part of the toolchain cleanup!
To improve code quality and keep the existing behavior working, we are
doing the following:
- adding a lint rule that reduces the risk of such imports breaking. The
failure scenario without the rule is that API goldens show unexpected
diffs, and types might be duplicated in a different package!
- keeping the `<amd-module` headers, but we manually insert them into
the package entry-points. This should ensure we don't regress
anywhere; while we also improved general safety around this above.
Long-term, isolated declarations or a lint rule from eslint-typescript
can make this even more robust.
PR Close#61312
Other code may depend on `ngServerMode` and it might have been set
globally / via a bundler. Forcing it to `undefined` in those situations
can lead to hard debug issues where the only symptom is that "suddenly"
browser-specific code paths run on the server and (obviously) break.
PR Close#61106
This cleans up the triggering code base and consolidates it down to one
function that outlines the logic. This also resolves the `hydrate when`
behavior issue.
fixes: #58709
PR Close#58833
This commit addresses a problem with tests that use the `fit` function to focus on individual test cases. While these tests run successfully in the full suite, they fail when focused individually using `fit`.
The issue lies in the behavior of `withEventReply` and other hydration-related functions (i.e., `provideX`, `withX`). These functions return platform-specific providers based on the `ngServerMode` setting, causing inconsistencies between server and browser environments. As a result, provider instances cannot be reused across server and browser applications.
**Example of problematic code:**
```ts
const hydrationFeatures = [withEventReply()];
const html = await ssr(SimpleComponent, { hydrationFeatures });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures,
});
// Expected behavior ...
```
**Solution:**
To address this, we define `hydrationFeatures` as a function instead of a static array. This ensures that a new instance of `withEventReply` is created separately for each environment, eliminating platform-specific mismatches between server and browser contexts:
```typescript
const hydrationFeatures = () => [withEventReply()]; // Define as a function
const html = await ssr(SimpleComponent, { hydrationFeatures: hydrationFeatures() });
// Expected behavior ...
const appRef = await prepareEnvironmentAndHydrate(doc, html, SimpleComponent, {
hydrationFeatures: hydrationFeatures(),
});
// Expected behavior ...
```
PR Close#58538
This re-organizes the hydration tests to make it easier to add new tests. Incremental hydration can have tests in a separate file after this groundwork is landed.
PR Close#58196