Elixir Phoenix多CSS文件Live Reload失效问题求助
问题背景
构建Phoenix网站时配置了多个Tailwind CSS入口文件(app.css、navigation.css、home.css),但只有修改app.css时Live Reload会触发,修改其他CSS文件无反应。相关配置如下:
config.exs 配置片段
# Configure tailwind (the version is required) config :tailwind, version: "3.4.3", my_dummy_website: [ args: ~w( --config=tailwind.config.js --input=css/app.css --output=../priv/static/assets/app.css ), cd: Path.expand("../assets", __DIR__) ], navigation: [ args: ~w( --config=tailwind.config.js --input=css/navigation.css --output=../priv/static/assets/navigation.css ), cd: Path.expand("../assets", __DIR__) ], home: [ args: ~w( --config=tailwind.config.js --input=css/home.css --output=../priv/static/assets/home.css ), cd: Path.expand("../assets", __DIR__) ]
dev.exs 配置片段
watchers: [ esbuild: {Esbuild, :install_and_run, [:my_dummy_website, ~w(--sourcemap=inline --watch)]}, tailwind: {Tailwind, :install_and_run, [:my_dummy_website, ~w(--watch)]} ] ... # Watch static and templates for browser reloading. config :my_dummy_website, MyDummyWebsiteWeb.Endpoint, live_reload: [ patterns: [ ~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$", ~r"priv/gettext/.*(po)$", ~r"lib/my_dummy_website_web/(controllers|live|components)/.*(ex|heex)$" ] ]
mix.exs 配置片段
defp aliases do [ setup: ["deps.get", "assets.setup", "assets.build"], "assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"], "assets.build": [ "tailwind my_dummy_website", "tailwind navigation", "tailwind home", "esbuild my_dummy_website", ], "assets.deploy": [ "tailwind my_dummy_website --minify", "tailwind navigation --minify", "tailwind home --minify", "esbuild my_dummy_website --minify", "phx.digest" ] ] end
问题核心确实是watchers仅监听了my_dummy_website这一个Tailwind目标,其他CSS文件修改不会触发对应的构建,自然也不会触发Live Reload。下面提供两种可行的解决方案:
解决方案一:添加多个Tailwind Watcher
直接在dev.exs的watchers中为每个Tailwind目标添加独立的监听进程,修改任意CSS文件都会触发对应构建,进而触发Live Reload。
修改后的dev.exs watchers配置:
watchers: [ esbuild: {Esbuild, :install_and_run, [:my_dummy_website, ~w(--sourcemap=inline --watch)]}, tailwind: {Tailwind, :install_and_run, [:my_dummy_website, ~w(--watch)]}, tailwind_navigation: {Tailwind, :install_and_run, [:navigation, ~w(--watch)]}, tailwind_home: {Tailwind, :install_and_run, [:home, ~w(--watch)]} ]
注意每个Watcher的键名要唯一(比如用tailwind_navigation、tailwind_home区分),避免冲突。
解决方案二:合并为单一Tailwind入口(推荐)
Tailwind官方推荐使用单一入口文件,通过@import导入其他CSS模块,只需维护一个Watcher,配置更简洁,也符合Tailwind构建逻辑。
步骤1:修改app.css导入其他文件
在assets/css/app.css中导入navigation.css和home.css:
@import "./navigation.css"; @import "./home.css"; /* 原app.css内容保留 */ @tailwind base; @tailwind components; @tailwind utilities; /* ...其他自定义样式 */
步骤2:简化config.exs配置
删除navigation和home这两个Tailwind目标,只保留my_dummy_website:
config :tailwind, version: "3.4.3", my_dummy_website: [ args: ~w( --config=tailwind.config.js --input=css/app.css --output=../priv/static/assets/app.css ), cd: Path.expand("../assets", __DIR__) ]
步骤3:更新mix.exs的assets命令
修改assets.build和assets.deploy,只保留针对my_dummy_website的Tailwind命令:
defp aliases do [ setup: ["deps.get", "assets.setup", "assets.build"], "assets.setup": ["tailwind.install --if-missing", "esbuild.install --if-missing"], "assets.build": [ "tailwind my_dummy_website", "esbuild my_dummy_website", ], "assets.deploy": [ "tailwind my_dummy_website --minify", "esbuild my_dummy_website --minify", "phx.digest" ] ] end
步骤4:保持dev.exs配置不变
原watchers只监听my_dummy_website即可,所有CSS模块都被导入到app.css中,修改任意模块都会触发app.css的重新构建,进而触发Live Reload。
两种方案对比
- 方案一:适合必须输出多个独立CSS文件的场景(比如不同页面加载不同CSS),但会启动多个Tailwind进程,配置相对繁琐。
- 方案二:符合Tailwind最佳实践,减少配置复杂度,构建效率更高,推荐大多数场景使用。
内容的提问来源于stack exchange,提问作者Stefanos Anagnostou

