Search code examples
node.jstypescriptaws-lambdaserverlessserverless-offline

Serverless v4 with offline : typescript handlers are not build


I have a problem migrationg my big app in serverless v3 to v4. I'm using typescript and I develop in local using serverless-offline.

But after change all configurations introduced by v4 and run sls offline start , all launch extreamly fast but when I try to access to one route I have this error :

✖ Unhandled exception in handler 'externalUserInfo'.
[serverless-v2] ✖ Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /Users/user/Development/aws/serverless-monorepo/node_modules/@middy/http-error-handler/package.json
[serverless-v2]     at exportsNotFound (node:internal/modules/esm/resolve:304:10)
[serverless-v2]     at packageExportsResolve (node:internal/modules/esm/resolve:594:13)
[serverless-v2]     at resolveExports (node:internal/modules/cjs/loader:634:36)
[serverless-v2]     at Function._findPath (node:internal/modules/cjs/loader:724:31)
[serverless-v2]     at node:internal/modules/cjs/loader:1211:27
[serverless-v2]     at nextResolveSimple (/Users/user/Development/aws/serverless-monorepo/node_modules/tsx/dist/register-DCnOAxY2.cjs:3:942)
[serverless-v2]     at /Users/user/Development/aws/serverless-monorepo/node_modules/tsx/dist/register-DCnOAxY2.cjs:2:2550
[serverless-v2]     at /Users/user/Development/aws/serverless-monorepo/node_modules/tsx/dist/register-DCnOAxY2.cjs:2:1624
[serverless-v2]     at resolveTsPaths (/Users/user/Development/aws/serverless-monorepo/node_modules/tsx/dist/register-DCnOAxY2.cjs:3:760)
[serverless-v2]     at Function._resolveFilename (/Users/user/Development/aws/serverless-monorepo/node_modules/tsx/dist/register-DCnOAxY2.cjs:3:1038)

It seem serverless (or serverless-offline) completly ignore the fact my handlers are in typescript and it does not compile it at all. I block since 3 hours without any resolution...

This is my serverless.mjs config :

export default {
    "frameworkVersion": "4",
    "package": {
        "individually": true,
        "excludeDevDependencies": true
    },
    "provider": {
        "name": "aws",
        "region": "eu-west-1",
        "runtime": "nodejs20.x",
        "architecture": "arm64",
        "memorySize": 1024,
        "deploymentMethod": "direct",
        "apiGateway": {
            "minimumCompressionSize": 1024
        },
        "stage": "${opt:stage, \"local\"}"
    },
    "build": {
        "esbuild": {
            "external": [
                "pg",
                "pg-query-stream",
                "better-sqlite3",
                "tedious",
                "mysql",
                "oracledb",
                "sqlite3",
                "sharp"
            ],
            "bundle": true,
            "buildConcurrency": 1,
            "exclude": [
                "@aws-sdk"
            ],
            "outputFileExtension": ".mjs",
            "packagerOptions": {
                "scripts": [
                    "npm install --os=linux --cpu=arm64 sharp"
                ]
            }
        }
    },
    "custom": {
        "prune": {
            "automatic": true,
            "number": 3
        },
        "cors": {
            "origin": "*",
            "allowCredentials": false,
            "headers": [
                "Allow-Header",
                "Content-Type",
                "X-Amz-Date",
                "Authorization",
                "X-Api-Key",
                "X-Api-Version",
                "X-Amz-Security-Token",
                "X-Amz-User-Agent",
                "AuthToken",
                "OrgId",
                "CustomerId"
            ]
        },
        "serverless-offline": {
            "noAuth": true,
            "useChildProcesses": true,
            "allowCache": true
        }
    },
    "plugins": [
        "serverless-offline"
    ],
    "service": "serverless",
    "functions": {
        "externalUserInfo": {
            "handler": "stacks/users/src/handlers/external-information-api.handler", // Typescript handler
            "maximumRetryAttempts": 0,
            "events": [
                {
                    "http": {
                        "method": "get",
                        "path": "/account",
                        "private": true
                    }
                }
            ]
        },
    }
}

Solution

  • For now, the only solution I found is not perfect: I deactivate serverless build process build.esbuild: false and I add serverless-esbuildplugin.

    After that, the build works correctly but it is not a perfect solution : sormally, with serverless-v4 I don't have to pass by third party module to build typescript.