Search code examples
javascriptwebpackwebpack-2webpack-file-loader

Webpack and copy while retaining file structure


I'm currently setting up a webpack workflow for a new project and I'm having difficulties understanding how to copy images while still retaining the old folder structure.

For example, I have images under /src/img/folder/name/01.png

Using the following rule with webpack, causes all images to be deposited directly into the /dist/img/ folder without any regard for the folder structure.

{
  test: /\.(jpg|png|svg/gif)$/,
  exclude: [/node_modules/, /font/, /fonts/],
  use: {
    loader: 'file-loader',
    options: {
      name: '[name].[ext]',
      outputPath: 'img/',
      publicPath: 'img/ ',
    },
  },
},

I understand that I'm literally telling webpack to do do that, though, I tried reading through the file-loader documentation and found out that I could use [path] to deposit the images into their relative folder, but then they end up in /dist/img/src/img/folder/name/01.png

I do know that I can set the context on file-loader to point to the specific directory, like so:

{
  test: /\.(jpg|png|svg|gif)$/,
  exclude: [/node_modules/, /font/],
  use: {
    loader: 'file-loader',
    options: {
      context: './src/vendors/mylib/img/',
      name: '[path][name].[ext]',
      outputPath: 'img/',
      publicPath: 'img/ ',
    },
  },
},

But this seems awfully redundant. Is there an easier way of having webpack copy images from the various /img/ folders that I and the libraries I rely on have, while still retaining the folder structure of the copied files?


Solution

  • You can use copy-webpack-plugin to copy files from one location to other.

    Your usage of file-loader / img-loader is incorrect, loaders are the one that responsible to introduce new file types to webpack (basically they converts none-js types to js).

    Simple usage:

    const CopyWebpackPlugin = require('copy-webpack-plugin')
    
    const config = {
      plugins: [
        new CopyWebpackPlugin([ ...patterns ], options)
      ]
    }