Rails项目切换Esbuild后Tailwind无法运行,求调试方案
问题描述
将Rails应用从Webpacker切换到Esbuild后,运行bin/dev时JS进程执行命令后很快退出(返回码0),导致整个服务终止。单独运行相关命令无报错,添加--trace参数也未获取到额外信息。
运行日志
16:43:45 web.1 | started with pid 99535 16:43:45 css.1 | started with pid 99536 16:43:45 js.1 | started with pid 99537 16:43:45 css.1 | yarn run v1.22.19 16:43:45 js.1 | yarn run v1.22.19 16:43:45 css.1 | $ tailwindcss --postcss --minify -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --watch 16:43:45 js.1 | $ node esbuild.config.mjs --watchcss: bin/rails tailwindcss:watch 16:43:46 js.1 | Done in 0.41s. 16:43:46 css.1 | 16:43:46 css.1 | Rebuilding... 16:43:46 js.1 | exited with code 0 16:43:46 system | sending SIGTERM to all processes 16:43:46 web.1 | terminated by SIGTERM 16:43:46 css.1 | exited with code 1
相关配置文件
tailwind.config.js
const colors = require('tailwindcss/colors') const defaultTheme = require('tailwindcss/defaultTheme') /** @type {import('tailwindcss').Config */ module.exports = { darkMode: 'class', plugins: [ require('@tailwindcss/aspect-ratio'), require('@tailwindcss/forms'), require('@tailwindcss/typography'), ], content: [ './app/components/**/*.rb', './app/helpers/**/*.rb', './app/javascript/**/*.js', './app/views/**/*.erb', './app/views/**/*.haml', './app/views/**/*.slim', './lib/jumpstart/app/views/**/*.erb', './lib/jumpstart/app/helpers/**/*.rb', ], theme: { extend: { colors: { purple: colors.purple, primary: colors.blue, secondary: colors.gray, tertiary: colors.gray, danger: colors.red, success: colors.green, info: colors.blue, warning: colors.yellow, }, fontFamily: { sans: ['Inter', ...defaultTheme.fontFamily.sans], }, }, }, future: { }, }
esbuild.config.mjs
import * as esbuild from "esbuild" import path from "path" import rails from "esbuild-rails" import chokidar from "chokidar" import http from "http" import { setTimeout } from "timers/promises" const clients = [] const entryPoints = [ "application.js", "administrate.js" ] const watchDirectories = [ "./app/javascript/**/*.js", "./app/views/**/*.html.erb", "./app/assets/builds/**/*.css", // Wait for cssbundling changes "./config/locales/**/*.yml", ] const config = { absWorkingDir: path.join(process.cwd(), "app/javascript"), bundle: true, entryPoints: entryPoints, minify: process.env.RAILS_ENV == "production", outdir: path.join(process.cwd(), "app/assets/builds"), plugins: [rails()], sourcemap: process.env.RAILS_ENV != "production" } async function buildAndReload() { // Foreman & Overmind assign a separate PORT for each process const port = parseInt(process.env.PORT || 3200) console.log(`Esbuild is listening on port ${port}`) const context = await esbuild.context({ ...config, banner: { js: ` (() => { if (typeof EventSource !== 'undefined') { new EventSource("http://localhost:${port}").onmessage = () => location.reload() } })(); `, } }) // Reload uses an HTTP server as an even stream to reload the browser http .createServer((req, res) => { return clients.push( res.writeHead(200, { "Content-Type": "text/event-stream", "Cache-Control": "no-cache", "Access-Control-Allow-Origin": "*", Connection: "keep-alive", }) ) }) .listen(port) await context.rebuild() console.log("[reload] initial build succeeded") let ready = false chokidar .watch(watchDirectories) .on("ready", () => { console.log("[reload] ready") ready = true }) .on("all", async (event, path) => { if (ready === false) return if (path.includes("javascript")) { try { await setTimeout(20) await context.rebuild() console.log("[reload] build succeeded") } catch (error) { console.error("[reload] build failed", error) } } clients.forEach((res) => res.write("data: update\n\n")) clients.length = 0 }) } if (process.argv.includes("--reload")) { buildAndReload() } else if (process.argv.includes("--watch")) { let context = await esbuild.context({...config, logLevel: 'info'}) context.watch() } else { esbuild.build(config) }
问题排查与解决
修复Procfile.dev命令格式
日志显示JS进程命令被错误解析为node esbuild.config.mjs --watchcss: bin/rails tailwindcss:watch,这是Procfile.dev里的命令混写导致的。打开Procfile.dev,将JS和CSS进程命令分开:web: bin/rails server -p 3000 js: yarn build --watch css: bin/rails tailwindcss:watch确保每个进程的命令独立,避免参数混淆。
验证esbuild watch模式
单独运行yarn build --watch,检查进程是否持续运行。如果仍退出,在esbuild.config.mjs的--watch分支添加日志输出,确认代码逻辑是否执行:else if (process.argv.includes("--watch")) { console.log("Starting esbuild watch mode...") let context = await esbuild.context({...config, logLevel: 'info'}) context.watch() }检查依赖完整性
运行yarn install重新安装所有依赖,确保esbuild、esbuild-rails、chokidar等包版本兼容且安装完整。开启调试日志
在esbuild.config.mjs的config对象中添加logLevel: 'debug',运行yarn build --watch查看详细构建日志,定位隐性问题。
内容的提问来源于stack exchange,提问作者Jamie Crone
相关产品推荐
相关产品推荐

