Rails 7、React和Esbuild - 生产环境下静态资产未被提供

3

我已经使用Esbuild和React从零开始创建了一个简单的Rails 7项目,以便了解它们,它们确实感觉比Webpack更高级,但我无法在生产中管理我的静态文件(即图像)。

我有一个Esbuild配置文件:

// esbuild.config.js

const path = require('path');

require("esbuild").build({
  entryPoints: ["application.jsx"],
  bundle: true,
  outdir: path.join(process.cwd(), "app/assets/builds"),
  absWorkingDir: path.join(process.cwd(), "app/javascript"),
  publicPath: "assets",
  sourcemap: true,
  watch: process.argv.includes('--watch'),
  plugins: [],
  loader: {
    '.js': 'jsx',
    '.jpg': 'file',
    '.png': 'file',
    '.MOV': 'file'
  },
}).catch(() => process.exit(1));

我将我的图片存储在app/javascript/images/文件夹中,并在React组件中导入和使用它们,例如:
import MyImage from "./images/myimage.jpg"
import styled from "styled-components";
//...

const SomeStyledComponent = styled.div`
    background-image: url(${MyImage});    
`

在开发环境中,一切都很好,Esbuild将图像复制到app/assets/builds/文件夹中,对它们进行指纹处理,并将所有图像URL的前缀设置为我的Esbuild配置的publicPath属性。例如上面的图片具有相对URLassets/myimage-FINGERPRINT.jpg,在开发中正确地提供服务。
然后,在生产环境中事情变得复杂(这里的生产环境只是为了生产而构建的Docker容器 - 我不添加Dockerfile以保持简单性,但当然可以提供)。
在我的production.rb中,我添加了以下内容:
config.public_file_server.enabled = true

(这将在稍后被环境变量替换)

资产预编译成功,我的图像位于app/public/assets/文件夹中,这次由Sprockets再次指纹化(据我所知),但现在我得到了404。我尝试更改Esbuild的publicPath并尝试直接在浏览器中获取图像,但无论我尝试什么(assetspublicpublic/assets),都没有起作用,我已经没有想法了。

我有一个临时解决方法,那就是将图像加载器更改为dataurl,但这不像是一个好的实践,因为我的编译后的javascript将会爆炸。

感谢您的帮助!

1个回答

3
我遇到了类似的问题,并通过查看https://github.com/rails/jsbundling-rails/issues/76上的答案和这个PR:https://github.com/rails/sprockets/pull/726/files,找到了正确的设置方法。在build选项中,我进行了更改。
publicPath: "assets",

to

publicPath: "/assets",

(包括前导的/,之前缺失导致使用了错误的路径)
然后添加了以下选项
assetNames: "[name]-[hash].digested",

从链接的PR中可以看出,这将防止Sprockets添加额外的指纹层。

希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接