Elixir Phoenix:如何创建并向特定模板导入JavaScript文件
解决Phoenix LiveView中特定页面导入独立JavaScript文件的问题
问题场景
我正在基于Elixir Phoenix框架结合LiveView做项目实验,想编写仅在特定页面(模板)中导入的JavaScript代码,但遇到了困难。
已创建独立JavaScript文件assets/js/custom.js,参考app.js的导入方式在root.html.heex中添加测试代码:
<script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/custom.js")}></script>
原本计划下一步将其导入独立模板而非根模板,但首次测试就失败,出现路由错误:
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /assets/custom.js (MyAppWeb.Router) (my_app 0.1.0) lib/phoenix/router.ex:405: MyAppWeb.Router.call/2 (my_app 0.1.0) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.plug_builder_call/2 (my_app 0.1.0) lib/plug/debugger.ex:136: MyAppWeb.Endpoint."call (overridable 3)"/2 (my_app 0.1.0) lib/my_app_web/endpoint.ex:1: MyAppWeb.Endpoint.call/2 (phoenix 1.6.15) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4 (cowboy 2.9.0) c:/Users/arnod/Desktop/phoenixtut/my_app/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2 (cowboy 2.9.0) c:/Users/arnod/Desktop/phoenixtut/my_app/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3 (cowboy 2.9.0) c:/Users/arnod/Desktop/phoenixtut/my_app/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3 (stdlib 4.0.1) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
解决方案
1. 配置esbuild打包独立JS文件
Phoenix 1.6及以上版本默认用esbuild处理静态资源,需修改配置让custom.js作为单独入口被打包:
- 对于Phoenix 1.6,编辑
config/config.exs中的esbuild配置:
config :esbuild, version: "0.14.41", my_app: [ args: ~w(js/app.js js/custom.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*), cd: Path.expand("../assets", __DIR__), env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} ]
- 对于Phoenix 1.7+,编辑
config/runtime.exs中的esbuild部分,将js/custom.js添加到args列表里。
修改后重启Phoenix服务器,esbuild会自动把custom.js打包到priv/static/assets/目录,解决路由找不到文件的问题。
2. 在特定模板中引入JS
不要在root.html.heex全局引入,直接在目标模板(比如lib/my_app_web/templates/page/show.html.heex)中添加代码:
<script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/custom.js")}></script>
这样该JS只会在这个特定页面加载。
3. 验证调试
- 检查
priv/static/assets/目录是否生成了custom.js文件 - 开发环境可执行
mix assets.deploy更新资源,或清除浏览器缓存 - 确认
lib/my_app_web/endpoint.ex中的静态资源配置正确:
plug Plug.Static, at: "/", from: :my_app, gzip: false, only: ~w(assets fonts images favicon.ico robots.txt)
确保only列表包含assets,保证静态资源能被正确访问。
内容的提问来源于stack exchange,提问作者Astarno
相关产品推荐
相关产品推荐

