如何使用 Laravel Mix 将版本号添加到路径中?

How can I add the version number to the path using Laravel Mix?

我正在使用 Laravel Mix 来编译我的 JS 和 CSS 资产。我目前正在使用 .version() 来实现这一点。

问题是这会生成类似于以下内容的文件:

/css/app.css?id=03def6a69840076e8f29

在本地提供它时工作正常,但如果我使用 CDN 通过原始拉取提供此内容,则查询字符串不会强制重新拉取文件。理想情况下,我想要以下内容:

/css/03def6a69840076e8f29/app.css

或:

/css/03def6a69840076e8f29.css

这两个是不同的文件,因此它强制拉取 CDN。

如何通过 Laravel Mix 实现这一点?

您可以尝试这样调用资产:

<link rel="stylesheet" type="text/css" href="{{ mix('css/app.css') }}">

我遇到了同样的问题,想出了解决办法:

  1. 将以下行添加到 public/.htaccess:

    RewriteRule ^assets/[a-f0-9]+/(.*)$ / [L]

就在RewriteCond %{REQUEST_FILENAME} !-d

之前

这会将像 /assets/ab7320d/css/whatever.css 这样的 url 视为 /css/whatever.css

  1. 把下面的代码放到resources/assets/js/rewriteMixManifest.js

    let fs = require('fs')
    let mixManifestPath = `${process.cwd()}/public/mix-manifest.json`
    let mixFileContents = fs.readFileSync(mixManifestPath)
    let oldMapping = JSON.parse(mixFileContents)
    function updateMapping(path) {
        if(path.indexOf("?") < 1) {
            return path
        }
        let [filename, idPart] = path.split("?")
        let [_, id] = idPart.split("=")
        return `/assets/${id}${filename}`
    }
    let newContent = {}
    for(let file in oldMapping) {
        newContent[file] = updateMapping(oldMapping[file])
    }
    console.log("Manifest rewritten.")
    fs.writeFileSync(mixManifestPath, JSON.stringify(newContent, null, 2))
    
  2. package.json中,在scripts中添加以下行(就像"dev"键)

    "rewrite-manifest": "node resources/assets/js/rewriteMixManifest.js",
    
  3. 每次构建后(例如npm run production)也会运行npm run rewrite-manifest

那么 public/mix-manifest.json 文件的作用是将每个资产文件(对于 {{ mix('css/app.css') }})映射到某个字符串,该字符串实际上将转到 HTML。我的脚本重写了字符串,使版本不是查询字符串,而是路径。 .htaccess 确保正确解释路径。

路径结构当然可以根据自己的喜好更改

对我来说,它解决了 Google Cloud CDN 的问题,希望对你也有帮助