Comments (37)
Guys no need for ts-node
, just use Deno or Bun:
deno run main.ts
bun run main.ts
from ts-node.
To summarize: Looks like this has been there for a while. Adding "type"="module"
to package.json
breaks ts-node --esm for any node version above v16.
The workarounds I've found so far:
- remove
"type="module"
- downgrade to node v16
- use
node --loader ts-node/esm
instead ofts-node --esm
(comes with a warning) - use
node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("ts-node/esm", pathToFileURL("./"));'
instead ofts-node --esm
(to avoid the warning) - use tsx instead of ts-node
If you are using webpack in your project, this also breaks using Typescript config files. The only workaround for this are:
- switch back to JS config file
- remove
"type="module"
- downgrade to node v16
from ts-node.
Update: The node version where ts-node with package.json "type"="module"
breaks is v18.19.0
Simple repro - francip/ts-node-test
from ts-node.
I use node v20.10.0.
In Package.json apply this configuration:
- Here is my start script :
nodemon --exec node --no-warnings=ExperimentalWarning --loader ts-node/esm src/index.ts
- Add
"type": "module",
- In dependencies add the matching @types dependencies in devDependencies if exists on npm for type completion:
"devDependencies": { "@types/node": "^20.11.26", "@types/jsonwebtoken": "^9.0.6", "@types/express": "^4.17.21", "nodemon": "^3.1.0", "ts-node": "^10.9.2", "typescript": "^5.4.2" }, "dependencies": { "cors": "^2.8.5", "express": "^4.18.3", "jsonwebtoken": "^9.0.2" }
In tsconfig.json apply the following:
"module": "ESNext", "target": "ESNext"
"esModuleInterop": true, "moduleResolution": "Node"
- At the same level of compiler option add
"ts-node": { "esm": true, }
Hope It will work !!
from ts-node.
Heres a working example with node v21.5.0, typescript v5.3.3, ts-node v10.9.2 :- https://github.com/AaronNGray/ts-node-example
This is not an ESM package. Try setting type to module in your package.json.
AFAICS I am not sure ts-node supports ESM. Could you provide the example that works on node v19.0.0, but not v21.5.0. Or is it as simple as setting "type":"module"
? As in :-
https://github.com/AaronNGray/ts-node-example/tree/ts-node-esm-module
on v21.5.0 resulting in :-
C:\Users\Nathaniel\test\Node.js\ts-node-example>npm start
> [email protected] start
> ts-node src/index.ts
TypeError: Unknown file extension ".ts" for C:\Users\Nathaniel\test\Node.js\ts-node-example\src\index.ts
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
at defaultLoad (node:internal/modules/esm/load:143:22)
at async ModuleLoader.load (node:internal/modules/esm/loader:409:7)
at async ModuleLoader.moduleProvider (node:internal/modules/esm/loader:291:45)
at async link (node:internal/modules/esm/module_job:76:21) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
from ts-node.
Adding :-
"start:node": "node --loader ts-node/esm src/index.ts"
and tsconfig.json :-
"module": "esnext"
We have :-
https://github.com/AaronNGray/ts-node-example/tree/ts-node-esm-loader
which gives :-
C:\Users\Nathaniel\test\Node.js\ts-node-example>npm run start:node
> [email protected] start:node
> node --loader ts-node/esm src/index.ts
(node:18508) ExperimentalWarning: `--experimental-loader` may be removed in the future; instead use `register()`:
--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("ts-node/esm", pathToFileURL("./"));'
(Use `node --trace-warnings ...` to show where the warning was created)
ts-node
NOTE: I have just found this does not seem to support imports !!!
from ts-node.
@cibilex https://github.com/AaronNGray/ts-node-esm-test works fine now !
I have added a node --test
example too.
from ts-node.
Heres a working example with node v21.5.0, typescript v5.3.3, ts-node v10.9.2 :-
https://github.com/AaronNGray/ts-node-example
NOTE: I have just found this does not seem to support imports !!!
from ts-node.
First of all ,I already looked at #1997 and most of other websites to solve the problem but I couldn't.This error is throwed when I try to use in Node v21.5.0.I realized that The problem is node version,when I updated Node version to v19.0.0 it works.Could you please update ts-node to work in new Node versions.
Could you please provide a minimal example of what does not work and then we can try to figure out why !
from ts-node.
Thank you a lot,It works now splendid :)
from ts-node.
@cibilex - Did you manage to add the two commits to a ts-node fork or did you just patch the diff's ? If you used git I would love to know how !
$ git fetch https://github.com/TypeStrong/ts-node refs/pull/2073/head
$ git checkout -b pr-2073 FETCH_HEAD
On the other front I seem to remember GitHub giving diffs but it does not seem to have downloads for them anymore.
You can just add .diff
or .patch
to any github url for a commit or PR, e.g.: https://github.com/TypeStrong/ts-node/pull/2073.diff
from ts-node.
@francip i made a fork of your example, adding a function:
.
├── README.md
├── another-function.ts # this file.
├── index.ts
├── package-lock.json
├── package.json
└── tsconfig.json
...and importing that funcion using the ESM syntax according to the node.js documentation:
import { anotherFunction } from './another-function.js'; // Here
export function hello(who: string = "world"): string {
return `Hello ${who}! `;
}
console.log(hello("ts-node"));
anotherFunction();
The result of execute npm run start
is the following:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /home/sleep-written/projects/node.js/ts-node-test/index.ts
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
at defaultLoad (node:internal/modules/esm/load:143:22)
at async nextLoad (node:internal/modules/esm/hooks:866:22)
at async nextLoad (node:internal/modules/esm/hooks:866:22)
at async Hooks.load (node:internal/modules/esm/hooks:449:20)
at async handleMessage (node:internal/modules/esm/worker:196:18) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
However, with npm run start:success
works as you suggest. But when I had to update my library to be compatible with node 20, I had to write my own loader to resolve the path aliases. Since I had to write the loader myself, I ran into exactly that problem with the extensions.
In conclusion, as you say, if you only want to make ts-node able to execute typescript code, you would simply have to implement a module that is preloaded with the --import
flag.
from ts-node.
Getting same issue, but I have a working version that I solved this issue on, and now a new project on which it does not. It is something else and I cannot remember what it is. Will report back once I have debugged the issue.
from ts-node.
Heres a working example with node v21.5.0, typescript v5.3.3, ts-node v10.9.2 :- https://github.com/AaronNGray/ts-node-example
This is not an ESM package. Try setting type to module in your package.json.
from ts-node.
First of all ,I already looked at #1997 and most of other websites to solve the problem but I couldn't.This error is throwed when I try to use in Node v21.5.0.I realized that The problem is node version,when I updated Node version to v19.0.0 it works.Could you please update ts-node to work in new Node versions.
Could you please provide a minimal example of what does not work and then we can try to figure out why !
I've modified the project a bit and created new repository.link: https://github.com/cibilex/ts-node-err
This project doesn't work in node v21.5.0 while works In node v16.20.2 for me.
from ts-node.
First of all ,I already looked at #1997 and most of other websites to solve the problem but I couldn't.This error is throwed when I try to use in Node v21.5.0.I realized that The problem is node version,when I updated Node version to v19.0.0 it works.Could you please update ts-node to work in new Node versions.
Could you please provide a minimal example of what does not work and then we can try to figure out why !
I've modified the project a bit and created new repository.link: https://github.com/cibilex/ts-node-err
This project doesn't work in node v21.5.0 while works In node v16.20.2 for me.
You modified start to : -"start": "ts-node-esm src/index.ts"
The version I posted last works AFAICT without proper testing, but I did do an import
Note: --loader
maybe deprecated.
https://github.com/AaronNGray/ts-node-example/tree/ts-node-esm-loader
NOTE: I have just found this does not seem to support imports !!!
from ts-node.
@cibilex - Theres a pull request waiting :- #2073
from ts-node.
@cibilex - Did you manage to add the two commits to a ts-node fork or did you just patch the diff's ?
If you used git I would love to know how ! On the other front I seem to remember GitHub giving diffs but it does not seem to have downloads for them anymore. Or did you just use a reference to the repo in package.json dependencies ?
from ts-node.
@cibilex - Wow great thanks, think I was over complicating things :)
from ts-node.
Is there an update on the progress of this bug?
from ts-node.
First of all ,I already looked at #1997 and most of other websites to solve the problem but I couldn't.This error is throwed when I try to use in Node v21.5.0.I realized that The problem is node version,when I updated Node version to v19.0.0 it works.Could you please update ts-node to work in new Node versions.
Best regards.
Odd-numbered versions of node are typically beta versions and should not be supported
from ts-node.
I realised that the issue that I had was not with the version of node or ts-node but I was importing a typescript dependancy incorrectly from a library. removing the dependency i was importing and importing the .js from the library rather that a typescript file fixed this issues.
from ts-node.
@djomajeff - building a repo following your instructions I am getting :- AaronNGray/ts-node-esm-test#1
I added you to the repo.
from ts-node.
One of the reasons for the failures with ts-node in ESM projects is linked to the file extensions in import statements. To understand the problem, let's envision this directory structure:
.
├── node_modules
├── src
│ ├── sum.ts
│ └── index.ts
├── package.json
├── package-lock.json
└── tsconfig.json
In ESM, you must use the .js
extension in your imports. For example, check ./src/index.ts
:
import { sum } from './sum.js'; // ...but in reality, the actual file ends in ".ts"
const r = sum(55, 66);
console.log('value:', r);
Thus, when the original ts-node loader receives that import ./sum.js
, it tries to resolve it as a ".js" file. But in reality, that file does not exist, and the available file ends with ".ts". To solve the problem, you have several options:
-
Rename all your imports from ".js" to ".ts":
This solves the problem with ts-node, but when you transpile your project, you will need to transform your imports back to ".js".
-
Modify the ts-node loader:
You must intercept all import statements and change the extension from ".js" to ".ts" only when attempting to execute ".ts" files.
I have created a module called @bleed-believer/path-alias (with ts-node as a dependency). Initially created to resolve path aliases, it now also solves this issue. To execute TypeScript files in ESM directly in Node 20 and above:
# Install the library:
npm i --save @bleed-believer/path-alias
# Execute your code using the command line:
npx bb-path-alias ./src/index.ts
# ...or if you need to execute using the node executable:
node --import @bleed-believer/path-alias ./src/index.ts
from ts-node.
@sleep-written Both ECMA 2025 and ECMA 2020 do not specify explicit extension, and the only import examples I found in both ( ECMA 2025, ECMA 2020 ) do not include any extension. But that's neither here, nor there...
If you look at my example, you will see nowhere do I use import statement, and the failure happens with a single file project. This is a basic scenario where ts-node should work without extra intermediaries.
Though, for folks who are just looking for a quick workaround, your solution might be good.
from ts-node.
Hi @francip, your example is relevant for Node.js versions 18 and earlier. However, when using Node.js version 20 or above with the command:
node --loader ts-node/esm ./src/index.ts
...you might encounter the following output:
(node:2036531) ExperimentalWarning:
--experimental-loader
may be removed in the future; instead useregister()
:
--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("ts-node/esm", pathToFileURL("./"));'
(Usenode --trace-warnings ...
to show where the warning was created)
To address this, consider creating a ./ts-node.register.mjs
file with:
import { pathToFileURL } from "node:url";
import { register } from "node:module";
register("ts-node/esm", pathToFileURL("./"));
And then launch your application with:
node --import ./ts-node.register.mjs ./src/index.ts
This approach should seamlessly solve the issue, unless your project uses relative imports. According to the Node.js import
specifiers:
Relative specifiers like
'./startup.js'
or'../config.mjs'
. They refer to a path relative to the location of the importing file. The file extension is always necessary for these.
More details of this problem are explained in this comment.
If executing your file with the ./ts-node.register.mjs
preloaded results in errors due to relative imports, consider using my module register at @bleed-believer/path-alias. This or building a custom ts-node module register, with the required logic for address relative/absolute imports, could provide a solution too.
from ts-node.
My example is relevant for node v18.19 and above, where ts-node --esm index.ts
command is broken and returns ERR_UNKNOWN_FILE_EXTENSION. (the original problem this issue tracks)
The node --loader ts-node/esm index.ts
syntax being deprecated is a separate issue, and the simplest workaround for that is using node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("ts-node/esm", pathToFileURL("./"));' index.ts
or your library which essentially does very similar thing. And yes, they both will successfully run index.ts, which is why I listed them as potential workarounds.
However, this workaround does not help people who want to use ESM, webpack, and TS for their webpack config, as webpack internally calls ts-node, thus hitting the same issue.
from ts-node.
Related Issues (20)
- console.log('hi'); fails in REPL with "module": "esnext" HOT 1
- UnhandledPromiseRejection: ts-node-esm does not display type checking results HOT 6
- ts-node doesn't run ESM modules as expected, either refusing`import` statements in ts file or not being able to run `.ts` files HOT 6
- In REPL, can't access the previous line's return value via `_`
- Error when using ts-node with tsonfig/bases and typescript 5.3.2 HOT 3
- "TypeError: require(...) is not a function" in ts-node dependecy
- extends of tsconfig.json doesn't work when it reference to other package HOT 2
- add --env-file environment variable similar to node v:20.6.0 HOT 9
- ERR_UNKNOWN_FILE_EXTENSION since Node.js 18.19.0 (works fine with 18.18.2) HOT 17
- Support clearing the local context with .clear when starting programmatically
- In #!/bin/bash clear apt update apt upgrade apt install figlet -y figlet Basic Installation apt install toilet -y apt install cowsay -y apt install nano -y apt install ruby -y gem install lolcat figlet -f big Done !!! | lolcat echo echo -e "\e[1m Now Run \e[32mbash t-ban.sh\e[0m...!!!" echo echo -e "\e[1m\e[32m Developed by :\e[33m Sutariya Parixit (8h4i)" echo echo( there are Issu for In title The Over view and synonyms Not Seen in his real formet
- ts-node is unable to resolve tsconfig files in Yarn workspace HOT 2
- ESM: Cannot find module './index.js' and requiring "imaginaryUncacheableRequireResolveScript" HOT 2
- "Cannot find package" when running mocha and importing between packages in monorepo HOT 1
- Can't use `--eval` with ESM
- calling `repl.start()` causes a doubling of stdin/stdout
- ts-node cannot run mixed ESM/CJS project HOT 2
- Cryptic error on invalid tsconfig.json, e.g. if attempting to extend nonexistent tsconfig file
- ts-node doesn't resolve extended tsconfigs if they originate from the export fields of packages
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ts-node.