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?

Kokodoko
  • 26,167
  • 33
  • 120
  • 197
  • Maybe use https://www.npmjs.com/package/ignore-loader – Roy J Jan 12 '18 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 :) – Kokodoko Jan 12 '18 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: https://stackoverflow.com/questions/27639005/how-to-copy-static-files-to-build-directory-with-webpack – Roy J Jan 12 '18 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'` – Kokodoko Jan 12 '18 at 21:00

3 Answers3

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

VivaLaPanda
  • 809
  • 7
  • 24
  • 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]' } }` – Kokodoko Jan 12 '18 at 20:30
  • 1
    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. – VivaLaPanda Jan 12 '18 at 20:34
  • 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. – Kokodoko Jan 12 '18 at 20:56
  • 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. – VivaLaPanda Jan 12 '18 at 21:25
  • OK, so how about images that are never referenced in code anywhere? Do you still have to copy them manually? – Kokodoko Jan 12 '18 at 21:26
  • Why would you want to have images in your Dist that are never referenced? – VivaLaPanda Jan 12 '18 at 21:27
  • For example, I use dynamic image names that are generated using javascript and then loaded, so webpack can't know which images will be needed. Another thing is that my webpack entry file is ts/entry.ts, so the index.html file is ignored by webpack as well. – Kokodoko Jan 12 '18 at 21:30
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163076/discussion-between-adrian-smith-and-kokodoko). – VivaLaPanda Jan 12 '18 at 21:31
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.

Martin
  • 201
  • 1
  • 4
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.

sidhuko
  • 3,274
  • 1
  • 17
  • 22
  • 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. – Kokodoko Jan 12 '18 at 20:39
  • 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 https://www.npmjs.com/package/url-loader for images – sidhuko Jan 12 '18 at 20:42
  • OK, cool - so how do I enable this "tree shaking" feature? It's not mentioned on the file loader documentation. https://webpack.js.org/loaders/file-loader/ – Kokodoko Jan 12 '18 at 20:52
  • It's actually the webpack caching layer - tree shaking is code only sorry for my mistake. Webpack 3 seems to have this problem: https://github.com/webpack-contrib/file-loader/pull/213 – sidhuko Jan 12 '18 at 21:04
  • 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 https://github.com/webpack-contrib/file-loader#function. If it doesn't work please post your webpack config in the question. – sidhuko Jan 12 '18 at 21:06