ReferenceError: exports is not defined in ES module scope
I am trying to run my bot and am presented with the following error
What do I need to do to resolve this?
Since there are so many files involved and the length would exceed the Discord limitations, I created a gist with everything I think is needed.
https://gist.github.com/dustin-lennon/30bee1b477e4de8dae3459f4fa4c6b96
Gist
ReferenceError: exports is not defined in ES module scope
ReferenceError: exports is not defined in ES module scope - TraktClient.ts
Solution:Jump to solution
so when using pnpm you need to hoist all of
@sapphire/*
because otherwise TS cannot properly resolve module augmentations. I forgot the exact option but it's one of the hoist pattern options.
As for your root cause, it really comes down to how you configured tsconfig. The modern standard is to use node16
for both module
and moduleResolution
then either use "type": "commonjs"
or "type": "module"
in your package.json based on whether you respectively want a CJS or ESM runtime.
Once that is done and you compile with either exclusively swc (which you seem to use yet you also mention ts-node, they DO NOT work together, also we discussed the downsides of ts-node) or alternatives such as tsc
/ tsc-watch
/ tsup
....6 Replies
I figured things out. Had a multiple things to change.
In my
tsconfig.json
I added
I needed to adjust my call to my TraktClient to using ./TraktClient.js
I had a typo in my bot.ts
with the first import. It was #/lib/setup
when it should have been #lib/setup
Locations in my code where I was calling my constants file needed to be adjusted to resolve errors.
well... I thought things were fixed
Updating my Gist with my latest changes and I'm currently getting the following error Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@sapphire/pieces' imported from /home/node/dist/lib/constants.js
resolved by adding @sapphire/pieces
to my package.json
. was weird how it worked in one environment but not another without that thereAre you using pnpm by any chance @Demonic Pagan ?
Also regarding ts-node:
TL;DR: Do not use
ts-node
, use tsc-watch
instead.
We very strongly discourage using ts-node
because it was never meant to be used for bots.
ts-node
is designed for REPL
purposes. That's short for Read Eval Print Loop
.
Which means to read some code, dump it in an eval()
statement, print the result, and loop.
A discord bot is not that.
A Discord bot sets up a permanent websocket connection to the discord server and connects to the rest gateway.
There is read yes, but no eval, no print, and no loop.
So what should you use instead?
The most ideal way is to just use the watch
flag of tsc
(tsc --watch
) and run node dist/index.js
to run your bot, then cancel that process and restart it when you have changes that require restarting.
You would open 2 terminal tabs, 1 in which you run tsc --watch
and another in which you run the bot.
This is in particular the most ideal way, because Discord has a limit to the amount of times you can login with your bot, or register commands, per day.
Constantly logging in over and over again due to an auto-restarting process will get you close to that limit very quickly and once you exceed it, your development will be halted entirely for the current day.
However, this can be quite tedious so a great package to use instead is tsc-watch
.yes, i am
in regards to
ts-node
would I replace that in my tsconfig.json
with tsc-watch
?
i probably should stop trying to run the bot in a docker container since it doesn't really make a bit of difference since i'm already developing in a linux environmentRemove it from tsconfig and just use tsc-watch for dev and tsc for prod build. Correct your main property to dist/whatever and done
Solution
so when using pnpm you need to hoist all of
@sapphire/*
because otherwise TS cannot properly resolve module augmentations. I forgot the exact option but it's one of the hoist pattern options.
As for your root cause, it really comes down to how you configured tsconfig. The modern standard is to use node16
for both module
and moduleResolution
then either use "type": "commonjs"
or "type": "module"
in your package.json based on whether you respectively want a CJS or ESM runtime.
Once that is done and you compile with either exclusively swc (which you seem to use yet you also mention ts-node, they DO NOT work together, also we discussed the downsides of ts-node) or alternatives such as tsc
/ tsc-watch
/ tsup
.
The error in particular suggests that you compiled for CJS but are running as ESM (i.e. you specified "type": "module"
in your package.json) which causes the error of exports
not being defined in an ES module (ESM) scope. So either change your compilation to ESM, or change "type": "module"
to "type": "commonjs
.