buffalo build 不打包 assets/ 和 templates/,因默认仅处理 public/ 目录且不触发前端构建;需先执行 buffalo dev 或 npm run build 生成 public/,或改用 packr2 //go:embed 显式嵌入资源。

buffalo build 为什么打包不出 assets/ 和 templates/
因为 buffalo build 默认只打包 public/ 目录下已构建好的文件,它不处理源码级的 assets/(如 SASS、TS)或 templates/(Plush 模板),更不会自动触发 Webpack 构建。如果你删了 webpack.config.js 或禁用了前端构建,public/ 就是空的,buffalo build 自然打了个寂寞。
常见错误现象:buffalo build 成功,但运行时访问 /assets/app.css 返回 404,或渲染报错 template: "index.html" not found。
- 确认你是否执行过
buffalo dev或手动运行过npm run build—— 这步必须先产出public/内容 - 若项目是纯 API 模式(没加
--with-nodejs),assets/目录本就不该存在,强行保留只会误导构建流程 -
buffalo build不会读取assets/或templates/,除非你显式启用 packr 或//go:embed
用 packr/v2 手动内嵌资源的正确姿势
这是目前最可控、兼容性最好的方式:绕过 Buffalo 的 asset pipeline,自己声明哪些目录要打进二进制,并在代码里加载。
先装 CLI 工具:go install github.com/gobuffalo/packr/v2/packr2@latest,确保 $GOPATH/bin 在 $PATH 中,验证用 packr2 version。
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 在项目根目录新建
box.go,内容类似:package main <p>import "github.com/gobuffalo/packr/v2"</p><p>var ( AssetsBox = packr.New("assets", "./assets") TemplatesBox = packr.New("templates", "./templates") ) - 运行
packr2生成packrd.go—— 这个文件必须提交进 Git,否则 CI 构建时 panic - 在
app.go初始化阶段调用AssetsBox.Walk(...)或TemplatesBox.Find(...),不能等到路由 handler 里才访问 - 别混用 packr 和
//go:embed同一路径,它们互不感知,会各自打包一份
Go 1.16+ 推荐直接用 //go:embed
如果你不用旧版 Go,且不需要开发时“改完文件立刻生效”这种动态能力,//go:embed 是更轻量、更安全的选择——零中间文件、类型安全、无额外工具链依赖。
示例写法:
package app
<p>import "embed"</p><p>//go:embed assets/<em> templates/</em>
var fs embed.FS</p><p>func App() *buffalo.App {
app := buffalo.New(buffalo.Options{})
app.Use(func(next buffalo.Handler) buffalo.Handler {
return func(c buffalo.Context) error {
// 用 fs.ReadFile("assets/app.css") 或 fs.ReadDir("templates/")
return next(c)
}
})
return app
}
-
//go:embed支持通配符(assets/**)、子目录(templates/*.html),但不支持排除模式 - 必须声明为包级变量,且
embed.FS不能跨 package 使用;如果actions/需要读模板,得把fs传进去或设为全局 - 开发时改了
assets/文件,必须go run或go build才能生效,没有热重载
最容易被忽略的初始化时机问题
无论用 packr 还是 //go:embed,资源 box 必须在 App() 函数执行前完成初始化,否则 buffalo dev 或 buffalo build 启动时会因找不到资源 panic。
典型错误写法:
// ❌ 错误:在 handler 里才初始化 box
func HomeHandler(c buffalo.Context) error {
box := packr.New("templates", "./templates") // 迟了!App 已启动
return c.Render(200, r.HTML("index.html"))
}
- 所有
packr.New或//go:embed变量必须放在main或app包顶层 - 如果用了
buffalo dev,它会自动 reload,但 packr box 不会自动重建——改了assets/后得手动再跑一次packr2 - CI 构建时若漏掉
packr2步骤或packrd.go未提交,错误往往表现为 “box not found” 或 “open /tmp/xxx: no such file”,而不是明确的资源缺失提示

















