From fd37c09412b5e123840e841289404055814d5bec Mon Sep 17 00:00:00 2001 From: yugasun Date: Fri, 25 Sep 2020 11:45:04 +0800 Subject: [PATCH] fix: support koa server --- README.en.md | 170 ---------------------------------------- README.md | 47 +++++++++-- src/_shims/handler.js | 6 +- src/_shims/package.json | 2 +- 4 files changed, 47 insertions(+), 178 deletions(-) delete mode 100755 README.en.md diff --git a/README.en.md b/README.en.md deleted file mode 100755 index cb3237a..0000000 --- a/README.en.md +++ /dev/null @@ -1,170 +0,0 @@ -[![Serverless Nextjs Tencent Cloud](https://img.serverlesscloud.cn/2020224/1582553715762-next.js_%E9%95%BF.png)](http://serverless.com) - -  - -# Tencent Next.js Serverless Component - -[简体中文](./README.md) | English - -## Introduction - -[Next.js](https://github.com/zeit/next.js) Serverless Component for Tencent Cloud. - -## Content - -0. [Prepare](#0-prepare) -1. [Install](#1-install) -1. [Create](#2-create) -1. [Configure](#3-configure) -1. [Deploy](#4-deploy) -1. [Remove](#5-Remove) - -### 0. Prepare - -#### Init Next.js Project - -```bash -$ npm init next-app serverless-next - -# cd into project folder after init -$ cd serverless-next -``` - -### 1. Install - -Install the Serverless Framework globally: - -```bash -$ npm install -g serverless -``` - -### 2. Create - -In project root, create the following simple boilerplate: - -```bash -$ touch serverless.yml -$ touch .env # your Tencent api keys -``` - -Add the access keys of a [Tencent CAM Role](https://console.cloud.tencent.com/cam/capi) with `AdministratorAccess` in the `.env` file, using this format: - -``` -# .env -TENCENT_SECRET_ID=XXX -TENCENT_SECRET_KEY=XXX -``` - -- If you don't have a Tencent Cloud account, you could [sign up](https://intl.cloud.tencent.com/register) first. - -### 3. Configure - -```yml -# serverless.yml -component: nextjs -name: nextjsDemo -org: orgDemo -app: appDemo -stage: dev - -inputs: - src: - src: ./ - exclude: - - .env - functionName: nextjsDemo - region: ap-guangzhou - runtime: Nodejs10.15 - apigatewayConf: - protocols: - - http - - https - environment: release -``` - -- [More Options](/docs/configure.md) - -### 4. Deploy - -#### 4.1 Build static assets - -```bash -$ npm run build -``` - -#### 4.2 Deploy to cloud - -```bash -$ sls deploy -``` - -> Notice: `sls` is short for `serverless` command. - -  - -### 5. Remove - -```bash -$ sls remove -``` - -## More Components - -Checkout the [Serverless Components](https://github.com/serverless/components) repo for more information. - -## Migration for custom express server - -If you had used `express` for you server, you should create entry file `sls.js`, please change depand on your server entry file, below is a template: - -```js -const express = require('express') -const next = require('next') - -const app = next({ dev: false }) -const handle = app.getRequestHandler() - -// not report route for custom monitor -const noReportRoutes = ['/_next', '/static'] - -async function createServer() { - await app.prepare() - const server = express() - - server.all('*', (req, res) => { - noReportRoutes.forEach((route) => { - if (req.path.indexOf(route) === 0) { - req.__SLS_NO_REPORT__ = true - } - }) - return handle(req, res) - }) - - // define binary type for response - // if includes, will return base64 encoded, very useful for images - server.binaryTypes = ['*/*'] - - return server -} - -module.exports = createServer -``` - -## Customize Monitor - -When deploying Next.js Application, if net config `role` in `serverless.yml`, it will try to bind `QCS_SCFExcuteRole` role for it, and start customize monitor which will help user to collect monitor data. -For project which have no customize entry file `sls.js`, it will ignore request paths which start with `/_next` and `/static`. If you want to customize `sls.js` file, you can create it by yourself. For no report path, just set `__SLS_NO_REPORT__` to `true` on `req` object, like below: - -```js -server.get('/no-report', (req, res) => { - req.__SLS_NO_REPORT__ = true - return handle(req, res) -}) -``` - -so when user access `GET /no-report` route, it won't report monitor data. - -## License - -MIT License - -Copyright (c) 2020 Tencent Cloud, Inc. diff --git a/README.md b/README.md index bd4e37f..4c7094e 100644 --- a/README.md +++ b/README.md @@ -169,9 +169,13 @@ Next.js 组件将在腾讯云账户中使用到如下 Serverless 服务: ## 更多组件 -可以在 [Serverless Components](https://github.com/serverless/components) repo 中查询更多组件的信息。 +可以在 [Serverless Components](https://github.com/serverless/components) 仓库中查询更多组件的信息。 -## 项目迁移 - 自定义 express 服务 +## 项目迁移 + +如果项目使用了自定义 Node.js 服务,比如 express 或者 koa,你需要做如下改造工作。 + +### 自定义 express 服务 如果你的 Next.js 项目本身运行就是基于 `express` 自定义服务的,那么你需要在项目中自定义入口文件 `sls.js`,需要参考你的服务启动文件进行修改,以下是一个模板文件: @@ -179,16 +183,16 @@ Next.js 组件将在腾讯云账户中使用到如下 Serverless 服务: const express = require('express') const next = require('next') -const app = next({ dev: false }) -const handle = app.getRequestHandler() - // not report route for custom monitor const noReportRoutes = ['/_next', '/static', '/favicon.ico'] async function createServer() { + const app = next({ dev: false }) + const handle = app.getRequestHandler() + await app.prepare() - const server = express() + const server = express() server.all('*', (req, res) => { noReportRoutes.forEach((route) => { if (req.path.indexOf(route) !== -1) { @@ -208,6 +212,37 @@ async function createServer() { module.exports = createServer ``` +### 自定义 koa 服务 + +如果你的项目使用的是 Koa 作为 Node.js 服务,需要在项目中自定义入口文件 `sls.js`,需要参考你的服务启动文件进行修改,以下是一个模板文件: + +```js +const Koa = require('koa') +const next = require('next') + +async function createServer() { + const app = next({ dev: false }) + const handle = app.getRequestHandler() + + const server = new Koa() + server.use((ctx) => { + ctx.status = 200 + ctx.respond = false + ctx.req.ctx = ctx + + return handle(ctx.req, ctx.res) + }) + + // define binary type for response + // if includes, will return base64 encoded, very useful for images + server.binaryTypes = ['*/*'] + + return server +} + +module.exports = createServer +``` + ## 自定义监控 当在部署 Next.js 应用时,如果 `serverless.yml` 中未指定 `role`,默认会尝试绑定 `QCS_SCFExcuteRole`,并且开启自定义监控,帮助用户收集应用监控指标。对于为自定义入口文件的项目,会默认上报除含有 `/_next`、`/static` 和 `/favicon.ico` 的路由。如果你想自定义上报自己的路由性能,那么可以自定义 `sls.js` 入口文件,对于无需上报的路由,在 express 服务的 `req` 对象上添加 `__SLS_NO_REPORT__` 属性值为 `true` 即可。比如: diff --git a/src/_shims/handler.js b/src/_shims/handler.js index 2e7de30..0d25585 100644 --- a/src/_shims/handler.js +++ b/src/_shims/handler.js @@ -21,7 +21,11 @@ module.exports.handler = async (event, context) => { app.request.__SLS_CONTEXT__ = context if (!server) { - server = createServer(app, null, app.binaryTypes || []) + server = createServer( + app.callback && typeof app.callback === 'function' ? app.callback() : app, + null, + app.binaryTypes || [] + ) } context.callbackWaitsForEmptyEventLoop = diff --git a/src/_shims/package.json b/src/_shims/package.json index 4941bb1..b8c1945 100644 --- a/src/_shims/package.json +++ b/src/_shims/package.json @@ -7,6 +7,6 @@ "dependencies": { "express": "^4.17.1", "tencent-component-monitor": "^1.1.0", - "tencent-serverless-http": "^1.2.0" + "tencent-serverless-http": "^1.3.1" } }