Is there a way to disable filenameHashing only for

2020-06-28 02:50发布

问题:

After building my website with Vue.js 2.6.2 using vue-cli, I encountered a problem with static resources (images in this case). Webpack bundles them up in the /img/ folder which is fine, but the images are given hashes like image_demo.25d62d92.png which is causing issues when trying to access those resources from an external source e.g. from another website.

There is an option for webpack to disable filenameHashing altogether, but that too great a sacrifice to not have the cache control for all the orher images on the website.

The desired solution is the option to have only some hand picked resources with their default names without the extra hash, while the other resources get the default hash for cache control.

回答1:

Yes, there is a way. You will need to override the 'images' rule that vue-cli comes with.

vue inspect --rule images yields the following:

$ vue inspect --rule images
/* config.module.rule('images') */
{
  test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 4096,
        fallback: {
          loader: 'file-loader',
          options: {
            name: 'img/[name].[hash:8].[ext]'
          }
        }
      }
    }
  ]
}

(Protip: vue inspect is a useful tool for figuring out why things behave like they do when building with vue-cli)

All images

vue-cli recommends webpack-chain for 'advanced' configuration. I'm personally not a fan, but if you want to remove hashes for all images, you should probably modify the 'images' rule. Edit vue.config.js like so:

module.exports = {
  // ...
  chainWebpack: (config) => {
    config.module
      .rule("images")
      .use("url-loader")
      .loader("url-loader")
      .tap((options) => {
        options.fallback.options.name = "img/[name].[ext]"
        return options
      })
  }
  // ...
}

Specific images

In my case I wanted to remove hashes only for a specific group of images with a unique prefix, so I added the following to configureWebpack in vue.config.js:

module.exports = {
  // ...
  configureWebpack: {
    module: {
      rules: [
        {
          test: /unique-prefix-\d*\.png/, // <= modify this to suit your needs
          use: [
            {
              loader: "url-loader",
              options: {
                limit: 4096,
                fallback: {
                  loader: "file-loader",
                  options: {
                    name: "img/[name].[ext]", // <= note how the hash is removed
                  },
                },
              },
            },
          ],
        },
      ],
    },
  // ...
}

It could probably be done with webpack-chain as well, but I prefer the more vanilla Webpack config format.