--
Change 1 of 1 by Paul Gschwendtner <paulgschwendtner@gmail.com>:
fix(tsc_wrapped): do not leak generated module name from previous compilations
Currently, the compiler host in `@bazel/typescript` assigns a `moduleName`
to source files when the module format is AMD or UMD.
It does that so that devmode compilations (which by default use the
module kinds as mentioned above), have unique module names for all
compilation source files. This is necessary so that the JS output
can run inside browsers and node in a concatenated way.
The update of the `moduleName` for source files is critical though,
because source files are re-used/cached across compilations. For
example, an initial compilation might be for AMD devmode where the module
name is computed and set to the source file. In a followed compilation
in _devmode_, the module name will be still set by accident and the
compilation output could unexpectedly be based on the module name that
does not work in the prodmode output (where for example relative paths
are expected).
Another scenario would be that the `moduleName` has changed in the
second compilation through an update to the `module_name` rule
attribute. The host will now throw an error because it _thinks_
that there are conflicting module names for the source file. This
results in the commonly known error looking as followed:
```
Compiling Angular templates (Ivy - devmode) <..> failed (Exit 1)
Error: ERROR: <..>/index.ts contains a module name declaration @angular/in-memory-web-api which would be overwritten with angular-in-memory-web-api by Bazel's TypeScript compiler.
```
We can fix this by not permanently persisting the `moduleName` in
the source file files. We do this by reseting the module name when
the compilation module kind changes (to a format where the generated
AMD module names are no longer desired).
Ideally we'd create recursive clones for source files when returning
them from the file loader, so that the actual cache is never invalidated
accidentally (e.g. through the module name change). It seems that this
is not achievable in a reasonable way as it complicates and slows-down
the cache significantly (due to a recursive clone & increased memory
consumption). Additionally, the idea of using a `Proxy` has been
considered, but it seems that a proxy is slightly behaving different
than an actual property on the source file object (most likely due to
scope binding when the module name is not directly part of the source
file; I wasn't able to get it work reliably in _all_ cases; the proxy
would be more complex than initially anticipated too as TS relies on
enumeration for source file objects; and more).
Regardless of that though, it seems like cloning the full source file is
not necessarily needed though. We can assume that TypeScript will not
modify/invalidate essential information for cached source files through an emit.
ds
Closes #504
PiperOrigin-RevId: 330609958
3 files changed