Firebase Hosting部署CRA应用如何将build目录设为站点根目录
在对应目录结构下执行 firebase deploy --only hosting 命令时,Firebase会部署整个ui文件夹的内容,导致必须访问 http://my-app.web.app/build 路径才能打开应用。
需要将firebase.json中predeploy步骤生成的build文件夹内容部署为站点根目录,最终实现my-app/ui/build/index.html可直接通过http://my-app.web.app根路径访问。
曾尝试在firebase.json中配置"public": "ui/build",但触发如下报错,提示找不到ui/build/package.json:
npm ERR! enoent ENOENT: no such file or directory, open 'C:\Users\me\Projects\my-app\ui\build\package.json'
已知该报错是因为public配置为ui/build后,部署流程会在该路径下查找package.json执行构建,需要找到正确配置方式,实现从ui目录执行构建命令,同时将生成的build文件夹内容部署为站点根目录。
- my-app
- functions/
- ui/
- build(执行
npm run build后生成) - src/
- whatever.tsx
- build(执行
- .firebaserc
- firebase.json
- firestore.indexes.json
- firestore.rules
{ "firestore": { "rules": "firestore.rules", "indexes": "firestore.indexes.json" }, "functions": { "predeploy": [ "npm --prefix \"$RESOURCE_DIR\" run build" ], "source": "functions" }, "hosting": { "predeploy": [ "npm --prefix \"$RESOURCE_DIR\" run build" ], // 问题配置行 "public": "ui", "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ], "rewrites": [ { "source": "**", "destination": "/index.html" } ] }, "emulators": { "auth": { "port": 9099 }, "functions": { "port": 5001 }, "firestore": { "port": 8080 }, "hosting": { "port": 5000 }, "ui": { "enabled": true } } }
报错根因是hosting配置中的$RESOURCE_DIR变量默认取public字段配置的路径作为执行上下文,当public设为ui/build时,predeploy脚本会自动到build目录下查找package.json执行构建,自然会报文件不存在。
直接修改hosting段的两处配置即可:
- 将
public字段值改为ui/build,指定部署的静态资源根目录为构建产物文件夹 - 把predeploy脚本中的
$RESOURCE_DIR替换为固定路径ui,强制构建命令在ui目录下执行,不依赖public路径变量
修改后的hosting配置段:
"hosting": { "predeploy": [ "npm --prefix \"ui\" run build" ], "public": "ui/build", "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ], "rewrites": [ { "source": "**", "destination": "/index.html" } ] }
配置完成后重新执行firebase deploy --only hosting,流程会先进入ui目录执行构建生成build产物,再将build目录下的所有内容发布到站点根路径,直接访问http://my-app.web.app即可打开应用,无需追加/build路径。
内容的提问来源于stack exchange,提问作者oooyaya

