Rails 7, React & Esbuild - 在生产中未提供的静态资产



我用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/文件夹中,对它们进行指纹识别,并使用我的Esbuild配置的publicPath属性预处理所有图像url。例如,上面的图像具有在开发中正确提供的相对urlassets/myimage-FINGERPRINT.jpg

然后,生产中的事情变得复杂起来(这里的生产只是为生产而构建的Docker容器——我添加Dockerfile并不是为了保持简单,因为我认为这不会有帮助,但当然很乐意提供它(。

在我的production.rb中,我添加了以下内容:

config.public_file_server.enabled = true

(稍后将被环境变量取代(

资产预编译成功,我的图像在app/public/assets/文件夹中,这次由Sprockets再次指纹(据我所知(,但现在我得到了404。我尝试过更改EsbuildpublicPath,并尝试过直接在浏览器中获取图像,但无论我尝试什么(assetspublicpublic/assets(,都无济于事,我的想法也快用完了。

我有一个临时的解决方案,就是将图像的加载程序更改为dataurl,但这感觉不是一个好的做法,因为我编译的javascript即将爆炸。

谢谢你的帮助!

我遇到了类似的问题,通过查看https://github.com/rails/jsbundling-rails/issues/76以及本PR:https://github.com/rails/sprockets/pull/726/files

我能够找到合适的设置。在build选项中,我更改了

publicPath: "assets",

publicPath: "/assets",

(包括之前丢失的导致使用错误路径的前导/(

然后添加以下选项

assetNames: "[name]-[hash].digested",

从关联的PR中可以看出,这将阻止Sprockets添加额外的指纹层。

我希望这能有所帮助。

最新更新