Next.js: how to run a custom express server with typescript and nextjs?

Created on 9 Aug 2017  路  13Comments  路  Source: vercel/next.js

{
  // package.json
  "name": "with-typescript",
  "version": "1.0.0",
  "scripts": {
    "dev": "concurrently \"tsc --watch\" && node server.js"
  },
  "dependencies": {
    "express": "^4.15.4",
    "express-logging": "^1.1.1",
    "logops": "^2.1.0",
    "next": "latest",
    "react": "^15.5.4",
    "react-dom": "^15.5.4"
  },
  "devDependencies": {
    "@types/node": "^8.0.20",
    "@types/react": "^15.0.1",
    "babel-plugin-root-import": "^5.1.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-register": "^6.24.1",
    "concurrently": "^3.1.0",
    "typescript": "^2.1.5"
  }
}
// server.ts
import express from 'express';
import next from 'next';

const dev = process.env.NODE_ENV !== 'production';
const port = process.env.PORT || 3000;
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare()
  .then(() => {
    const server = express();

    server.get('*', (req, res) => {
      return handle(req, res);
    });

    server.listen(port, (err) => {
      if (err) throw err;
      console.log(`> Ready on http://localhost:${port}`);
    });
  });

If I run npm run dev nothing really happens.

If I instead run change the script to "dev": "node server.js"

I get an error TypeError: next_1.default is not a function

Since server.ts is being converted to server.js it gives me this line where this error is:
const app = next_1.default({ dev }); from const app = next({ dev });

So question is, how can I run custom express server using typescript?

Most helpful comment

Don't use older TypeScript + Next.js boilerplates.

Continue running the custom server like you used to, you can use nodemon with ts-node to run it and with Next.js 5, use @zeit/next-typescript along with your custom server in combination with @zeit/next-css or whatever you happen to require.

And get rid of concurrently. Just start the custom server and next-typescript or your custom ts-loader configuration in next.config.js will keep you good to go.

All 13 comments

It's because default ESM import transpiles to require.default so use CommonJS.
If you want to use ESM, try import * as next from 'next' or import * from 'next' (0% guarantee, I don't know how TypeScript will handle this.)

this seems to work.

What I can't get to work is the script to run both tsc and node

"dev": "concurrently \"tsc --watch\" && node server.babel.js -p $PORT",

It just runs the first part before &&

that's not how concurrently works, it doesn't split off tsc somewhere else. what you'll need to do is:

concurrently \"tsc --watch\" node server.babel.js -p $PORT

@retrixe I tried that but gave me error, I got it working like this though:
"dev": "concurrently \"tsc --watch\" \"node server.babel.js -p $PORT\"",

Thank you!

no problem, i was about to edit my comment. seems like concurrently only takes one word commands if you wish to remove the quotes.

here is a example for using next.js width koa2 & typescript: https://github.com/lvlinhaohan2010/next-koa2-typescript-starter

Anybody have any tips on getting the custom server going in light of the latest next 5 release?

Don't use older TypeScript + Next.js boilerplates.

Continue running the custom server like you used to, you can use nodemon with ts-node to run it and with Next.js 5, use @zeit/next-typescript along with your custom server in combination with @zeit/next-css or whatever you happen to require.

And get rid of concurrently. Just start the custom server and next-typescript or your custom ts-loader configuration in next.config.js will keep you good to go.

That works great @retrixe ! Thank you so much!

@retrixe Would you be willing to submit a PR to add a custom-server-typescript example like was mentioned in #3694? I'm using nodemon to execute ts-node --project tsconfig.server.json server.ts (using ES import and need to use commonjs module option), but something is killing the server after a short period of time. I'm clearly missing something and would be interested in seeing your solution.

I also ran into more odd issues and strange behavior telling me I have some setup wrong @corydeppen . I would be willing to buy @retrixe a beer or coffee if I had a working example for inspiration :)

@zachariahtimothy @corydeppen see #3838 :smile:

Use import * as express from 'express'; import * as next from 'next'; or set "esModuleInterop": true will fix TypeError: next_1.default is not a function.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sospedra picture sospedra  路  3Comments

jesselee34 picture jesselee34  路  3Comments

knipferrc picture knipferrc  路  3Comments

kenji4569 picture kenji4569  路  3Comments

flybayer picture flybayer  路  3Comments