3

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:

  1. 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
  2. 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?
Kirill Metrik
  • 384
  • 1
  • 2
  • 12

0 Answers0