10

I am using webpack to bundle .vue files, which use import and export. Webpack creates a nice bundle.js and that's all fine and dandy.

BUT when my Vue file mentions an image, for example:

<div> <img src='./images/thing.png'> </div> .style { background: url('./images/anotherthing.png'); } 

Now, suddenly this image needs to be in my dev folder as well, and webpack wants to copy ALL my image files each and every time I update one character in one javascript file. Also, not ALL my images are imported this way, so I have to copy some files manually to the dist folder, and webpack also copies some files...

Can I tell webpack not to bundle static image files that never change? Is that even recommended?

6
  • Maybe use npmjs.com/package/ignore-loader Commented Jan 12, 2018 at 20:28
  • Thanks. Is that recommended? Why would you want webpack to copy a 100 images every time you change one character in a .js file? Sorry, I just don't understand the concept :) Commented Jan 12, 2018 at 20:37
  • Webpack is for putting together a distribution, which would have to include the images. I'm not much of a webpack guru, so I can't explain why its rebuilding behavior isn't smarter. There may be some helpful info for you in this thread: stackoverflow.com/questions/27639005/… Commented Jan 12, 2018 at 20:59
  • After installing ignore-loader and using { test: /\.svg$/, loader: 'ignore-loader' } I still get the error Module not found: Error: Can't resolve './images/triangle.svg' Commented Jan 12, 2018 at 21:00
  • In the newer versions, it is: { test: /\.(png|svg|jpg|jpeg|gif)$/i, type: 'asset/resource' } loading-images asset/resource emits a separate file and exports the URL. Previously achievable by using file-loader. lasset-modules Commented Sep 16 at 16:21

3 Answers 3

4

Webpack has a file-loader which will handle copying static dependencies and resolving their URLs correctly:

https://webpack.js.org/loaders/file-loader/

Here is more in depth discussion about images specifically: https://webpack.js.org/guides/asset-management/#loading-images

Sign up to request clarification or add additional context in comments.

8 Comments

But is it really necessary that webpack handles images? I just need my .js files bundled. My webpack config already includes { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } }
The other route is to just have an assets folder and somewhere in your build process you copy the assets folder into your dist directory. Obviously simpler, but it means you need to make all of the URLs in your code relative to that asset directory and that if you have a lot of images it can be slow. This is what Angular CLI does.
In this case the images never change, so I'd much rather just copy them once manually and not have them as part of the build process.
That's fine except that it removes the guarantee that dist can be built using only src. Imagine the following scenario: 1) img.png added to src/ 2) img.png manually moved to dist/ 3) img.png referenced in code 4) img.png deleted in src/, but you forget to remove references. Now your code will look fine to you, but if you delete your local copy and pull down from Git, or share your code with someone, it will have missing images.
OK, so how about images that are never referenced in code anywhere? Do you still have to copy them manually?
|
3

Let's say we have following structure: - public/ - dist/ - static/ - src/ - webpack.config.js You can keep your static images in static directory and all files built by webpack in dist directory. Set webpack directory to src. Webpack will work with only src directory and your static files will be separated from webpack.

And use webpack watch: true. Webpack will compile only changed code not all project.

Comments

1

You can use a different file extension to handle certain images differently. Be sure to include the ignore-loader before the file-loader:

{ test: /ignore\.(png|jpg|gif|svg)$/, loader: 'ignore-loader' }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } } 

Then include your image using the prefixed extension:

<img src='./images/thing.ignore.png'> 

You'll need to rename the file to thing.ignore.png as well.

5 Comments

Thanks, I think my real question is why this functionality even exists. It doesn't seem very practical to copy hundreds of images if I change one console.log statement.
It should be static tree shaking to only rebuild assets it needs too... It's actually really helpful to convert small images into data uris (strings) so the browser doesn't have to load lots of small images. This can block other more important assets (js, css) from loading as it'll block parallelisation. Instead of file-loader most projects use npmjs.com/package/url-loader for images
OK, cool - so how do I enable this "tree shaking" feature? It's not mentioned on the file loader documentation. webpack.js.org/loaders/file-loader
It's actually the webpack caching layer - tree shaking is code only sorry for my mistake. Webpack 3 seems to have this problem: github.com/webpack-contrib/file-loader/pull/213
Can you tree adding the function here to your configuration? I think the problem is the hash it generates cannot be cached so using a filename in development instead should allow webpack to cache github.com/webpack-contrib/file-loader#function. If it doesn't work please post your webpack config in the question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.