我用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
,并尝试过直接在浏览器中获取图像,但无论我尝试什么(assets
、public
、public/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添加额外的指纹层。
我希望这能有所帮助。