查看原始碼 資產管理

除了製作 HTML 外,大部分的 web 應用程式都有各種資產(JavaScript、CSS、圖片、字型等等)。

從 Phoenix v1.7 開始,新的應用程式使用 esbuild 來透過 Elixir esbuild 封裝器 準備資產,並透過 Elixir tailwindcss 封裝器 使用 tailwindcss 製作 CSS。與 esbuildtailwind 直接整合的意思是,新產生的應用程式不必仰賴 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 相依性,您至少有三個選項可以將它們加入到您的應用程式裡

  1. 在您的專案內建置這些相依性,並使用相對路徑在您的 "assets/js/app.js" 中匯入它們

    import topbar from "../vendor/topbar"
  2. 在您的資產目錄中呼叫 npm install topbar --save,而 esbuild 就會自動選取它們

    import topbar from "topbar"
  3. 使用 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

  1. 移除 config/config.exsconfig/dev.exs 中的 esbuild 組態,
  2. 移除在 mix.exs 中定義的 assets.deploy 任務,
  3. 移除 mix.exs 中的 esbuild 相依性,
  4. 移除 esbuild 相依性
$ mix deps.unlock esbuild

其他 CSS 架構

預設情況下,Phoenix 會使用 tailwind 函式庫和它的預設外掛程式產生 CSS。

如果你要使用外部 tailwind 外掛程式或其他 CSS 架構,你應該取代 tailwind Hex 套件(請參閱下列步驟)。然後你可以使用 esbuild 外掛程式(如上所述),甚至完全引入一個獨立的架構。

移除 tailwind

  1. 移除 config/config.exsconfig/dev.exs 中的 tailwind 組態,
  2. 移除在 mix.exs 中定義的 assets.deploy 任務,
  3. 移除 mix.exs 中的 tailwind 相依性,
  4. 移除 tailwind 相依性
$ mix deps.unlock tailwind

你也可以選擇移除和刪除 heroicons 相依性。