Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ERROR] Must use import to load ES module #314

Closed
angelhdzmultimedia opened this issue May 31, 2022 · 43 comments
Closed

[ERROR] Must use import to load ES module #314

angelhdzmultimedia opened this issue May 31, 2022 · 43 comments

Comments

@angelhdzmultimedia
Copy link

Issue description

image

Context

Totally new Node project with typescript, @types/node, and ts-node-dev packages installed.
I only get this error when I set type: "module" in package.json.

ts-node-dev: ^2.0.0

OS version (is it docker or host?), ts-node-dev version

Did you try to run with ts-node?

Did you try to run with --files option enabled?

Did you try to run with --debug option enabled?

Do you have a repro example (git repo) with simple steps to reproduce your problem?

@danlupascu
Copy link

danlupascu commented Jun 2, 2022

I'm having the same problem

ts-node-dev version: 2.0.0
typescript version: 4.7.2

@angelhdzmultimedia
Copy link
Author

Switched to babel with @babel/preset-typescript, and nodemon. Everything is working there. Can use imports without filenames, can use directories with implied index.ts, and can use mongoose. Will try other packages later to confirm that everything works now.

@angelhdzmultimedia
Copy link
Author

Still having this issue with ts-node-dev. No matter what I try (type: "module" in package.json, module:"esnext" and module:"commonjs" in tsconfig.json, etc.)

Right now, my problem is with the package inquirer. It's ready for ESM in new version v9.0.0. But if I remove type: "module" from package.json, inquirer complains. Then I replaced the import with a dynamic import await import('inquirer'), but then I get an error that can't use top level await with a commonjs module...

It's a paradox.

But with babel and nodemon, and babel typescript presets it works flawlessly.

I'm reaching the conclusion that ts-node-dev isn't ready for ESM so I will continue using babel and nodemon.

@halvors
Copy link

halvors commented Jul 4, 2022

I have this exact same problem too, would it be possible to support this?

@dawosch
Copy link

dawosch commented Jul 29, 2022

Same problem.
I'm using ts-node-dev while i'm developing. And there the error occures.
When i build my project for production with bable it's woking.

@angelhdzmultimedia
Copy link
Author

Same problem. I'm using ts-node-dev while i'm developing. And there the error occures. When i build my project for production with bable it's woking.
Yeah, with babel works.

You can try this config, I tested it with most ES2022 features (including Top Level Await) and it works.

{
  "type": "module",
  "name": "test_typescript_esm",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "dev": "nodemon -I --exec node --experimental-specifier-resolution=node  --loader ts-node/esm ./src/main.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "nodemon": "^2.0.19",
    "ts-node": "^10.9.1",
    "typescript": "^4.7.4"
  },
  "exports": "./dist/index.js",
  "devDependencies": {
    "@babel/core": "^7.18.2",
    "@babel/node": "^7.17.10",
    "@babel/plugin-proposal-decorators": "*",
    "@babel/preset-env": "^7.18.2",
    "@types/node": "^18.6.2"
  }
}

@ghost
Copy link

ghost commented Aug 1, 2022

mark

@ChromeGG
Copy link

Same problem here. I tried with

ts-node-esm --experimental-specifier-resolution=node --transpile-only ./src/index

and it works BUT it'll not restart automatically if files will change

@angelhdzmultimedia
Copy link
Author

angelhdzmultimedia commented Sep 11, 2022

Update

Besides it working with Babel, I achieved to make it working with nodemon and ts-node.

Install nodemon and ts-node and of course typescript, set type: "module" in package.json,
and set tsconfig.json to:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "moduleResolution": "Node",
    "module": "ESNext",
    "target": "ESNext"
  }
}

And then: nodemon --exec node --loader ts-node/esm src/main.ts

@zhoutengshen
Copy link

I also encountered this problem. These contents may help you

node version : v16.13.2

package.json

{
  "devDependencies": {
    "@types/node": "^18.11.18",
    "nodemon": "^2.0.20",
    "ts-node": "^10.9.1",
    "typescript": "^4.9.4"
  },
  "scripts": {
    "dev": "nodemon --exec ts-node index.ts --project ./tsconfig.json"
  },
  "type": "module"
}

tsconfig.json

{
  "extends": "ts-node/node16/tsconfig.json",
  "ts-node": {
    "transpileOnly": true,
    "files": true,
    // Tell ts-node CLI to install the --loader automatically, explained below
    "esm": true,
    "compilerOptions": {
      "module": "ESNext"
    }
  },
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Node",
    "lib": [
      "DOM",
      "ES2015"
    ],
    "target": "ES2015"
  }
}

@angelhdzmultimedia
Copy link
Author

I also encountered this problem. These contents may help you

node version : v16.13.2

package.json

{
  "devDependencies": {
    "@types/node": "^18.11.18",
    "nodemon": "^2.0.20",
    "ts-node": "^10.9.1",
    "typescript": "^4.9.4"
  },
  "scripts": {
    "dev": "nodemon --exec ts-node index.ts --project ./tsconfig.json"
  },
  "type": "module"
}

tsconfig.json

{
  "extends": "ts-node/node16/tsconfig.json",
  "ts-node": {
    "transpileOnly": true,
    "files": true,
    // Tell ts-node CLI to install the --loader automatically, explained below
    "esm": true,
    "compilerOptions": {
      "module": "ESNext"
    }
  },
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Node",
    "lib": [
      "DOM",
      "ES2015"
    ],
    "target": "ES2015"
  }
}

Thank you!

soedirgo added a commit to supabase/postgres-meta that referenced this issue Jan 16, 2023
Replace ts-node-dev with nodemon + ts-node: wclr/ts-node-dev#314 (comment)
soedirgo added a commit to supabase/postgres-meta that referenced this issue Jan 16, 2023
Replace ts-node-dev with nodemon + ts-node: wclr/ts-node-dev#314 (comment)
@oxilor
Copy link

oxilor commented Feb 25, 2023

According to the typescript documentation the moduleResolution must be:

  • node for Node.js’ CommonJS implementation
  • nodenext for Node.js’ ECMAScript Module Support from TypeScript 4.7 onwards.

So the moduleResolution must be nodenext for ESM. I created the repository with minimum configuration for restarting the node app when the file changes. It uses nodemon, because the ts-node-env doesn't seem to support ESM yet.

@angelhdzmultimedia
Copy link
Author

I'm using tsx now. No issues so far.

But thanks for the update. I'm gonna try ts-node-dev again with module resolution set to nodenext.

Is the ts-node set to esm mandatory?

@oxilor
Copy link

oxilor commented Feb 26, 2023

@angelhdzmultimedia Wow, tsx looks even better. I'll try it. Thanks.

Is the ts-node set to esm mandatory?

Unfortunately, I don't quite understand your question. To make ts-node compatible with ESM, we should use the appropriate loader in one of the following ways, but ts-node-dev (v2.0.0) still throws an error if ESM is used (Must use import to load ES Module).

P.S. tsx does not support type checking. We can, of course, run the TS compiler at first tsc --noEmit && tsx watch src/index.ts, but in this case, if we violated some types during watch mode, tsx doesn't show any errors. This seems to be the main reason why tsx is faster than, for example, ts-node. IMO it's inconvenient, because we don't immediately know about mistakes in types.

We are looking forward to ESM support in ts-node-dev. In the meantime, we can use nodemon + ts-node if we need to check types in watch mode, or tsx if not.

@angelhdzmultimedia
Copy link
Author

@angelhdzmultimedia Wow, tsx looks even better. I'll try it. Thanks.

Is the ts-node set to esm mandatory?

Unfortunately, I don't quite understand your question. To make ts-node compatible with ESM, we should use the appropriate loader in one of the following ways, but ts-node-dev (v2.0.0) still throws an error if ESM is used (Must use import to load ES Module).

P.S. tsx does not support type checking. We can, of course, run the TS compiler at first tsc --noEmit && tsx watch src/index.ts, but in this case, if we violated some types during watch mode, tsx doesn't show any errors. This seems to be the main reason why tsx is faster than, for example, ts-node. IMO it's inconvenient, because we don't immediately know about mistakes in types.

We are looking forward to ESM support in ts-node-dev. In the meantime, we can use nodemon + ts-node if we need to check types in watch mode, or tsx if not.

My question is, is it mandatory to add this:

image

And yes, you're right about tsx.

I've been also using nodemon --exec "node --loader ts-node/esm src/main.ts" or just node --loader ts-node/esm and it works great.

I'm exited to see ts-node-dev being improved.

@oxilor
Copy link

oxilor commented Feb 26, 2023

@angelhdzmultimedia,

My question is, is it mandatory to add this

We should somehow tell ts-node to use the loader that supports ESM. This can be done in one of the following ways:

1. Specify in tsconfig.json that the ts-node uses ESM loader

{
  "ts-node": {
    "esm": true
  }
}

In this case, you don't need to specify additional arguments in nodemon command:

nodemon src/index.ts

2. Specify the ts-node command with ESM in nodemon:

nodemon --exec ts-node-esm src/index.ts

or

nodemon --exec 'ts-node --esm' src/index.ts

In this case, you don't need to change the tsconfig.json file.

3. Set ts-node with ESM as the node loader

NODE_OPTIONS='--loader ts-node/esm' nodemon src/index.ts

or

nodemon --exec 'node --loader ts-node/esm' src/index.ts

I prefer the first case (set ts-node.esm to true in tsconfig), because it looks cleaner.

@angelhdzmultimedia
Copy link
Author

angelhdzmultimedia commented Feb 26, 2023

I appreciate your kind responses A LOT!!! They have been on fire🔥, on point👌!

Sorry to bother you with one last question... ❔

Difference between ts-node/esm and ts-node-esm flags? Both allowed or is one of them deprecated?

Wishing you health, peace, and success!

@oxilor
Copy link

oxilor commented Feb 26, 2023

Seems that ts-node-esm and ts-node --esm are aliases of commands. ts-node/esm is the node loader.

I don't see any of them being deprecated at the moment. So you can use any of these methods that you like best.

@ThallesP
Copy link

ThallesP commented Apr 11, 2023

Got one-liner working with nodemon:

npx nodemon -e ts,json --exec 'node --experimental-specifier-resolution=node --loader ts-node/esm' <path>.js

@RangerCoder99
Copy link

npx nodemon -e ts,json --exec 'node --experimental-specifier-resolution=node --loader ts-node/esm' <path>.js

not working on windows :(

@angelhdzmultimedia
Copy link
Author

angelhdzmultimedia commented Apr 24, 2023

image

I don't know what you're trying to achieve, but I got it working with:

npx nodemon -e ts,json --exec node --experimental-specifier-resolution=node --loader ts-node/esm main.ts

Where main.ts is my main file in the root of my project.

image

@RicFer01
Copy link

@angelhdzmultimedia,

My question is, is it mandatory to add this

We should somehow tell ts-node to use the loader that supports ESM. This can be done in one of the following ways:

1. Specify in tsconfig.json that the ts-node uses ESM loader

{
  "ts-node": {
    "esm": true
  }
}

In this case, you don't need to specify additional arguments in nodemon command:

nodemon src/index.ts

2. Specify the ts-node command with ESM in nodemon:

nodemon --exec ts-node-esm src/index.ts

or

nodemon --exec 'ts-node --esm' src/index.ts

In this case, you don't need to change the tsconfig.json file.

3. Set ts-node with ESM as the node loader

NODE_OPTIONS='--loader ts-node/esm' nodemon src/index.ts

or

nodemon --exec 'node --loader ts-node/esm' src/index.ts

I prefer the first case (set ts-node.esm to true in tsconfig), because it looks cleaner.

Thanks to your suggestions I got it working! There is one thing I didn't get, I'm using TS, why do I need to import file adding the extension and this extension has be in .js?

import app from './api.js'

@cincarnato
Copy link

@RicFer01 Your last question have the answer here: https://www.typescriptlang.org/docs/handbook/esm-node.html

image

@RicFer01
Copy link

@RicFer01 Your last question have the answer here: typescriptlang.org/docs/handbook/esm-node.html

image

Thank you!

@ivannalon
Copy link

I'm using tsx now. No issues so far.

But thanks for the update. I'm gonna try ts-node-dev again with module resolution set to nodenext.

Is the ts-node set to esm mandatory?

Are you using it in conjunction with docker? My tsx doesn't work watch mode in the container.

@rtlayzell
Copy link

Repo is looking stale, fair to say this isn't getting fixed any time soon?

@jaclas
Copy link

jaclas commented Jul 24, 2023

and still nothing?

@itxtoledo
Copy link

same error here

@Marcelofj
Copy link

I solved my problem by simply removing "type" : "module" from package.json

@ThallesP
Copy link

if anyone want an alternative, i use tsx for about sometime and i love it, simple to use and maintained.

@rolanday
Copy link

I solved my problem by simply removing "type" : "module" from package.json

Sorry, but this is not a solution.

@rolanday
Copy link

+1 for tsx -- it doesn't perform type checking though, so just keep that in mind. I just add "check": "tsc --noEmit" to my package.json script and spot check occasionally (or a full build), and good linter setup goes a long way.

@Marcelofj
Copy link

Marcelofj commented Oct 16, 2023

I solved my problem by simply removing "type" : "module" from package.json

Sorry, but this is not a solution.

For me it is. Works fine.

My package.json:

{ "name": "general", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "dev": "ts-node-dev --respawn --transpile-only src/app.ts" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "ts-node-dev": "^2.0.0", "typescript": "^5.1.6" } }

@devgrunge
Copy link

I also encountered this problem. These contents may help you

node version : v16.13.2

package.json

{
  "devDependencies": {
    "@types/node": "^18.11.18",
    "nodemon": "^2.0.20",
    "ts-node": "^10.9.1",
    "typescript": "^4.9.4"
  },
  "scripts": {
    "dev": "nodemon --exec ts-node index.ts --project ./tsconfig.json"
  },
  "type": "module"
}

tsconfig.json

{
  "extends": "ts-node/node16/tsconfig.json",
  "ts-node": {
    "transpileOnly": true,
    "files": true,
    // Tell ts-node CLI to install the --loader automatically, explained below
    "esm": true,
    "compilerOptions": {
      "module": "ESNext"
    }
  },
  "compilerOptions": {
    "module": "ESNext",
    "moduleResolution": "Node",
    "lib": [
      "DOM",
      "ES2015"
    ],
    "target": "ES2015"
  }
}

It worked well for me!
using at my package.json:

"dev": "nodemon --exec ts-node ./src/index.ts --project ./tsconfig.json"

louis-marceron added a commit to louis-marceron/BACK-AWI that referenced this issue Nov 13, 2023
I recognize this may not be optimal for performance,
but it's simpler to set up. I might revise this approach
in the future. Found the command here:
wclr/ts-node-dev#314 (comment)
@t-benze
Copy link

t-benze commented Dec 25, 2023

I'm using tsx now. No issues so far.

But thanks for the update. I'm gonna try ts-node-dev again with module resolution set to nodenext.

Is the ts-node set to esm mandatory?

This is good! Thanks

@mblackrittr
Copy link

I solved my problem by simply removing "type" : "module" from package.json

Sorry, but this is not a solution.

For me it is. Works fine.

Löl, no, it doesn't! 😹💦

Well, yeah, yeah, always the same everywhere - it "works" for them... löl
... exactly until they'll've to resolve it - just because "type": "module" is NOT something optional one can set as he wishes - gruesome! 🙀

@mblackrittr
Copy link

mblackrittr commented Mar 17, 2024

if anyone want an alternative, i use tsx for about sometime and i love it, simple to use and maintained.

Thanks @angelhdzmultimedia and @ThallesP, works as great as you say - WoooF! 😻 😹💦

@teadrinker2015
Copy link

It is built on top of ts-node, and ts-node is a ... please search on stackoverflow for solutions like --esm, remove { "type": "module" } ... you will end up being recommended with tsx any way.

@angelhdzmultimedia
Copy link
Author

I'm lately using node --watch ts-node/esm src/main.ts

And in tsconfig.json:
{
"ts-node": {
"experimentalSpecifierResolution": "node",
"transpileOnly": true,
"esm": true,
}
}

And works... good...
I dream of a day where there's only 1 configuration and working with TypeScript + Node is a pleasure...
Waiting for Bun Windows 👀

@mblackrittr
Copy link

mblackrittr commented Mar 20, 2024

I'm lately using node --watch ts-node/esm src/main.ts

I wonder what issues await the brave on that path (with latest Node, etc.), but would you share with us - why it's not TSX anymore for you?

Just using it a day now, but works great so far, even already with Node 21.7.1.

And beside tons of features, it can also watch, same as TS-Node-Dev:

> tsx watch ./file.ts

@IzaelGomes
Copy link

IzaelGomes commented Apr 15, 2024

i solved this problem removing "type": "module" from my package.json and keeping just "module": "CommonJS" on my tsconfig.json. it works fine.

@angelhdzmultimedia
Copy link
Author

Bun for Windows is out guys! 🔥👀✌️🤣

Bun, tsx, unjs/jiti. Solid options now.

Closing this.

@mblackrittr
Copy link

mblackrittr commented Apr 15, 2024

i solved this problem removing "type": "module" from my package.json and keeping just "module": "CommonJS" on my tsconfig.json. it works fine.

Yeah, yeah, "solved" and "works fine" (always were the words of the ignorant) - see you again later in the day when you figure out it'll blow on all these "EVIL" ESM only packages or any other valid reason for ESM, e.g. publishing a package for others to use - then no ESM?! 🙀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests