无法在Phoenix伞形应用程序中加载资产



背景

我有一个旧的雨伞应用程序,我正试图让它再次复活。为此,我决定在保护伞下添加一个phoenix项目,使用:

mix phx.new.web hello_test --no-ecto

注意--no-ecto部分,这很重要。

设置

在我的雨伞apps文件夹中运行上述命令后,我通过添加以下内容更改了雨伞的config/config.exs文件:

config :phoenix, json_library: Jason

解决了这个问题后,我转到apps/hello_test/lib/hello_test/application.ex,并在start函数中添加了以下内容:

children = [
# Start the Telemetry supervisor
HelloTest.Telemetry,
# Start the Endpoint (http/https)
HelloTest.Endpoint,
# Start a worker by calling: HelloTest.Worker.start_link(arg)
# {HelloTest.Worker, arg}
{Phoenix.PubSub, name: HelloTest.PubSub}
]

然后,我在hello_test应用程序文件夹中运行mix assets.deploy,然后运行mix phx.server

问题

现在,当加载到localhost:4000时,我希望看到一些不错的欢迎页面。相反,我得到了一个没有css的页面和一条错误消息:

16:17:44.695 [debug] Processing with HelloTest.PageController.index/2
Parameters: %{}
Pipelines: [:browser]
16:17:44.737 [info]  Sent 200 in 51ms
16:17:44.821 [info]  GET /assets/app.js
16:17:44.887 [info]  GET /assets/app.css
16:17:44.887 [debug] ** (Phoenix.Router.NoRouteError) no route found for GET /assets/app.js (HelloTest.Router)
(hello_test 0.1.0) lib/phoenix/router.ex:406: HelloTest.Router.call/2
(hello_test 0.1.0) lib/hello_test/endpoint.ex:1: HelloTest.Endpoint.plug_builder_call/2
(hello_test 0.1.0) lib/plug/debugger.ex:136: HelloTest.Endpoint."call (overridable 3)"/2
(hello_test 0.1.0) lib/hello_test/endpoint.ex:1: HelloTest.Endpoint.call/2
(phoenix 1.6.5) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
(cowboy 2.9.0) c:/Users/User/Workplace/market_manager/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.9.0) c:/Users/User/Workplace/market_manager/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
(cowboy 2.9.0) c:/Users/User/Workplace/market_manager/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3

16:17:44.897 [debug] ** (Phoenix.Router.NoRouteError) no route found for GET /assets/app.css (HelloTest.Router)
(hello_test 0.1.0) lib/phoenix/router.ex:406: HelloTest.Router.call/2
(hello_test 0.1.0) lib/hello_test/endpoint.ex:1: HelloTest.Endpoint.plug_builder_call/2
(hello_test 0.1.0) lib/plug/debugger.ex:136: HelloTest.Endpoint."call (overridable 3)"/2
(hello_test 0.1.0) lib/hello_test/endpoint.ex:1: HelloTest.Endpoint.call/2
(phoenix 1.6.5) lib/phoenix/endpoint/cowboy2_handler.ex:54: Phoenix.Endpoint.Cowboy2Handler.init/4
(cowboy 2.9.0) c:/Users/User/Workplace/market_manager/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2
(cowboy 2.9.0) c:/Users/User/Workplace/market_manager/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3
(cowboy 2.9.0) c:/Users/User/Workplace/market_manager/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3

公平地说,到目前为止所做的设置并不是微不足道的,但我通过在旧的github问题和这个社区中无休止地搜索来管理它。

然而,现在不同了。这和任何凤凰伞应用程序一样简单,但它仍然无法开箱即用。

我找到的唯一解决方案是非常旧的Phoenix版本,那些仍然使用NPM的版本。我使用的是最新版本的phoenix,所以这些解决方案不适用:

λ mix phx.new --version
Phoenix installer v1.6.5
λ elixir -v
Erlang/OTP 24 [erts-12.1.4] [source] [64-bit] [smp:6:6] [ds:6:6:10] [async-threads:1] [jit]
Elixir 1.13.1 (compiled with Erlang/OTP 22)

如何消除此错误并使我的应用程序正确运行?

我自己刚刚遇到这个问题。默认情况下,在config/dev.exs下,Endpoint配置有一个指向默认esbuild配置文件的esbuild密钥:

config :admin, AdminWeb.Endpoint,
http: [ip: {127, 0, 0, 12}, port: 4000],
url: [host: "admin.myapp.test"],
check_origin: false,
code_reloader: true,
debug_errors: true,
secret_key_base: "secret",
watchers: [
# Start the esbuild watcher by calling Esbuild.install_and_run(:default, args)
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]}
]

该配置文件在config/config.exs下定义如下:

config :esbuild,
version: "0.14.0",
default: [
args:
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../apps/myapp_web/assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
]

其指向默认web应用程序中的资产路径。为了支持多个web应用程序,您需要向config/config.exs添加第二个配置

config :esbuild,
version: "0.14.0",
default: [
args:
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../apps/myapp_web/assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
],
admin: [
args:
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../apps/admin_web/assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
],

更改密钥(在本例中为admin(和/apps/目录下的相应路径。然后返回config/dev.exs,切换端点配置,指向刚刚创建的新esbuild概要文件。

config :admin, AdminWeb.Endpoint,
http: [ip: {127, 0, 0, 12}, port: 4000],
url: [host: "admin.myapp.test"],
check_origin: false,
code_reloader: true,
debug_errors: true,
secret_key_base: "secret",
watchers: [
# Start the esbuild watcher by calling Esbuild.install_and_run(:default, args)
esbuild: {Esbuild, :install_and_run, [:admin, ~w(--sourcemap=inline --watch)]}
]

根据您的发行版配置,您可能还需要为其他环境执行此操作,但如果您正在构建资产作为发行版的一部分,则应该可以不执行此操作。

答案

因此,经过一些研究,我最终创建了一个新的雨伞项目,里面有一个儿童凤凰应用程序。这个问题不见踪影,一切都很正常。

mix new koko --umbrella
cd koko/apps
mix phx.new.web hello --no-ecto
cd hello
mix assets.deploy

所以一切都指向我的旧雨伞应用程序中的一些问题。因为我想做更多的测试,我在hello的旁边创建了另一个phoenix应用程序。

然后我能够复制这个问题。

在这一点上,我怀疑伞式应用程序会有问题,如果你试图:

  • 添加多个phoenix儿童应用程序
  • 添加一个新的phoenix child应用程序,而该项目过去已经有了(并被删除(

我无法理解为什么会出现这种情况,但我无法理解的是这里的含义:我必须用一个新的伞形应用程序重新制作我的项目,然后重新开始。

相关内容

最新更新