I have created a simple Angular library "test-pub" (using nx g @nrwl/angular:lib test-pub --publishable
). Then I've added a very basic component to it.
super.component.html:
<p>super works!</p>
super.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-super',
templateUrl: './super.component.html'
})
export class SuperComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
In my tsconfig.json
I've added the following (please note that enableResourceInlining
is set to true
:
"angularCompilerOptions": {
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"enableResourceInlining": true
}
Finally, I've run ng build for this library: ng run test-pub:build
Then I looked into the generated code for the library and have found the following:
import { ɵɵdefineComponent, ɵɵelementStart, ɵɵtext, ɵɵelementEnd, ɵsetClassMetadata, Component, ɵɵdefineNgModule, ɵɵdefineInjector, ɵɵsetNgModuleScope, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
var SuperComponent = /** @class */ (function () {
function SuperComponent() {
}
SuperComponent.prototype.ngOnInit = function () {
};
SuperComponent.ɵfac = function SuperComponent_Factory(t) { return new (t || SuperComponent)(); };
SuperComponent.ɵcmp = ɵɵdefineComponent({ type: SuperComponent, selectors: [["rd-super"]], decls: 2, vars: 0, template: function SuperComponent_Template(rf, ctx) { if (rf & 1) {
ɵɵelementStart(0, "p");
ɵɵtext(1, "super works!");
ɵɵelementEnd();
} }, styles: [""] });
return SuperComponent;
}());
/*@__PURE__*/ (function () { ɵsetClassMetadata(SuperComponent, [{
type: Component,
args: [{
selector: 'rd-super',
templateUrl: './super.component.html',
styleUrls: ['./super.component.less']
}]
}], function () { return []; }, null); })();
var TestPubModule = /** @class */ (function () {
function TestPubModule() {
}
TestPubModule.ɵmod = ɵɵdefineNgModule({ type: TestPubModule });
TestPubModule.ɵinj = ɵɵdefineInjector({ factory: function TestPubModule_Factory(t) { return new (t || TestPubModule)(); }, imports: [[CommonModule]] });
return TestPubModule;
}());
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && ɵɵsetNgModuleScope(TestPubModule, { declarations: [SuperComponent], imports: [CommonModule], exports: [SuperComponent] }); })();
/*@__PURE__*/ (function () { ɵsetClassMetadata(TestPubModule, [{
type: NgModule,
args: [{
imports: [CommonModule],
declarations: [SuperComponent],
exports: [SuperComponent]
}]
}], null, null); })();
/**
* Generated bundle index. Do not edit.
*/
export { SuperComponent, TestPubModule };
//# sourceMappingURL=rd-test-pub.js.map
Please pay attention to the fact that generated JS file still contains templateUrl
in ɵsetClassMetadata(SuperComponent ....
.
Moreover, when I tried to use the library in my JIT Angular app, it threw an error 404: super.component.html not found. This means that my application was trying to find the asset, it didn't use the inlined template!
During my research I've come to the following issue: https://github.com/angular/angular/issues/30174
In there @alxhub explains that indeed enableResourceInlining
is now ignored and basically resources are always inlined with Ivy.
I am having two questions here:
- Why does compiled Ivy code in my example still use
templateUrl
and why is my JIT Angular application still trying to find the HTML asset separately - Right now we can easily work around the problem by using
enableIvy: false
. But what to do when older ViewEngine will be dropped and we will be forced to use Ivy?