I am writing a decorator for custom elements,the primary code is:
interface CustomElementOptions {
selector: string,
template?: { default: string };
}
function CustomElement(options: CustomElementOptions) {
return (target: CustomElementConstructor) => {
if(options.template) {
const template = document.createElement('template');
template.innerHTML = options.template.default;
Object.defineProperty(target.prototype, 'template', {
value: template,
});
}
window.customElements.define(options.selector, target as any);
};
}
@CustomElement({
selector: 'test-span',
template: require('./template.html'), // <---------------------- I want to change here with `templateUrl`
})
export class SpanElement extends HTMLElement {
public template?: HTMLTemplateElement;
constructor() {
super();
if(this.template) {
this.appendChild(this.template.content.cloneNode(true));
}
}
}
I am now using raw-loader
to load html template, but this is not elegant enough, I want to be like Angular:
@CustomElement({
selector: 'test-span',
templateUrl: './template.html', // <---------------------- templateUrl
})
export class SpanElement extends HTMLElement { ... }
But I can not use require or import inside decorator, the error message like this:
Uncaught Error: Cannot find module './template.html'
at webpackEmptyContext (app|sync:2)
at application.ts:10
at __webpack_modules__../src/app/application.ts.__decorate (index.js:6)
at Object../src/app/application.ts (application.ts:20)
at __webpack_require__ (bootstrap:18)
at Object../src/main.ts (main.ts:1)
at __webpack_require__ (bootstrap:18)
at startup:3
at startup:5
What's the magic inside angular-cli? I tried my best, thanks for your help!
Finally, Finally! I found the solution.
The short answer is update the typescript ast.
The next are my detailed steps.
I had no idea at first, I want to achieve automated
require('./template.html')
, then I thought of AST, I am usingts-loader
for compile typescript,ts-loader
providergetCustomTransformers
to custom typescript transformer, and this is my transformer, please ignore my messy code, this is my first time working with AST: