У меня есть большая сборка приложения с NestJS
, которую я развертываю, используя serverless framework
. Я делал это в течение некоторого времени, и все было замечательно. Через пару дней go мне пришлось обновиться до Nestjs 7
, и у меня возникло множество проблем при начальной загрузке приложения, когда оно развернуто до aws
. Пройдя бесчисленные неудачные попытки решить проблему, оказалось, что на самом деле это никак не связано с процессом начальной загрузки Nestjs / serverless, и apollo-server-express
не смог получить доступ к маршрутизатору express - ошибка с ошибкой:
express_1.default.Router is not a function
Наконец я понял, что когда я импортирую express
напрямую и пытаюсь получить доступ к express.Router()
, у меня возникает та же проблема. Поэтому я сделал очень простой тест:
lambda.ts:
import { Context, Handler } from "aws-lambda";
import express from "express";
export const handler: Handler = async (event: any, context: Context) => {
console.log("Import express:", express);
console.log("Test express app: ", express());
console.log("Test router:", express.Router());
/* express.Router() ->
ERROR TypeError: express_1.default.Router is not a function at
/var/task/dist/lambda.js:19:51 at Generator.next (<anonymous>) at
/var/task/dist/lambda.js:8:71 at new Promise (<anonymous>) at
__awaiter (/var/task/dist/lambda.js:4:12) at exports.handler (/var/task/dist/lambda.js:16:39) at
Runtime.handler (/var/task/serverless_sdk/index.js:9:131872) at
Runtime.handleOnce (/var/runtime/Runtime.js:66:25)
*/
};
Это не с ошибкой в комментарии, как было сказано ранее. Вот другие файлы:
serverless.yml:
service: xxxxx
app: xxxx
tenant: xxxxx
plugins:
- serverless-pseudo-parameters
- serverless-prune-plugin
- serverless-deployment-bucket
provider:
name: aws
runtime: nodejs12.x
region: eu-west-1
stage: dev
timeout: 29
memorySize: 3008
deploymentBucket:
name: ${self:service}-${self:custom.currentStage}-deployment-bucket
serverSideEncryption: AES256
custom: ${file(./serverless-common.yml):custom}
package:
include:
- ./dist/**
exclude:
- node_modules/aws-sdk/**
functions:
index:
handler: ./dist/lambda.handler
name: bm-${self:custom.currentStage}-express-test
events:
- http:
path: "/{proxy+}"
method: POST
пакет. json:
{
"name": "@xxx/XXXXXX",
"version": "0.1.13",
"dependencies": {
"express": "4.17.1"
},
"devDependencies": {
"serverless-deployment-bucket": "1.1.1",
"serverless-prune-plugin": "1.4.2",
"serverless-pseudo-parameters": "2.5.0",
"ts-node": "^8.7.0",
"tsconfig-paths": "^3.7.0",
"tslint": "5.12.1",
"tslint-config-prettier": "^1.18.0",
"typescript": "^3.8.3"
}
}
tsconfig. json:
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@root/*": ["src/*"]
},
"module": "commonjs",
"moduleResolution": "node",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es6",
"sourceMap": true,
"outDir": "dist",
"esModuleInterop": true
},
"include": ["*"],
"exclude": ["**/node_modules/**/*", "dist"]
}
Я хотел бы подчеркнуть, что этот код дает сбой только после развертывания в lambda. Он работает нормально локально, что указывает на то, что, возможно, что-то не так с процессом упаковки, но zip-файл содержит правильный код и зависимости.
Я долго работал над этой проблемой, прежде чем сузить ее до этого. Если кто-то сможет пролить свет на вышесказанное, это было бы очень признательно, поскольку оно, очевидно, блокирует меня.
Большое спасибо
ОБНОВЛЕНИЕ:
ОК, похоже что если я:
import Router from 'express/lib/router'
, то я получаю экземпляр маршрутизатора. Это тот же экземпляр, который индекс express должен экспортировать.
Так что я близок, но это кажется неправильным, я ничего не изменил, я чувствую, что у меня какая-то неправильная конфигурация модуля или что-то в этом роде.
Так почему я не могу сделать express.Router()
. Любые идеи будут с благодарностью.
ОБНОВЛЕНИЕ:
В конце я исправил apollo-server-express
, чтобы он получал экземпляр маршрутизатора из lib / router, а затем все работает, как ожидалось.
Я, очевидно, не хочу этого делать, поэтому мне действительно нужно разобраться, что вызывает это.
Исправлен ApolloServer. js: https://gist.github.com/TreeMan360/8dc8373ffebe2b24ff51df42090fcb52
ОБНОВЛЕНИЕ:
Другая связанная проблема возникла из-за того, что заголовки возвращаются как часть тела ответа, например:
HTTP/1.1200OKX-Powered-By: ExpressAccess-Control-Allow-Origin: *Content-Type: application/json;charset=utf-8Content-Length: 155ETag: W/"9b-mbrRmusN4ADjvBFA5aFJNLyRMHs"Date: Sat,
04Apr202014: 35: 09GMTConnection: keep-alive{
"data": {
"memberLoginHook": {
"id": "1bb4ca87-d9f6-4ccb-a2a4-0249b19699b3",
"occupation": "C3PO",
"positions": [
{
"id": "f4deaf82-ad87-472b-82ab-c78d08138526"
}
]
}
}
}
Также стоит отметить, что я нашел кто-то еще, кто имеет такую же проблему: https://forum.serverless.com/t/highly-confusing-express-router-issue/10987/8