Using NextJS to execute a Typescript script on the server

I am working on a NextJS/Typescript project where I need to implement a CLI script for processing files on the server.

However, I am facing difficulties in getting the script to run successfully.

Here is an example of the script src/cli.ts:

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

I attempted to execute the script using the following command:

ts-node src/cli.ts

But I encountered 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.

Upon adding an empty 'export {}' statement, I received the following warning:

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

It appears that using ES modules with NextJS is currently not supported.

Is there an alternative approach to running the script within a NextJS project? Perhaps modifying the webpack configuration could help?

My setup includes the latest versions: Next 11, Typescript 4.3, Node 14.18, ts-node 10.13 with the default tsconfig.json, package.json.

Answer №1

If you're looking to integrate seamlessly with NextJS, consider using TSX instead. This tool supports both JavaScript and TypeScript without the need for any additional setup.

Get started by adding it to your project:

yarn add -D tsx

Next, declare your script in the package.json file:

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

Finally, run your custom script with the following command:

yarn my-custom-script

Answer №2

Instead of the original command, consider running the following:

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

To learn more about this method, visit: https://github.com/TypeStrong/ts-node#tsconfig

By using the --skip-project flag in your command, you can bypass loading the tsconfig.json, thus avoiding conflicts with

"isolatedModules": true
required by Next.js.

If needed, you can create a separate tsconfig file specifically for ts-node and utilize the --project [path] option.

An alternative approach is to customize configuration for ts-node within your existing tsconfig.json as demonstrated below:

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

  "ts-node": {
    "compilerOptions": {
      // By setting specific compiler options here, they will take precedence over global settings,
      // exclusively for ts-node. This is beneficial when requiring distinct options for ts-node versus tsc
      // while maintaining a single tsconfig.json.

      "isolatedModules": false
    }
  },

  "compilerOptions": {
    // Define TypeScript options here
  }
}

For further details on this approach, refer to: https://github.com/TypeStrong/ts-node#via-tsconfigjson-recommended

Answer №3

Expanding on the response provided by @brc-dd.

The use of --skip-project has been replaced with --skipProject

To configure the new TSConfig for executing the script, include the following setup:

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

  "ts-node": {
    "compilerOptions": {
      // compilerOptions outlined here take precedence over those defined below,
      // specifically within ts-node scope. This allows customization between
      // ts-node and tsc using a single tsconfig.json.

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

  "compilerOptions": {
    // additional TypeScript options can be specified here
  }
}

The only modification introduced is:

"module": "CommonJS",

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Themeing for dark mode using styled components in Next JS

I have been searching for an answer to this question, but haven't found one yet Currently, I am using styled components with next js along with the use-dark-mode hook to manage theme changes and detection The global styles switch seems to work fine ...

Unsure about module loading with system.js and navigating Typescript

I am currently in the process of transitioning an ASP.Net MVC application to Angular2, and I've encountered some perplexing behavior that I can't seem to grasp. Within my Angular2 app, I have a separate Layoutview that allows me to switch betwee ...

What is the reason behind material-ui's decision to invoke their dialogs twice?

After attempting to implement a modal and realizing the strange behavior, I switched to using a dialog instead. To my surprise, the issue persisted. This is how I approached it: import Dialog, { DialogProps } from '@material-ui/core/Dialog'; imp ...

Step-by-step guide to initializing data within a service during bootstrap in Angular2 version RC4

In this scenario, I have two services injected and I need to ensure that some data, like a base URL, is passed to the first service so that all subsequent services can access it. Below is my root component: export class AppCmp { constructor (private h ...

Is there a way to establish a universal font for all apps within ant design?

I am currently working with NextJS version 14 and I have the following setup: In my globals.css file, I have imported a Google font like so: @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@100;200;300;400;500;600;700;800& ...

What are some effective strategies for utilizing observables for handling http requests in an Angular application?

In my Angular application, I am retrieving data from APIs. Initially, my code in detail.component.ts looked like this: //code getData() { this.http.get(url1).subscribe(data1 => { /* code: apply certain filter to get a filtered array out */ t ...

The specified type 'MutableRefObject<HTMLInputElement | undefined>' cannot be assigned to type 'LegacyRef<HTMLInputElement> | undefined'

Consider the following simplified component : const InputElement => React.forwardRef((props:any, ref) => { const handleRef = React.useRef<HTMLInputElement|undefined>() React.useImperativeHandle(ref, () => ({ setChecked(checke ...

How can we create a versatile Action type in typescript that can accommodate varying numbers of arguments and argument types?

When working with Typescript, encountering a duplicate type error can be frustrating. For instance, consider the following code snippet: export type Action<T> = (arg:T) => void export type Action<T1,T2> = (arg1:T1, arg2:T2) => void How c ...

Tips for avoiding multiple reference paths in Angular TypeScript: - Simplify your imports

Setting up Typescript for an Angular 1.5 application has been a bit of a challenge. To ensure that a TS file can be compiled by gulp without any errors, I have to include the following line: ///<reference path="../../../../typings/angularjs/angular.d.t ...

Retrieving information using useSWR. Advancing to the Next Image

When fetching data from the backend URL without a host, in the Next Image I pass the source with the host. However, the requested URL of the image ends up being the page's pathname + the URL without the host. How does this happen? const { data: pa ...

Exploring limitless possibilities with Vue slot manipulation

Imagine I am looking to develop a multi-layered Component for reusability, similar to a 'Tab' UI. This would allow developers to use it like this: <tabs> <tab label="My First Tab"> Content for first tab which could co ...

Discover the Category of Union based on Discriminator

Imagine a scenario where there is a concept of a union type called Thing, which combines types Foo, Bar, and Baz, each identified by the property tag. interface Foo { tag: 'Foo' foo: string } interface Bar { tag: 'Bar' bar: nu ...

Is there a way for me to obtain a selection of 20 random items from this JSON data

When working with my JSON data using Myjson.slice(1, 20), I encountered a situation where I needed to extract only 20 items from a dataset that had a length of 2624. In the code snippet provided, I attempted to use the slice method but struggled to differe ...

Unable to connect to web3 object using typescript and ethereum

Embarking on a fresh project with Angular 2 and TypeScript, I kicked things off by using the command: ng new myProject Next, I integrated web3 (for Ethereum) into the project through: npm install web3 To ensure proper integration, I included the follow ...

VueJS - When using common functions, the reference to "this" may be undefined

I'm struggling to extract a function that can be used across various components. The issue is that when I try to use "this", it is coming up as undefined. I'm not sure of the best practice for handling this situation and how to properly assign th ...

Steps for displaying an error message when incorrect credentials are entered during a login attempt

As I work on implementing a login feature, I am facing the challenge of displaying an error message when users enter incorrect login credentials. My development environment involves using the POST method within Next.js. Here is a snippet of my code: ...

Using static typing in Visual Studio for Angular HTML

Is there a tool that can validate HTML and provide intellisense similar to TypeScript? I'm looking for something that can detect errors when using non-existent directives or undeclared scope properties, similar to how TypeScript handles compilation er ...

The @ViewChild in Angular 2 seems to be unable to detect the BaseChartDirective from the ng2-charts

I'm currently using ng2-charts v1.5.0 and I'm facing an issue with updating the chart data after a click event. Despite following suggestions from other sources, I am unable to get it to work properly. Here is a snippet of my code: <div styl ...

Tips for adding an item to an array within a Map using functional programming in TypeScript/JavaScript

As I embark on my transition from object-oriented programming to functional programming in TypeScript, I am encountering challenges. I am trying to convert imperative TypeScript code into a more functional style, but I'm struggling with the following ...

Setting text in a datetime picker with ngx-mat-datetime-picker in an Angular application is a straightforward process

I've been utilizing the ngx-mat-datetime-picker library from angular-material-components to enable datetime selection. It's functioning effectively, but I'm searching for a way to insert text preceding the hour and minute inputs, such as &ap ...