vite:将静态资产(带有缓存清除)添加到构建中

Die*_*ski 3 http-caching webpack vue.js esbuild vite

我有大型静态文件,应该使用 HTTP 缓存的哈希值来破坏这些文件。如果我将它们放入public目录中,vite 只会复制它们,而不在文件名中附加哈希值。如果我将它们放入assets目录中,vite 会忽略它们,因为它们不是直接从代码引用,而是通过 XHR 请求加载。\n目录结构非常标准:

\n
/\n\xe2\x94\x9c\xe2\x94\x80 src/\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 assets/\n\xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 locales/\n\xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 en.json\n\xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 de.json\n\xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 ru.json\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 main.js\n\xe2\x94\x9c\xe2\x94\x80 public/\n\xe2\x94\x9c\xe2\x94\x80 dist/\n\xe2\x94\x9c\xe2\x94\x80 index.html\n
Run Code Online (Sandbox Code Playgroud)\n

我如何告诉 vite 复制那些在文件名中添加了哈希值的文件,以及如何获取生成的文件名以在 XHR 请求中使用它们?

\n

ton*_*y19 5

一种解决方案是使用url后缀导入.json

// BEFORE:
// fetch('@/assets/locales/en.json').then(res => res.json()).then(json => /*...*/)

// AFTER:                                   
import enUrl from '@/assets/locales/en.json?url'
fetch(enUrl).then(res => res.json()).then(json => /*...*/)
Run Code Online (Sandbox Code Playgroud)

如果有很多语言环境文件,您可以使用以下命令将它们全部导入import.meta.glob

async function loadLocales() {
  const localeFiles = await import.meta.glob('@/assets/locales/*.json', { as: 'url', eager: true })

  // get basename of file from path
  const basename = s => s.split('/').at(-1).split('.').at(0)

  // create map of locale name to file -> { en: '/src/assets/locales/en-abc123.json' }
  const resolvedUrls = {}
  for (const [key, filePath] of Object.entries(localeFiles)) {
    resolvedUrls[basename(key)] = filePath
  }
  return resolvedUrls
}
Run Code Online (Sandbox Code Playgroud)

如果您的文件小于 4KB,它们将作为数据 URL 内联,并且您不会在构建输出中看到相应的文件。要禁用此内联,请设置build.assetsInlineLimit0

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    assetsInlineLimit: 0,
  },
})
Run Code Online (Sandbox Code Playgroud)

此外,要将构建的语言环境文件保留在 下dist/locales,您必须配置资产命名:

// vite.config.js
import { normalizePath, defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        assetFileNames(assetInfo) {
         // output src/assets/locales/*.json files to dist/locales
          const pathToFile = normalizePath(assetInfo.name)
          if (/\/src\/assets\/locales\/.*\.json$/.test(pathToFile)) {
            return 'locales/[name]-[hash].json'
          }

          return 'assets/[name]-[hash][extname]'
        },
      },
    },
  },
})
Run Code Online (Sandbox Code Playgroud)

演示