How to access the actual name/path/url of a static resource hashed during copy webpack plugin

Viewed 229

So I have resources that I hash with copy webpack plugin.

{
            from: "data/json/*.json",
            to: "data/json/[name].[hash:6].json",
},

Now during runtime I need to get the access to the actual url of these json files. What I would ideally like is to be able to fetch this url during runtime so that I can do something like

let name = "tiles";
const tileDataUrl = requireUrl(`data/json/${name}.json`);
fetch(tileDataUrl) // tileData Url here would  data/json/tiles.abc34f.json


...

What I need is a method requireUrl (or whatever it might be called) which returns the actual url of the static resources with hashes during runtime.

( For anyone wondering, the hashes are used to do cache busting here)

Please and thank you :)

1 Answers

Assuming you're on version 5, Webpack asset modules will provide what you want without the need for copy-webpack-plugin. Webpack can recognize a require statement with expressions. Webpack will automatically included all possibly matching files for you without additional configuration. In this case you may want to watch out for optimizations where Webpack knows that name is set to "tiles". Here's the required addition to your config:

module.exports = {
   module: {
      rules: [
          {
              test: /data\/json\/.+\.json$/
              type: 'asset/resource',
              generator: {
                  // Look at https://webpack.js.org/configuration/output/#template-strings to see additional template strings.
                  filename: '[path][name].[hash:6][ext]'
              }
          }
      ]
   }
}

Alternatively for Webpack 4 you can add file-loader as a dependency and use it with this equivalent config addition:

module.exports = {
   module: {
      rules: [
          {
              test: /data\/json\/.+\.json$/
              loader: 'file-loader',
              options: {
                  name: '[path][name].[hash:6][ext]'
              }
          }
      ]
   }
}

Either way your code will now be able to work simply as follows:

let name = "tiles";
const tileDataUrl = require(`data/json/${name}.json`); // tileDataUrl will display the interpolated filename.
fetch(tileDataUrl);
Related