10

I have a NextJS/Typescript project where I want to add a CLI script which should process some files on the server.

Unfortunately I don't manage to run the script.

Example script src/cli.ts:

console.log("Hello world");
// Process files

I tried to run the script with:

ts-node src/cli.ts

But I get this error message:

src/cli.ts:1:1 - error TS1208: 'cli.ts' cannot be compiled under '--isolatedModules' because it is considered a global script file. Add an import, export, or an empty 'export {}' statement to make it a module.

When I add an empty 'export {}' statement I get this error message:

(node:15923) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

As far as I know it is now not possible to use NextJS with ES modules.

Is there another way to run the script in a NextJS project? Maybe I need to change the webpack config?

I'm using the latest versions: Next 11, Typescript 4.3, Node 14.18, ts-node 10.13 with the default tsconfig.json, package.json.

3 Answers 3

25

You can use TSX, which plays nicely with NextJS, for both JavaScript and TypeScript. No need for extra configuration or anything.

Install it:

yarn add -D tsx

Declare your script in package.json:

...
"scripts": {
  ...
  "my-cli-script": "tsx src/cli.ts"
},

Run it:

yarn my-cli-script
Sign up to request clarification or add additional context in comments.

5 Comments

I was literally going insane. Tried about 20 different solutions, until this worked. Thank you!!!
@MarekLisý Same here :)
Thanks! This worked for me. If you want you can also just npx tsx path/to/your/script.ts, without the need to add tsx to the dependencies and an appropriate script in package.json.
I tried a LOT of different things to get my .ts script (used for some db updates) to execute with ts-node and nothing worked. tsx worked on first try, no changes to tsconfig.json or package.json. Incredible. Thanks!
TSX is the answer - not sure why ts-node is even suggested in places
14

Run this instead:

npx ts-node --skip-project src/cli.ts

Reference: https://github.com/TypeStrong/ts-node#tsconfig

The --skip-project flag will not resolve/load your tsconfig.json and, thus, ignore the "isolatedModules": true required by Next.js.

You can also create a separate tsconfig file for ts-node and use the --project [path] option.

Another way is to override configuration for ts-node in your tsconfig.json itself like this:

{
  "extends": "ts-node/next/tsconfig.json",

  "ts-node": {
    "compilerOptions": {
      // compilerOptions specified here will override those declared below,
      // but *only* in ts-node.  Useful if you want ts-node and tsc to use
      // different options with a single tsconfig.json.

      "isolatedModules": false
    }
  },

  "compilerOptions": {
    // typescript options here
  }
}

Reference: https://github.com/TypeStrong/ts-node#via-tsconfigjson-recommended

Comments

3

Following on from @brc-dd answer.

The --skip-project flag is now --skipProject

And for the new TSConfig to specify when running the script you would need the following:

{
  "extends": "ts-node/next/tsconfig.json",

  "ts-node": {
    "compilerOptions": {
      // compilerOptions specified here will override those declared below,
      // but *only* in ts-node.  Useful if you want ts-node and tsc to use
      // different options with a single tsconfig.json.

      "module": "CommonJS",
      "isolatedModules": false
    }
  },

  "compilerOptions": {
    // typescript options here
  }
}

All I added to this was: "module": "CommonJS",

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.