如何将Svelte构建生成的CSS接入Rails 7常规资产CSS管线
问题核心原因
- 现有esbuild配置未开启Svelte样式的独立提取:默认
esbuild-svelte会把组件内的Sass/CSS打包进JS文件,运行时动态注入页面head,根本不会生成预期的app/assets/builds/all.css文件 - Sprockets(Rails资产管线)的
require指令基于配置的资产查找路径解析,之前写的../builds/all.css属于跨目录相对路径,且app/assets/builds默认不在Sprockets的查找路径里,必然报文件不存在错误
具体操作步骤
1. 修改esbuild配置,开启CSS独立输出
替换esbuild.config.js的全部内容如下,核心是关闭Svelte默认的JS注入样式逻辑,配置esbuild支持JS、CSS双产物输出:
#!/usr/bin/env node var watch = process.argv.includes("--watch"); var esbuild = require('esbuild') var esbuildSvelte = require('esbuild-svelte'); var sveltePreprocess = require('svelte-preprocess'); esbuild .build({ entryPoints: ["app/javascript/application.js"], bundle: true, outdir: "app/assets/builds", entryNames: "all", // 固定输出文件名,最终生成all.js、all.css plugins: [ esbuildSvelte({ preprocess: sveltePreprocess(), compilerOptions: { css: false // 关闭Svelte默认的运行时注入样式,交给esbuild提取CSS文件 } }), ], logLevel: "debug", watch: watch }) .catch(() => process.exit(1));
修改完成后执行yarn build,确认app/assets/builds目录下同时生成all.js和all.css两个文件。
注意compilerOptions.css: false是核心配置,必须添加,否则Svelte会默认把样式打包进JS,不会生成独立CSS文件
2. 将builds目录加入Sprockets资产查找路径
打开config/initializers/assets.rb,添加如下配置:
Rails.application.config.assets.paths << Rails.root.join("app/assets/builds")
这一步是让Sprockets能直接识别builds目录下的静态资源,不需要写跨目录相对路径。
3. 修正CSS引入配置
打开app/assets/stylesheets/application.css,删掉之前写的错误相对路径引入,替换为直接引用all文件(Sprockets会自动匹配.css后缀):
/* *= require_tree . *= require all *= require_self */
这里的require all就会自动加载builds目录下esbuild生成的all.css,并把内容合并到最终的application.css产物里,完全走Rails原生资产管线。
4. 调整manifest.js配置避免重复预编译
打开app/assets/config/manifest.js,删掉原来的link_tree ../builds配置,显式指定需要预编译的builds目录下的JS文件即可,避免CSS被重复预编译:
//= link_tree ../images //= link_directory ../stylesheets .css //= link all.js
验证方法
- 执行
bin/rails assets:clobber清空旧的资产缓存 - 开发环境可以执行
yarn build --watch启动esbuild监听,同时启动Rails服务 - 访问任意页面,查看页面加载的
application.css内容,确认Svelte组件里编写的Sass样式已经被正确合并进去
注意事项
- Sprockets的
require指令不要写跨目录的../相对路径,所有资源路径都基于config.assets.paths配置的根目录解析 - 如果不需要把Svelte生成的CSS合并进
application.css,可以跳过步骤2、3,直接在manifest.js里加//= link all.css,然后在布局文件里单独加<%= stylesheet_link_tag "all" %>即可 - 开发环境下esbuild的watch模式会自动监听Svelte组件的样式改动,重新生成all.css,Sprockets会自动检测文件变更,不需要重启Rails服务
内容的提问来源于stack exchange,提问作者Matrix
相关产品推荐
相关产品推荐

