查看源代码 资产管理
除了生成 HTML,大多数 Web 应用程序还有各种资产(JavaScript、CSS、图像、字体等等)。
从 Phoenix v1.7 开始,新应用程序使用 esbuild 通过 Elixir esbuild 包装器 来准备资产,以及使用 tailwindcss 通过 Elixir 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"
在你的 assets 目录中运行
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"
新应用程序使用这种第三种方法来导入 Heroicons,避免在可能只使用几个甚至不使用任何图标的情况下提供所有图标的副本,避免使用 Node.js 和
npm
,并跟踪一个易于更新的显式版本,这要归功于 Mix。需要注意的是,git 依赖项不能被 Hex 包使用,因此,如果你打算将你的项目发布到 Hex,请考虑将文件作为供应商提供。
图像、字体和外部文件
如果你在 CSS 或 JavaScript 文件中引用了外部文件,esbuild
会尝试验证和管理它们,除非另有说明。
例如,假设你想从你的 CSS 文件中引用 priv/static/images/bg.png
,在 /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 包装器)不允许你使用 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
依赖项。