I have a problem with loading an image using webpack.
When I use an image tag on an html page, everything works fine:
<img src="../../content/images/logo.png">
But I also have a need to use inline styles:
<div style="background-image: url('../../content/images/logo.png')">
In this case, webpack doesn't resolve the images and leaves the string in the url()
untouched.
Webpack config:
module: {
rules: [
{ test: /bootstrap\/dist\/js\/umd\//, loader: 'imports-loader?jQuery=jquery' },
{
test: /\.ts$/,
loaders: [
'angular2-template-loader',
'awesome-typescript-loader'
],
exclude: ['node_modules/generator-jhipster']
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
minimize: true,
caseSensitive: true,
removeAttributeQuotes:false,
minifyJS:false,
minifyCSS:false
},
exclude: ['./src/main/webapp/index.html']
},
{
test: /\.scss$/,
loaders: ['to-string-loader', 'css-loader', 'sass-loader'],
exclude: /(vendor\.scss|global\.scss)/
},
{
test: /(vendor\.scss|global\.scss)/,
loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
},
{
test: /\.css$/,
loaders: ['to-string-loader', 'css-loader'],
exclude: /(vendor\.css|global\.css)/
},
{
test: /(vendor\.css|global\.css)/,
loaders: ['style-loader', 'css-loader']
},
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loaders: ['file-loader?hash=sha512&digest=hex&name=/images/[hash].[ext]']
}
]
},
I would be grateful if someone could help me with this issue.
I have a problem with loading an image using webpack.
When I use an image tag on an html page, everything works fine:
<img src="../../content/images/logo.png">
But I also have a need to use inline styles:
<div style="background-image: url('../../content/images/logo.png')">
In this case, webpack doesn't resolve the images and leaves the string in the url()
untouched.
Webpack config:
module: {
rules: [
{ test: /bootstrap\/dist\/js\/umd\//, loader: 'imports-loader?jQuery=jquery' },
{
test: /\.ts$/,
loaders: [
'angular2-template-loader',
'awesome-typescript-loader'
],
exclude: ['node_modules/generator-jhipster']
},
{
test: /\.html$/,
loader: 'html-loader',
options: {
minimize: true,
caseSensitive: true,
removeAttributeQuotes:false,
minifyJS:false,
minifyCSS:false
},
exclude: ['./src/main/webapp/index.html']
},
{
test: /\.scss$/,
loaders: ['to-string-loader', 'css-loader', 'sass-loader'],
exclude: /(vendor\.scss|global\.scss)/
},
{
test: /(vendor\.scss|global\.scss)/,
loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
},
{
test: /\.css$/,
loaders: ['to-string-loader', 'css-loader'],
exclude: /(vendor\.css|global\.css)/
},
{
test: /(vendor\.css|global\.css)/,
loaders: ['style-loader', 'css-loader']
},
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loaders: ['file-loader?hash=sha512&digest=hex&name=/images/[hash].[ext]']
}
]
},
I would be grateful if someone could help me with this issue.
Share Improve this question edited Sep 8, 2017 at 22:27 Scotty Waggoner 3,3802 gold badges29 silver badges41 bronze badges asked May 21, 2017 at 12:17 Vladimir TopolevVladimir Topolev 3943 silver badges21 bronze badges 3- There's an unresolved issue about this github./webpack-contrib/html-loader/issues/131 – Scotty Waggoner Commented Sep 8, 2017 at 21:57
- There's also a pull request about this, and it has been there since 2020, but still not get merged github./webpack-contrib/html-loader/pull/279 – Mizok.H Commented Jan 19, 2022 at 7:32
- The alternative I am taking now is to use CopyWebpackPlugin to copy all my background-image source right into /dist, just check my answer below. – Mizok.H Commented Jan 19, 2022 at 7:40
7 Answers
Reset to default 7You might require your ´html´ file with interpolation flag enabled:
require("html-loader?interpolate!./your-file.html");
...and then require your inlined-style background image like:
<div style="background-image: url('${require(`../../content/images/logo.png`)}')">
On webpack 5, the correct answer will be to use your html-loader
.
Change your inline styles:
## Heading ##<div background-image="../../content/images/logo.png">
and your html-loader
:
{
test: /\.html$/i,
loader: 'html-loader',
options: {
minimize: true,
attributes: {
list: [
'...',// All default supported tags and attributes
{
tag: 'div',
attribute: 'data-background',
type: 'src',
}
]
}
}
}
Here for more details.
Googled myself for solution, and decided to make a loader. https://github./apotap2/url-replace-loader It's just 20 lines of code :D it just that replaces every 'url(.*)' with require() so you can use it with file-loader. If you need more plicated logic it seems it's faster to make a loader yourself.
Other solution would be (if you dont want to use interpolate flag)
$scope.imageToUse = require(`../../content/images/logo.png`)
in your controller
and use directly in your background: url({{imageToUse }})
Internally webpack will encode image to base64 and that will be assigned to imageToUse variable which than will rendered to your html page.
This solution is related to implementing webpack in Angular 1.X project. Similar approach can be applied in other cases.
The most straightforward solution for me was to use interpolate
option in Webpack as mentioned in this answer.
{
test: /\.(html)$/,
include: path.join(__dirname, 'src/views'),
use: {
loader: 'html-loader',
options: {
interpolate: true
}
}
}
And then in your HTML
<div style="background-image: url('${require('../../content/images/logo.png')')">
Very basic just:
<div class="background-design-element" style="background-image: url('<%= require('./../assets/images/test.jpg') %>')"></div>
Key is to remember: <%= =%> It can actually be this simple - :-)
interpolate
option is removed Since 1.0.0
check the change log here : https://github./webpack-contrib/html-loader/blob/master/CHANGELOG.md
Since 1.0.0
, interpolate
option is removed, so using url('{require(...)}')
is no longer possible.
The alternative I am taking now is to use CopyWebpackPlugin
to clone all background-image source into dist
(the ouput) folder, and use relative path to get source file in html.
<div style="background-image:url('../assets/images/xx.png')">
But using this way you will also lose the tree-shaking of those background-images source, and it's actually not possible to use source alias in url(), so it is just a temporary way :(
const CopyPlugin = require('copy-webpack-plugin');
...
plugins: [
...,
new CopyPlugin(
{
patterns: [
...
{
from: 'src/assets/images/background-image',
to: 'assets/images/background-image',
}
]
}
)
]