typescriptexpressdeploymentserverlessvercel

Vercel deployment changing maxDuration not working, functions config not recognizing my routes


I am trying to deploy my backend to Vercel but increasing the maxDuration to 30 seconds. However, builds does not support modifying a functions maxDuration so I attempted to use the functions config. However, my backend is written in TypeScript using Express with the code compiled in a dist directory. My main route file is called index.js inside an API folder, meaning after compilation that file is in /dist/api/index.js. All my source files themselves are in a src directory so the source location for my index.js file /src/api/index.ts. The rest of the src file structure looks like this:

└───src
    ├───api
    ├───config
    ├───controllers
    ├───db
    │   └───migrations
    │       └───meta
    ├───docs
    │   ├───db
    │   └───routes
    ├───middleware
    │   └───security
    ├───routes
    ├───services
    ├───test
    └───utils

Regardless of what I do, Vercel does not recognize my function and wants it to be in an api directory, which I can't pull off since my compiled files are directed to the dist directory.

My current vercel.json file which functions file but doesn't have a custom maxDuration is:

{
  "version": 2,
  "buildCommand": "npm run build",
  "installCommand": "npm install",
  "builds": [
    {
      "src": "dist/api/index.js",
      "use": "@vercel/node",
      "config": {
        "includeFiles": ["dist/**"]
      }
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "dist/api/index.js"
    }
  ]
}

Snippet of my package.json:

{
    "name": "backend",
    "version": "1.0.0",
    "description": "",
    "private": true,
    "scripts": {
        "build": "rimraf dist && tsc",
        "ts.check": "tsc --project tsconfig.json",
        "start": " node ./dist/api/index.js",
        "add-build": "git add dist",
        "test": "nyc --reporter=html --reporter=json --reporter=text mocha dist/test --experimental-modules --timeout 10000 --exit",
        "db:generate": "drizzle-kit generate",
        "db:migrate": "drizzle-kit migrate"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "pre-commit": [
        "ts.check",
        "build",
        "add-build"
    ],

A different vercel.json file which I tried:

{
  "version": 2,
  "buildCommand": "npm run build",
  "installCommand": "npm install",
  "outputDirectory": "dist",
  "functions": {
    "api/index.js": {
      "maxDuration": 30,
      "includeFiles": "dist/**"
    }
  }
}

The exact error is: The pattern "api/index.js" defined in `functions` doesn't match any Serverless Functions inside the `api` directory.


Solution

  • ℹ️ Note: I know my answer is super late. But I had come across your post while I wanted the answer to your exact question. So just putting out here incase if anyone else sees, or helps you in future.

    1. Adding maxDuration

    However, builds does not support modifying a functions maxDuration so I attempted to use the functions

    Yes, builds does not support modifying a functions maxDuration. But you can add maxDuration to your project via your starter file (src/api/index.ts), even with builds array in vercel.json (like this) [Interestingly this feature was added to vercel around the same time you asked this question - link]

    //src/api/index.ts
    import express, { Application } from "express";
    import router from "../routes";
    
    const app: Application = express();
    
    app.use(router);
    
    export const config = { maxDuration: 30 };
    
    export default app;
    

    2. Building typescript file

    There are two I found so far:

    1. By compiling ts files by ourself into dist folder first by running npm run build, then running vercel to let vercel build from the compiled files (dist/api/index.js). In this case you can follow this post. Also make sure to remove ./dist from .gitignore
    // working vercel.json I tried for case 1
    {
      "builds": [
        {
          "src": "dist/api/index.js",
          "use": "@vercel/node"
        }
      ],
      "routes": [
        {
          "src": "/.*",
          "dest": "dist/api/index.js"
        }
      ]
    }
    
    
    1. Without compiling and directly letting vercel read the typescript files from src/api/index.ts. For that follow this post
    // working vercel.json I tried for case 2
    {
      "builds": [
        {
          "src": "src/api/index.ts",
          "use": "@vercel/node"
        }
      ],
      "routes": [
        {
          "src": "/.*",
          "dest": "src/api/index.ts"
        }
      ]
    }
    
    

    Hope this fixes the errors.