Udate:
Although I haven't been able to find out whether this is a feature or a bug. It seems url-loader
can't process the assets used in the Svelte component unless those are loaded via require
. So I would like to know what's the more common or recommended way to load/preprocess, using Webpack 4, a Svelte component source so that all image assets used in src
/url
in HTML tags and CSS styles get inlined, i.e. converted to use the embedded base64 data in the HTML or CSS output files.
Original Question
I want to have a tag <img src="./assets/logo.png">
in a svelte component to be converted to <img src="data:image/png;base64,iV...CC">
in the output, but if I add url-loader
to my webpack.config.js
file like so:
module: {
rules: [
//...
{
test: /logo.png/,
loader: (process.stdout.write("!!!\n"), 'url-loader')
}
The URL in src
does still appear as "./assets/logo.png"
in the output even is the console shows "!!!" during the webpack build process with no errors, why is url-loader
not making the conversion? The file logo.png
is about 3KB in size, but I'm not sure is that's the problem since it's small in size.
The image is being used here like so:
<div id="app">
{#if path === '/'}
<span on:click={navigateToSettings} id="menu"><div class="hamburger" /></span>
{/if}
{#if path === '/settings' && isStored()}
<span on:click={cancel} id="menu"><div class="close" /></span>
{/if}
<img class='logo' src='./assets/img/logo.png' alt='Spark'>
{#if connected}
<span id="status" class="green">•</span>
{:else}
<span id="status" class="red">•</span>
{/if}
<div id="content">
<RouterView />
</div>
</div>
And I'm adding the url-loader
rule here before the rule for audio files:
module: {
rules: [
//...
{
test: /logo.png/,
loader: (process.stdout.write("!!!\n"), 'url-loader')
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader'
},
If you use webpack
and url-loader
with any of modern frontend frameworks it is a common practice to use images via require
.
Example from react
world:
import iconMore from “../path_to_image/name_of_image.jpg”;
const Icon = (props) => {
return <img src={iconMore} />
}
for more examples please see this question.
Also I found svelte-assets-preprocessor
- you can use it in pair with url-loader
without direct require
, but under the hood it is the same technique:
module: {
rules: [
...
{
test: /\.(png|svg|jpg|gif)$/,
loader: 'file-loader',
options: {
outputPath: 'images',
}
},
{
test: /\.(html|svelte)$/,
exclude: /node_modules/,
use: {
loader: 'svelte-loader',
options: {
preprocess: require('svelte-assets-preprocessor')({ /* options */ exclude: [ (attr) => !/\.(png|svg|jpg|gif)$/.test(attr)} ])
},
},
},
...
]
}
Input
<img src="./example.png">
Output
<script>
import ___ASSET___1 from './example.png';
</script>
<img src="{___ASSET___1}">