查看原始碼 資產管理
除了製作 HTML 外,大部分的 web 應用程式都有各種資產(JavaScript、CSS、圖片、字型等等)。
從 Phoenix v1.7 開始,新的應用程式使用 esbuild 來透過 Elixir esbuild 封裝器 準備資產,並透過 Elixir tailwindcss 封裝器 使用 tailwindcss 製作 CSS。與 esbuild
和 tailwind
直接整合的意思是,新產生的應用程式不必仰賴 Node.js 或外部建置系統(例如 Webpack)。
您的 JavaScript 通常會放在 "assets/js/app.js",而 esbuild
會將它萃取到 "priv/static/assets/app.js"。在開發階段,這會透過 esbuild
偵測器自動完成。在製作階段,這會透過執行 mix assets.deploy
完成。
esbuild
也可以處理您的 CSS 檔案,但預設情況下 tailwind
會處理所有的 CSS 建置。
最後,其他通常不需要預先處理的資產,會直接傳送至 "priv/static"。
第三方 JS 套件
如果您想要匯入 JavaScript 相依性,您至少有三個選項可以將它們加入到您的應用程式裡
在您的專案內建置這些相依性,並使用相對路徑在您的 "assets/js/app.js" 中匯入它們
import topbar from "../vendor/topbar"
在您的資產目錄中呼叫
npm install topbar --save
,而esbuild
就會自動選取它們import topbar from "topbar"
使用 Mix 從原始儲存庫追蹤相依性
# mix.exs {:topbar, github: "buunguyen/topbar", app: false, compile: false}
執行
mix deps.get
來取得相依性,然後匯入它import topbar from "topbar"
新的應用程式會使用這第三種方法來匯入 Heroicon,在您可能只會使用一些或甚至完全不使用所有圖示的情況下,避免同時打包所有圖示的副本,避免 Node.js 和
npm
,並追蹤一個清楚的版本,而這要感謝 Mix 可以輕鬆更新。重要的是要注意,Hex 套件無法使用 git 相依性,因此如果您打算將您的專案發佈到 Hex 上,請考慮改為建置檔案。
圖片、字型和外部檔案
如果您在 CSS 或 JavaScript 檔案中參照外部檔案,esbuild
會嘗試驗證和管理它們,除非另有說明。
例如,想像您想要參照 priv/static/images/bg.png
,並從 CSS 檔案中以 /images/bg.png
提供服務
body {
background-image: url(/images/bg.png);
}
可能會以以下訊息失敗
error: Could not resolve "/images/bg.png" (mark it as external to exclude it from the bundle)
由於影像已由 Phoenix 管理,因此需要將 /images
(以及 /fonts
) 的所有資源標記為外部,正如錯誤訊息所述。這是 Phoenix 在 v1.6.1+ 之後的新應用程式所執行的預設動作。使用者會在 config/config.exs
中找到
args: ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
如果需要參照其他目錄,則需要相應地更新以上的引數。請注意,執行 mix phx.digest
會為 priv/static
中的所有資源建立摘要檔,因此影像和字型仍會被快取清除。
Esbuild 外掛
Phoenix 的預設 esbuild
組態(透過 Elixir wrapper)不允許你使用 esbuild 外掛。如果想要使用 esbuild 外掛,舉例來說,將 SASS 檔編譯為 CSS,可以將預設建置系統替換為自訂建置指令碼。
以下是透過 Node.JS 使用 esbuild 的自訂建置範例。首先,需要在開發環境中安裝 Node.js,並讓它可用於生產建置步驟。
接著需要將 esbuild
新增至 Node.js 套件和 Phoenix 套件。在 assets
目錄中執行
$ npm install esbuild --save-dev
$ npm install ../deps/phoenix ../deps/phoenix_html ../deps/phoenix_live_view --save
或,對於 Yarn
$ yarn add --dev esbuild
$ yarn add ../deps/phoenix ../deps/phoenix_html ../deps/phoenix_live_view
下一步,新增一個自訂 JavaScript 建置指令碼。我們將範例命名為 assets/build.js
const esbuild = require("esbuild");
const args = process.argv.slice(2);
const watch = args.includes('--watch');
const deploy = args.includes('--deploy');
const loader = {
// Add loaders for images/fonts/etc, e.g. { '.svg': 'file' }
};
const plugins = [
// Add and configure plugins here
];
// Define esbuild options
let opts = {
entryPoints: ["js/app.js"],
bundle: true,
logLevel: "info",
target: "es2017",
outdir: "../priv/static/assets",
external: ["*.css", "fonts/*", "images/*"],
nodePaths: ["../deps"],
loader: loader,
plugins: plugins,
};
if (deploy) {
opts = {
...opts,
minify: true,
};
}
if (watch) {
opts = {
...opts,
sourcemap: "inline",
};
esbuild
.context(opts)
.then((ctx) => {
ctx.watch();
})
.catch((_error) => {
process.exit(1);
});
} else {
esbuild.build(opts);
}
本指令碼涵蓋下列使用案例
node build.js
:建置用於開發與測試 (適用於 CI)node build.js --watch
:同上,但會不斷監看是否有變更node build.js --deploy
:建置用於生產的縮小資源
修改 config/dev.exs
,使每當你變更檔案時,指令碼就會執行,並取代 watchers
下現有的 :esbuild
組態
config :hello, HelloWeb.Endpoint,
...
watchers: [
node: ["build.js", "--watch", cd: Path.expand("../assets", __DIR__)]
],
...
修改 mix.exs
中的 aliases
任務,以在 mix setup
期間安裝 npm
套件,並在 mix assets.deploy
上使用新的 esbuild
defp aliases do
[
setup: ["deps.get", "ecto.setup", "cmd --cd assets npm install"],
...,
"assets.deploy": ["cmd --cd assets node build.js --deploy", "phx.digest"]
]
end
最後,從 config/config.exs
中移除 esbuild
組態,並從 mix.exs
中的 deps
函數移除相依項目,就大功告成了!
其他 JS 建置工具
如果你正在撰寫 API 或是想要使用另一個資源建置工具,可能想要移除 esbuild
Hex 套件 (請參閱以下步驟)。隨後必須遵循第三方工具所需要的額外步驟。
移除 esbuild
- 移除
config/config.exs
和config/dev.exs
中的esbuild
組態, - 移除在
mix.exs
中定義的assets.deploy
任務, - 移除
mix.exs
中的esbuild
相依性, - 移除
esbuild
相依性
$ mix deps.unlock esbuild
其他 CSS 架構
預設情況下,Phoenix 會使用 tailwind
函式庫和它的預設外掛程式產生 CSS。
如果你要使用外部 tailwind
外掛程式或其他 CSS 架構,你應該取代 tailwind
Hex 套件(請參閱下列步驟)。然後你可以使用 esbuild
外掛程式(如上所述),甚至完全引入一個獨立的架構。
移除 tailwind
- 移除
config/config.exs
和config/dev.exs
中的tailwind
組態, - 移除在
mix.exs
中定義的assets.deploy
任務, - 移除
mix.exs
中的tailwind
相依性, - 移除
tailwind
相依性
$ mix deps.unlock tailwind
你也可以選擇移除和刪除 heroicons
相依性。