9

I am setting up Webpack 3 and currently configuring asset management of static images that I would like to copy over from my src folder to my dist folder. I would like to keep the file structure of my /img folder in place as it copies over to the dist folder, but the issue I am running into is where I am trying to remove part of the path placeholder. Is what I am trying to achieve possible?

I have my rule as follows:

  {
      test: /\.(png|jpe?g|gif|ico)$/,
      use: [{
          loader: 'file-loader',
          options: {
              name: '[path][name].[ext]?[hash]',
              //outputPath: 'img/'
          }
      }]
  }

And it's grabbing images from my entry point file through the context:

require.context('./img/', true, /\.(png|jpe?g|gif|ico)$/);

However when the file gets copied over, because I have the [path] placeholder as part of the name, the files will resemble /src/img/[name].[extension]?[hash]. I would like to keep the rest of the path intact as some of the images have paths like /src/img/favicons/[name].[extension]?[hash] and I feel that the dist folder should maintain this structure. As you can see by the code I have tried to use the outputPath but this just sets the file to /img/src/img/[name].extension?[hash]. I have also tried utilizing the publicPath setting but it didn't seem to have any effect at all. The end goal would be to have the 2 files mentioned above not have the /src part of the file name included in this path.

user3267755
  • 1,010
  • 1
  • 13
  • 32

4 Answers4

27

The context option is what you are looking for, in your case:

  {
      test: /\.(png|jpe?g|gif|ico)$/,
      use: [{
          loader: 'file-loader',
          options: {
              name: '[path][name].[ext]?[hash]',
              context: 'src'
          }
      }]
  }
Shikyo
  • 1,430
  • 1
  • 14
  • 25
4

Just in case you didn't solve this yourself: There is a useRelativePath option which allows to keep the relative path. Also, you can use a callback on the outputPath to change what it returns if you don't want things like ../ in there.

Doc on both things:

mvmoay
  • 1,535
  • 3
  • 15
  • 26
3

With webpack 4 you can output to custom directory, in this case parent folder's directory, as follows:

  {
    test: /\.(png|jpe?g|gif|ico)$/,
    exclude: [/some-folder/],
    use: {
      loader: "file-loader",
      options: {
        name: `[path][name].[ext]`,
        // Output into parent folder's directory
        outputPath: url => url.slice(url.indexOf(`/`) + 1)
      }
    }
  }

Output path takes url, resourcePath, context as argument in that order.

snnsnn
  • 10,486
  • 4
  • 39
  • 44
  • This sort of worked, but the actual usage of the paths was not updated, they all pointed to the old path. The files however got stored in the right place specified by the outputPath function. – redfox05 Jan 27 '21 at 16:24
0

You can strip out parts of the path with the context-option:

...
query: {
  context: path.join(__dirname, 'content'),
...
Lars Bilke
  • 4,940
  • 6
  • 45
  • 63