sveltejs / svelte-loader

Webpack loader for svelte components.
MIT License
597 stars 72 forks source link

Assets import #114

Open GMartigny opened 4 years ago

GMartigny commented 4 years ago

Hi,

When importing assets (images for examples) inside HTML of svelte component, it's not processed by the loader and therefore neither by webpack.

example that don't work:

<img src="./statics/image.png"/>

workaround:

<script>
  import img from "./statics/image.png";
</script>
<img src="{img}"/>

You might be interested at the way vue-loader is doing it. I don't know if this is relevant to svelte tho.

lloy0076 commented 4 years ago

To make the above work I also had to add:

            {
                test: /\.(png|svg|jpg|gif)$/,
                use:  [
                    'file-loader',
                ],
            },

And npm install --save-dev file-loader (although that may have been about as a pre-requisite already).

Without the above I get:

ERROR in ./src/chook.jpg 1:0 Module parse failed: Unexpected character '�' (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to > process this file. See https://webpack.js.org/concepts#loaders

(I was using a picture of a chook aka a chicken).

benmccann commented 4 years ago

It looks like the way Vue does it is to have the loader invoke the Vue compiler. They're able to get the AST as a result which makes it easier to handle things like this. I wonder if we should do something similar

webdagger commented 3 years ago

Using @GMartigny and @lloy0076 's fix allows setting of background images too. <script> import img from "./statics/image.png"; </script> <img src="{img}"/>

<style> background-image: url({img}) </style>

niketpathak commented 3 years ago

Any update on this ? Currently, I'm trying to import assets via css (background: url('./xyz.svg')) and need the url to be correctly translated to (background: url('./client/contenthash.svg')) to enable versioning, but to no avail. I'm guessing that this needs to be implemented in the svelte-loader so it gets picked up by webpack, although I'm not quite sure.

Any alternates/workarounds for achieving the same?

mefaba commented 3 years ago

You can achieve this behavior with rollup image-loader.

npm install @rollup/plugin-image --save-dev

>>rollup.config.js
import image from '@rollup/plugin-image';
export default {
  ...
  plugins: [ 
      image(), 
      ...
  ]
};
Source From <https://github.com/rollup/plugins/tree/master/packages/image> 
non25 commented 3 years ago

For style tag image links there are two ways:

  1. HMR compatible: implement file-loader-like functionality using postcss-url and taking inspiration from css-loader - https://github.com/postcss/postcss-url#url-function
  2. HMR incompatible: use emitCss: true and rely on css-loader to process urls for you.

When using emitCss: true it is important to inline imports at preprocess step using postcss-import.

mcuppi commented 2 years ago

@dummdidumm; This should probably be labeled as a feature request.

Webpack's default behavior requires you to explicitly import your assets. This can be seen in the "Loading Images" section of the asset management documentation.

If this is a feature request, we probably need to flesh out exactly what needs to be handled. A good reference point might be the html-loader plugin. That plugin seeks out every loadable attribute in your markup and imports the asset for you.

woss commented 1 year ago

for ones who are looking quick copy/paste for webpack here it is:

{
  test: /\.(png|svg|jpg|gif)$/,
  use: ['file-loader']
}

put this in the module.rules