Default webpack.common.js generated using file-loader The src attr of image gonna be like '[object Module]' and image is not loaded and does not appear
In our company projects are generated by Jhipster, and to load a picture in html, we use a relative path to load resources in front-end as this example:
<img src="../../content/images/logo-OPT2.png">
We have a common generator-jhipster-custom, but we do not customized the default generated webpack.common.js so, that's why I am reporting the issue.
To fix the issue you have to update webpack.common.js and in the folowing section:
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loader: 'file-loader',
options: {
digest: 'hex',
hash: 'sha512',
name: 'content/[hash].[ext]',
}
You have to add `esModule:` false option to file-loader, and it works, the images are properly load in the browser.
`
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loader: 'file-loader',
options: {
digest: 'hex',
hash: 'sha512',
name: 'content/[hash].[ext]',
**esModule: false**
}
`
##### **JHipster Version(s)**
位 jhipster --version
INFO! Using JHipster version installed globally
6.6.0
##### ** Which version of JHipster are you using, is it a regression?**
Webpack update, not regression.
位 jhipster --version
INFO! Using JHipster version installed globally
6.6.0
##### **JHipster configuration**
位 jhipster info
INFO! Using JHipster version installed globally
INFO! Executing jhipster:info
INFO! Options: from-cli: true
Welcome to the JHipster Information Sub-Generator
##### **JHipster Version(s)**
[email protected] C:\Users\aattia\IdeaProjects\jhipster6.6.0.3
`-- (empty)
##### **JHipster configuration, a `.yo-rc.json` file generated in the root folder**
{
"generator-jhipster": {
"promptValues": {
"packageName": "nc.opt.image",
"nativeLanguage": "fr"
},
"jhipsterVersion": "6.6.0",
"applicationType": "monolith",
"baseName": "image",
"packageName": "nc.opt.image",
"packageFolder": "nc/opt/image",
"serverPort": "8080",
"cacheProvider": "no",
"websocket": false,
"databaseType": "sql",
"devDatabaseType": "postgresql",
"prodDatabaseType": "postgresql",
"searchEngine": "elasticsearch",
"messageBroker": false,
"serviceDiscoveryType": false,
"buildTool": "gradle",
"enableSwaggerCodegen": false,
"embeddableLaunchScript": false,
"useSass": true,
"clientPackageManager": "npm",
"clientFramework": "angularX",
"clientTheme": "none",
"clientThemeVariant": "",
"creationTimestamp": 1580358890904,
"testFrameworks": [],
"jhiPrefix": "jhi",
"entitySuffix": "",
"dtoSuffix": "DTO",
"otherModules": [],
"enableTranslation": true,
"nativeLanguage": "fr",
"languages": ["fr"],
"blueprints": []
}
}
entityName.json files generated in the .jhipster directory
JDL entity definitions
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
git version 2.13.0.windows.1
node: v10.16.2
npm: 6.9.0
yeoman: 2.0.5
yarn: 1.15.2
Docker version 18.06.1-ce, build e68fc7a
docker-compose version 1.22.0, build f46880fe
OS : windows 10 pro
Browser: Chrome
??
@opt-nc-dev Thanks for reporting this. Indeed we do not use relative urls in our frontend, so maybe we have a bug here. Would you mind doing a PR for this as it seems you already have a solution (which should not affect other parts as it seems).
@opt-nc-dev, I did a quick check (using dev profile) and not able to reproduce. I tried with an img tag pointing to one of static images like <img src="../../content/images/jhipster_family_member_3.svg" /> and can view correct replacement in output as <img src="content/caf1c2b432b5b77c5607b636395ab471.svg">. If you are using a dynamic image path, then, you may have to use require
Can you provide more detailed steps to reproduce?
Adding the below to home.component.html:
<img width="100" height="100" src="/content/images/logo-jhipster.png" />
<img width="100" height="100" src="/content/images/jhipster_family_member_0.svg" />
<img width="100" height="100" src="../../content/images/logo-jhipster.png" />
<img width="100" height="100" src="../../content/images/jhipster_family_member_0.svg" />
Results in:
<img _ngcontent-iwf-c13="" height="100" src="/content/images/logo-jhipster.png" width="100">
<img _ngcontent-iwf-c13="" height="100" src="/content/images/jhipster_family_member_0.svg" width="100">
<img _ngcontent-iwf-c13="" height="100" src="[object Module]" width="100">
<img _ngcontent-iwf-c13="" height="100" src="[object Module]" width="100">
With the fix:
<img _ngcontent-yxi-c1="" height="100" src="/content/images/logo-jhipster.png" width="100">
<img _ngcontent-yxi-c1="" height="100" src="/content/images/jhipster_family_member_0.svg" width="100">
<img _ngcontent-yxi-c1="" height="100" src="content/b731e05e2700a00db88828a857ca2bd5.png" width="100">
<img _ngcontent-yxi-c1="" height="100" src="content/068483b5e9a98559fe8b9755f577c433.svg" width="100">
The fix works as expected, and is an improvement as now image references are hashed. The bundle sizes generated by webpack also don't change, so your fix looks good to me.
@vishal423 I'm curious how you didn't end up reproducing the issue.
Thanks @ruddell I tried against an old project generated with v6.5.1. With the latest v6.7.0 I can also reproduce.
It seems the corresponding issue is fixed in the html-loader
I see two immediate solutions, first one as suggested by @opt-nc-dev and the second one is to enable interpolation in html-loader and use require like
{
test: /\.html$/,
loader: 'html-loader',
options: {
minimize: true,
caseSensitive: true,
removeAttributeQuotes: false,
minifyJS: false,
minifyCSS: false,
interpolate: true,
},
exclude: /(src\/main\/webapp\/index.html)/
},
<img width="100" height="100" src="${require(`../../content/images/logo-jhipster.png`).default}" />
<img width="100" height="100" src="${require(`./../../content/images/jhipster_family_member_0.svg`).default}" />
Considering, it's an issue with html-loader, I tend to prefer the second approach and wait for the next html-loader release that should resolve as default
I've never seen that approach for loading images. I think most developers would expect to be able to use:
<img width="100" height="100" src="../../content/images/logo-jhipster.png" />
instead of
<img width="100" height="100" src="${require(`./../../content/images/logo-jhipster.png`).default}" />
We also don't have any example img tags so it would be confusing to new developers.
Aside from that, html-loader has not been released for over two years. I do see some recent developments though, so something may be coming. Would developers would then have to update all of their img tags to remove .default when that release happens?
Is there a downside to setting esModule: false?
My understanding is that the existing syntax should continue to work after a new release, however, I agree that the require syntax is a bit clumsy. I am no expert in this area and also fine with disabling esModule with a note to revisit whenever the next html-loader release happens.
@opt-nc-dev, would you be able to create a PR with your suggested changes?
My understanding is that the existing syntax should continue to work after a new release, however, I agree that the
requiresyntax is a bit clumsy. I am no expert in this area and also fine with disablingesModulewith a note to revisit whenever the nexthtml-loaderrelease happens.@opt-nc-dev, would you be able to create a PR with your suggested changes?
Yes I can do that
Most helpful comment
I've never seen that approach for loading images. I think most developers would expect to be able to use:
instead of
We also don't have any example
imgtags so it would be confusing to new developers.Aside from that,
html-loaderhas not been released for over two years. I do see some recent developments though, so something may be coming. Would developers would then have to update all of theirimgtags to remove.defaultwhen that release happens?Is there a downside to setting
esModule: false?