Skip to content

Commit 2b8f66b

Browse files
committed
Extract CSS and JS assets into dedicated plug module
The changes move CSS/JS assets from layouts into a dedicated plug module, enabling cached and immutable asset serving.
1 parent f884fec commit 2b8f66b

File tree

4 files changed

+68
-27
lines changed

4 files changed

+68
-27
lines changed

lib/oban/web/assets.ex

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
defmodule Oban.Web.Assets do
2+
@moduledoc false
3+
4+
@behaviour Plug
5+
6+
import Plug.Conn
7+
8+
phoenix_js_paths =
9+
for app <- ~w(phoenix phoenix_html phoenix_live_view)a do
10+
path = Application.app_dir(app, ["priv", "static", "#{app}.js"])
11+
Module.put_attribute(__MODULE__, :external_resource, path)
12+
path
13+
end
14+
15+
@static_path Application.app_dir(:oban_web, ["priv", "static"])
16+
17+
@external_resource css_path = Path.join(@static_path, "app.css")
18+
@external_resource js_path = Path.join(@static_path, "app.js")
19+
20+
@css File.read!(css_path)
21+
22+
@js """
23+
#{for path <- phoenix_js_paths, do: path |> File.read!() |> String.replace("//# sourceMappingURL=", "// ")}
24+
#{File.read!(js_path)}
25+
"""
26+
27+
@impl Plug
28+
def init(asset), do: asset
29+
30+
@impl Plug
31+
def call(conn, asset) do
32+
{contents, content_type} = contents_and_type(asset)
33+
34+
conn
35+
|> put_resp_header("content-type", content_type)
36+
|> put_resp_header("cache-control", "public, max-age=31536000, immutable")
37+
|> put_private(:plug_skip_csrf_protection, true)
38+
|> send_resp(200, contents)
39+
|> halt()
40+
end
41+
42+
defp contents_and_type(:css), do: {@css, "text/css"}
43+
defp contents_and_type(:js), do: {@js, "text/javascript"}
44+
45+
for {key, val} <- [css: @css, js: @js] do
46+
md5 = Base.encode16(:crypto.hash(:md5, val), case: :lower)
47+
48+
def current_hash(unquote(key)), do: unquote(md5)
49+
end
50+
end

lib/oban/web/components/layouts.ex

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
11
defmodule Oban.Web.Layouts do
22
use Oban.Web, :html
33

4-
phoenix_js_paths =
5-
for app <- ~w(phoenix phoenix_html phoenix_live_view)a do
6-
path = Application.app_dir(app, ["priv", "static", "#{app}.js"])
7-
Module.put_attribute(__MODULE__, :external_resource, path)
8-
path
9-
end
10-
11-
@static_path Application.app_dir(:oban_web, ["priv", "static"])
12-
13-
@external_resource css_path = Path.join(@static_path, "app.css")
14-
@external_resource js_path = Path.join(@static_path, "app.js")
15-
16-
@css File.read!(css_path)
4+
embed_templates "layouts/*"
175

18-
@js """
19-
#{for path <- phoenix_js_paths, do: path |> File.read!() |> String.replace("//# sourceMappingURL=", "// ")}
20-
#{File.read!(js_path)}
21-
"""
6+
defp asset_path(conn, asset) when asset in [:css, :js] do
7+
hash = Oban.Web.Assets.current_hash(asset)
228

23-
def render("app.css"), do: @css
24-
def render("app.js"), do: @js
9+
# prefix = conn.private.phoenix_router.__live_dashboard_prefix__()
10+
prefix = "/oban"
2511

26-
embed_templates "layouts/*"
12+
Phoenix.VerifiedRoutes.unverified_path(
13+
conn,
14+
conn.private.phoenix_router,
15+
"#{prefix}/#{asset}-#{hash}"
16+
)
17+
end
2718

2819
def logo(assigns) do
2920
~H"""

lib/oban/web/components/layouts/root.html.heex

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
type="image/png"
1616
/>
1717

18-
<style phx-track-static nonce={@csp_nonces.style}>
19-
<%= raw(render("app.css")) %>
20-
</style>
18+
<link rel="stylesheet" nonce={@csp_nonces.style} href={asset_path(@conn, :css)} />
2119

2220
<script nonce={@csp_nonces.script}>
2321
const wantsDark = window.matchMedia("(prefers-color-scheme: dark)").matches
@@ -29,13 +27,12 @@
2927
document.documentElement.classList.remove("dark")
3028
}
3129
</script>
30+
31+
<script nonce={@csp_nonces.script} src={asset_path(@conn, :js)} defer>
32+
</script>
3233
</head>
3334

3435
<body class="min-h-screen antialiased bg-gray-200 dark:bg-gray-950 text-gray-900 dark:text-gray-100 transition duration-200 ease-out">
3536
{@inner_content}
3637
</body>
37-
38-
<script phx-track-static type="text/javascript" nonce={@csp_nonces.script}>
39-
<%= raw(render("app.js")) %>
40-
</script>
4138
</html>

lib/oban/web/router.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ defmodule Oban.Web.Router do
194194
{session_name, session_opts, route_opts} = Oban.Web.Router.__options__(prefix, opts)
195195

196196
live_session session_name, session_opts do
197+
get "/css-:md5", Oban.Web.Assets, :css, as: :oban_web_asset
198+
get "/js-:md5", Oban.Web.Assets, :js, as: :oban_web_asset
199+
197200
live "/", Oban.Web.DashboardLive, :home, route_opts
198201
live "/:page", Oban.Web.DashboardLive, :index, route_opts
199202
live "/:page/:id", Oban.Web.DashboardLive, :show, route_opts

0 commit comments

Comments
 (0)