Linker Babel Plugin needs to explicitly run on partially compiled Ivy libraries
See original GitHub issueBug Report
@angular/compiler-cli/linker/babel
does not detect/compile partial Ivy libraries when compiling application code. This results in a runtime error Uncaught Error: Angular JIT compilation failed: '@angular/compiler' not loaded!
When running the loader explicitly on partial ivy libraries they are compiled correctly.
Affected Package
@angular/compiler-cli/linker/babel
Is this a regression?
No, Angular 12 is the first version that includes the loader.
Description
In order to consume modern libraries that published partial Ivy code, the Angular Linker is used to compile it to full Ivy. To use the linker outside of the CLI you would use the babel-loader @angular/compiler-cli/linker/babel
.
It is ill advised to run babel over the entirety of node_modules/
so you include the loader in the babel config running only on application code. In this case the loader is able to detect from imports what libraries need to be compiled. This works fine for legacy libraries published in the View Engine format (with a metadata entry in package.json), but it is ignoring partial Ivy libraries.
Minimal Reproduction
Later this week I would be able to create a minimal reproduction if deemed necessary – this is however quite involved.
Exception or Error
Since the linker is able to detect legacy libraries used in application code, it is expected that it would also pick up partial Ivy libraries, instead an explicit webpack rule needs to be configured to run over modern libs.
Because the library stays uncompiled, it results in runtime errors like Uncaught Error: Angular JIT compilation failed: '@angular/compiler' not loaded!
.
Your Environment
Angular Version:
12.1.0
Anything else relevant?
Custom build using @ngtools/webpack
and @angular-devkit/build-optimizer/webpack-loader
ngcc
is also ignoring the library (as is expected?).
Workaround
Posting here for others that might encounter the issue. Make sure you set up webpack.config.json
to run the babel loader explicitly over the libraries that need to be compiled to full Ivy.
/* Explicit rule to rune the linker over partial libraries */
rules: [{
test: /.*\.(js|ts)$/,
include: /node_modules\/(ngx\-tiptap|ngx\-another\-lib)/,
use: [
{
loader: 'babel-loader',
options: {
configFile: false,
plugins: ['@angular/compiler-cli/linker/babel'],
},
},
],
},
/* your regular build, excluding packages */
{
test: /.*\.(js|ts)$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' },
{ loader: '@ngtools/webpack' },
{ loader: '@angular-devkit/build-optimizer/webpack-loader' },
],
},
// ... other rules
]
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
This is working as intended. The linker needs to be incorporated into a custom build pipeline manually.
A Webpack loader is only run when a module is requested to be included in the final bundle, so the linker will not run on everything in
node_modules
. Still, if it’s included in a Webpack rule without conditions then it will indeed also run Babel on modules that don’t contain partially compiled code.I don’t quite understand what is meant here. The linker is not involved in ngcc-processed libraries, if that’s what you mean by “legacy libraries”. The linker also doesn’t detect anything, it gets invoked as long as it’s configured to run in a Babel loader.
From sibiraj-s/ngx-tiptap#10 I notice your following comment:
That is indeed exactly how it’s designed. We should probably improve the reported error message when the JIT compiler is not present.
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.