html-loader
html-loader copied to clipboard
Problem with migration from webpack 4 to 5. Html-loader strange behavior with @ngtools/webpack.
Hi there,
I do migration from webpack 4 to 5. For my development webpack configuration it works in the end, but for production one I have build issues. Looks like html goes out not as a string, but as a variable/module. I've got plenty of errors like following:
Here as a text: `src/app/layouts/support/SupportComponent.ts:21:18 21 templateUrl: 'support.html', ~~~~~~~~~~~~~~ Error occurs in the template of component SupportComponent. src/app/layouts/support/support.html:20:1784 - error NG5002: Unexpected closing tag "ng-container". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags
20 var code = "<div class="settings-panel support">\n <div class="support__statuses">\n <div class="support__env-info">\n <div class="support__env-info-item">\n {{ 'i18n.settings.version-number' | translate }}: {{ version }}\n \n \n <div class="support__systems">\n <div *ngFor="let s of (systems$ | async)" class="support__system">\n <div class="status-circle" [ngClass]="s.statusClass || ''">\n {{ s.name }}\n \n \n \n\n <ng-container *ngLet="supportEmail$ | async as orgSupportEmail">\n <ng-container *ngLet='supportNumber$ | async as supportNumber'>\n <ng-container *ngIf="orgSupportEmail || supportNumber">\n <a *ngIf="supportNumber" class="support__link" (click)="callSupport(supportNumber)">\n <i class="zmdi zmdi-phone"> {{ supportNumber }}\n \n\n <a *ngIf="orgSupportEmail" class="support__link" [href]="'mailto:' + orgSupportEmail">\n <i class="zmdi zmdi-email"> {{orgSupportEmail}}\n \n\n <div class="support__header">\n {{ 'i18n.settings.header' | translate }}\n \n\n <div class="support__org-logo">\n <img src="" + HTML_LOADER_REPLACEMENT_0 + "" alt="{{ 'i18n.short-app-name' | translate }}">\n \n <p class="support__description">\n {{ 'i18n.settings.our-dedicated-team' | translate }}\n
\n \n \n \n\n\n\n\n";`Html-loader has for both config as following:
{ test: /\.html$/, use: [{ loader: 'html-loader', options: { esModule: false, } }], },
Why it's like var code =?
ng-container
is not HTML tag... so it is expected when parser failed with non standard markup
hey @alexander-akait, thanks for trying to help. But with dev webpack it's totally fine. It's one and only loader for html files that I have in this project (webpack.dev works fine, webpack.prod for electron build fails). But failing build has target: 'electron-renderer' and MiniCssExtractPlugin.
You can't use html-loader
for non standard HTML, we just can't parse it, you need other loader/type, I recommend to use type: 'asset/source'
https://webpack.js.org/guides/asset-modules/
@alexander-akait it works like a charm! Thank you very much! This approach leads to another problem.
When I have in my html markup: <img src="~shared/images/empty-avatar.png" />
of course doesn't resolve it anymore like html-loader. So the links are not resolved anymore. Do you have any advice for it?
@PabloDotcom Unfortunately not, you need a loader for this, we can't parse non standard HTML (we use parse5
for parsing), so you need convert your code to html, maybe parse5
have options to suppress it, we need to look at possible options
@alexander-akait sure. For now I will probably import them on *component.ts code level and pass them to html via property.
Unfortunately parse5
doesn't have options to allow using non standard HTML code, I think in this case you need to using type: 'asset/source'
and maybe you can do like
@Component({
template: `
<div>
<!-- Hello, Padma -->
<h1>Hello, {{customer}}</h1>
<img src={{myImage}} alt='test'>
<ul>
<!-- Ebony and Chiho in a list-->
<li *ngFor="let customer of customers">{{ customer.value }}</li>
</ul>
</div>
`
})
class AppComponent {
customers = [{value: 'Ebony'}, {value: 'Chiho'}];
customer = 'Padma';
// Or you can do `import myImage from './path/to/image.png'; ` on the top of file
myImage = new URL('./image.png', import.url.meta);
}
So all URLs will be resolved
I am not familiar with angular syntax, sorry, but I hope you understand my idea
@alexander-akait yeah, this is approach that I mentioned in my previous comment :) If I will find another way to do it I will let you know.
Hey guys .. this issue makes me feel confused and anxious about upgrading to latest html-loader in multiple projects.
So if I define a web component named <ng-container>
would html-loader fail to parse it? This sounds like broken behavior. Custom tag names are a pretty standard thing these days. What difference does it make that it's a structural/internal tag name in Angular?
Sorry for my confusion. Maybe I am simply not understanding something.
@Rush <ng-container>
tag doesn't exist in HTML spec, so we don't know how to parse it
It doesn't have to exist as it could be a custom element such as a Web Component.
https://developer.mozilla.org/en-US/docs/Web/Web_Components https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots
See this exmaple https://codesandbox.io/s/web-components-using-vanilla-js-forked-c9xsk where I defined a custom ng-container
web component.
https://github.com/WICG/webcomponents
Somebody can provide simple case to reproduce, yep, looks it should be parser, maybe something wrong in markup, i.e. extra closing
It seems img tag not being closed properly. Can it be a concern for the parser? Has neither end tag nor self closing by itself.
Not closing some tags is legal in HTML5 https://stackoverflow.com/a/3558200/403571
@Rush, that is TRUE.
My point is whether the parse5 is honoring them or not. Most modern browsers do, but I'm not sure if it is the case with parse5.
Sorry if my point makes no sense.
Seems to work fine https://astexplorer.net/#/1CHlCXc4n4
Without example of code I can't help :disappointed:
My issue after installing html loader is it gives an error that this.getOptions() is not defined. which literally not defined in or called in the file it was written on. I found a cheap solution to that i copied the function from my loader-utilities library and past it there which works fine now but it wont work on automation deploys since the node modules gets reinstalled.
NEED A PERMANENT SOLUTION FOR THIS
Maybe this will help someone. I got a similar error in my Angular project when running unit tests. I use html-loader in my webpack config. This error appeared after updating the version of Angular from 10 to 13. Analysis of the build revealed that the problem is in the loader, which was added in the commit https://github.com/angular/angular-cli/commit/f4cd6848555cd44b6a327aa936951282891a2b52. I fixed this error by adding html-loader resourceQuery: /(?<!?ngResource)$/.
@wprogeye Could you please share some code? I can't make it work html-loader crashes with directTemplateLoading=false whatever I do It shows this https://ibb.co/KrST2dZ Thank you
Closing due to inactivity. Please test with latest version and feel free to reopen if still regressions. Thanks!