我正在开发一个使用 Firebase 应用托管(不是 Firebase 托管)部署的 Next.js 项目,并且我最近将 Cloud Functions 添加到了我的设置中。我取消了示例函数的注释:
import {onRequest} from "firebase-functions/v2/https";
import * as logger from "firebase-functions/logger";
export const helloWorld = onRequest((request, response) => {
logger.info("Hello logs!", {structuredData: true});
response.send("Hello from Firebase!");
});
当我运行时,Cloud Functions 的部署工作正常:
firebase deploy --only functions
但是,当我使用 App Hosting 部署完整的应用程序时,遇到错误,指示无法找到某些依赖项。我怀疑这个问题与应用程序托管如何处理我的应用程序和云功能的依赖关系有关。
以下是我的设置的简要概述:
/project_name
├── /app
├── /components
├── /functions
│ ├── /lib
│ ├── /src
│ │ └── index.ts
│ ├── package.json
│ ├── tsconfig.json
│ └── .eslintrc.js
├── /public
├── .firebaserc
├── firebase.json
├── apphosting.yaml
├── .gitignore
├── package.json
├── package-lock.json
├── next.config.js
├── tsconfig.json
├── next.config.mjs
./functions/package.json:
{
"name": "functions",
"scripts": {
"lint": "eslint --ext .js,.ts .",
"build": "tsc",
"build:watch": "tsc --watch",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "18"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^12.1.0",
"firebase-functions": "^6.0.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.12.0",
"@typescript-eslint/parser": "^5.12.0",
"eslint": "^8.9.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-import": "^2.25.4",
"firebase-functions-test": "^3.1.0",
"typescript": "^4.9.0"
},
"private": true
}
./functions/tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017"
},
"compileOnSave": true,
"include": [
"src"
]
}
./functions/.eslintrc.js:
module.exports = {
root: true,
env: {
es6: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:import/typescript",
"google",
"plugin:@typescript-eslint/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
project: ["tsconfig.json", "tsconfig.dev.json"],
sourceType: "module",
},
ignorePatterns: [
"/lib/**/*", // Ignore built files.
"/generated/**/*", // Ignore generated files.
],
plugins: [
"@typescript-eslint",
"import",
],
rules: {
"quotes": ["error", "double"],
"import/no-unresolved": 0,
"indent": ["error", 2],
},
};
./firebase.json:
{
"emulators": {
"auth": { "port": 9099 },
"functions": { "port": 5001 },
"firestore": { "port": 8080 },
"storage": { "port": 9199 },
"ui": { "enabled": true },
"singleProjectMode": true
},
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "firebasestorage.rules"
},
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log",
"*.local"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
]
}
./tsconfig.json:
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
./package.json:
{
"name": "project_name",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"browser-image-compression": "^2.0.2",
"dotenv": "^16.4.5",
"firebase": "^10.13.1",
"next": "14.2.11",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.11",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}
问题: 完整的应用程序部署(使用应用程序托管)失败,并出现与缺少依赖项相关的错误。但是,仅部署 Cloud Functions 效果很好。我怀疑 App Hosting 构建项目时管理应用程序依赖项和函数依赖项的方式存在冲突。
我预计,由于独立部署功能可以工作,因此通过应用程序托管部署时也可以工作。
我需要什么帮助:
我能够通过排除 ./tsconfig.json 中的函数文件夹并使用
firebase deploy --only functions
: 单独部署函数来解决此问题
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules", "./functions"]
}