Nodejs, TypeScript, ts-node-dev & top-level await
TL;DR: Don't use ECMAScript modules with ts-node or ts-node-dev (yet); just refactor the top-level await out
Today I tumbled down the same rabbit hole, starting with the innocuous error:
Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
As a result, I felt inclined to edit my tsconfig.json
and set module
to esnext
, which in turn forced me to set moduleResolution
to node
and finally add type: module
to my package.json
. What I failed to realize (and IMO they shouldn't suggest this in the error message-- you can just simply refactor the top-level await out), that this switches the module resolution strategy of NodeJS from CommonJS to ESM. This is actually a big deal for many reasons:
- ESM support is still experimental in ts-node
- Mixing CJS and ESM modules may lead to problems
- There are open issues with ESM support in NodeJS itself
I feel that at this time (december 2020) the NodeJS ecosystem is still in transition from the classic CommonJS modules to the new ECMAScript modules. As a result other tech like ts-node or ts-node-dev are transitioning as well and support can be flaky. My advice is to stick with CommonJS until the dust has settled and these things "just work" out of the box.