art*_*ras 5 firebase google-cloud-functions next.js
在学习了一些像这样的教程之后,我能够将我的Next.js
应用程序部署到 Firebase Hosting/Functions。这是我的项目的简化文件夹结构:
myApp
node_modules // Next.js app dependencies
.next // destination of npm run build of the Next.js project
pages // Next.js pages
functions
lib // this is where the functions compile
node_modules // functions' dependencies
src
app.ts
index.ts
other.ts
package.json
public // Next.js app public files
firebase.json
package.json
...
Run Code Online (Sandbox Code Playgroud)
当我运行时firebase deploy
,它会编译functions
到其lib
文件夹中并成功部署所有内容。
但是,当我尝试访问我的网络应用程序的 url 时,我得到了Error: could not handle the request
. 当我查看 Firebase Functions 日志时,我可以看到一条错误消息Error: Cannot find module 'react'
: . 于是,我又添加react
了functions/package.json
,npm install
又firebase deploy
成功了。然而,另一个错误,但这次它说Cannot find module 'react-dom'
。
我的理解是,这样做的原因是我的 Next.js 应用程序依赖于我的文件夹中列出的所有依赖项package.json
(root
下面的简化列表):
"dependencies": {
"babel-plugin-prismjs": "^2.1.0",
"firebase": "^8.8.1",
"firebase-admin": "^9.11.0",
"formik": "^2.2.9",
"js-cookie": "^3.0.0",
"next": "11.0.1",
"next-i18next": "^8.5.5",
"nookies": "^2.5.2",
"prismjs": "^1.24.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-ga": "^3.3.0",
"react-select": "^4.3.1",
"react-spinners": "^0.11.0",
"react-transition-group": "^4.4.2",
"recharts": "^2.0.10",
"styled-components": "^5.3.0",
"yup": "^0.32.9"
}
Run Code Online (Sandbox Code Playgroud)
而我的functions/package.json
显然要短得多:
"dependencies": {
"@sendgrid/mail": "^7.4.4",
"firebase-admin": "^9.8.0",
"firebase-functions": "^3.14.1",
"next": "^11.0.1",
"react": "^17.0.2"
}
Run Code Online (Sandbox Code Playgroud)
我认为错误会要求我将所有依赖项复制到文件中functions/package.json
,这显然是我不想要的。
或者,我可以从to添加firebase-functions
其他相关依赖项,并在根文件夹中设置下一个服务器。但是,如何包含其他现有的云功能呢?functions/package.json
root/package.json
我的文件内容如下所示functions/src
:
索引.ts
import * as admin from 'firebase-admin'
admin.initializeApp()
export * from './app' // next.js
export * from './other'
Run Code Online (Sandbox Code Playgroud)
其他.ts
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
exports.onUserCreate = functions.database.ref...
// my other cloud functions, such as db triggers, https functions, etc.
Run Code Online (Sandbox Code Playgroud)
应用程序.ts
import next from 'next'
import {https} from 'firebase-functions'
const server = next({
dev: process.env.NODE_ENV !== 'production',
conf: {distDir: '.next'}
})
const nextjsHandler = server.getRequestHandler()
exports.app = https.onRequest(async (req, res) => {
await server.prepare()
return await nextjsHandler(req, res)
})
Run Code Online (Sandbox Code Playgroud)
另外,这是我的firebase.json
:
{
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
},
"hosting": {
"target": "myApp",
"public": "public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [{
"source": "**",
"function": "app"
}]
}
}
Run Code Online (Sandbox Code Playgroud)
如何Next.js
正确部署应用程序并确保我的其他云功能继续工作?
谢谢!
虽然您可以将该/functions
目录提升到项目的根目录,但这意味着您的其他功能因Next.js
应用程序的所有依赖项而不必要地膨胀。
当您部署云功能时,/functions
将部署配置的部署目录(默认情况下)中的所有内容 - 即使您不使用它。它还为每个功能部署一次。因此,如果您的函数目录中有一个 10MB 的文件,则每个函数的部署大小将增加 10MB。这就是我所说的“膨胀”函数的意思。
仅供参考:您可以通过将以下内容添加到firebase.json
文件(docs)来更改部署的函数目录:
"functions": {
"source": "." // <- the project's root directory
}
Run Code Online (Sandbox Code Playgroud)
相反,您应该使用部分部署。在这种情况下,您需要移至app.ts
Next 项目的目录,并将不依赖于 Next 部署的其他功能保留在该/functions
文件夹中。如果您部署整个项目目录,即使您不使用它,您最终也会进行部署/functions
,因此您应该将 Next 前端和函数移动到其自己的文件夹中。
文件结构将类似于(详细信息如下):
/myApp
/functions
/lib // this is where the functions compile
/node_modules // functions' dependencies
/src
index.ts
other.ts
firebase.json // configuration for this folder's contents
package.json // configuration for this folder's contents
/next
/node_modules // Next.js app dependencies
/.next // compiled Next.js project
/pages // Next.js pages
/public // Next.js app public files
/functions-lib
app.js // compiled Next function
/functions-src
app.ts // source of Next function
firebase.json // configuration for this folder's contents
package.json // configuration for this folder's contents
...
Run Code Online (Sandbox Code Playgroud)
您的/functions
文件夹的firebase.json
文件将类似于:
{
"functions": {
"source": ".",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
}
Run Code Online (Sandbox Code Playgroud)
为了使上述结构正常运行,您需要调整firebase.json
和package.json
文件的配置。
将以下内容添加到/function
文件夹的package.json
文件中:
"scripts": {
"deploy": "firebase deploy --only functions:otherFunc1,functions:otherFunc2",
...
}
Run Code Online (Sandbox Code Playgroud)
您还可以将这些函数导出为单个组以便于部署,但这些函数将被命名为otherFunctions-otherFunc1
、otherFunctions-otherFunc2
等:
// index.ts
import * as otherFunctions from './other.ts';
export { otherFunctions };
Run Code Online (Sandbox Code Playgroud)
// package.json
"scripts": {
"deploy": "firebase deploy --only functions:otherFunctions",
...
}
Run Code Online (Sandbox Code Playgroud)
您的/next
文件夹的firebase.json
文件将类似于:
{
"functions": {
"source": ".",
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
},
"hosting": {
"target": "myApp",
"public": "public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [{
"source": "**",
"function": "app"
}]
}
}
Run Code Online (Sandbox Code Playgroud)
将以下内容(或类似内容)添加到/next
文件夹的package.json
文件中:
"scripts": {
"build": "npm run build:next && npm run build:functions",
"build:functions": "tsc",
"build:next": "next build",
"lint": "npm run lint:next && npm run lint:functions",
"lint:functions": "eslint --ext .js,.ts ./functions-src",
"lint:next": "...",
"deploy": "firebase deploy --only hosting,functions:app"
}
Run Code Online (Sandbox Code Playgroud)
通过上述更改,放入适当的目录并npm run deploy
在需要使用时使用firebase deploy
。
注意:不要忘记,Cloud Functions会自动使用请求的正文,因此,请确保在 Next 项目中使用正文解析器并使用 进行本地测试时考虑到这一点next start
。
归档时间: |
|
查看次数: |
2747 次 |
最近记录: |