Skip to content

journal 2020 08 30: Understanding NodeJS ES modules

Eason Chen edited this page Aug 30, 2020 · 4 revisions

Consolidating the knowledge around experiments run yesterday

I made hardly any code contributions today, but I carefully read through the NodeJS documentation on its handling of ES modules. In particular, I read about how to run code written using ES modules, under various circumstances:

  • Interactively over the node REPL
  • Piped into STDIN of node
  • Interpreted as a script via some node my-script.js command

Yesterday I was randomly reading a bunch of material, not understanding how everything fits together:

  • unofficial blogposts counting the history of nodejs module system development: (LogRocket)
  • ideas about asking TypeScript to output .mjs files: (Github issue)

but today I read the NodeJS official documentation, for NodeJS v14:

The outcome of reading this documentation is that the random fiddling that I made work yesterday actually makes sense now, and I kind of know what I'm doing. I'm also actually writing out the body of the wiki post for yesterday; see it again:

A bottleneck: ts-node

So actually I know how to get TypeScript and NodeJS all operating on ES modules:

  • In tsconfig.json, use a high target (e.g. es2015, es2020, esnext), so that module is implied to be default at least es2015.
  • In package.json use "type": "module" so that ts-out/*.js are interpreted by NodeJS as ES modules, not CommonJS modules.

However, the other workflow I want to support, instead of just compiling TypeScript source code and running the compilation output separately, is to use ts-node as an interpreter --- but ts-node isn't quite there yet:

While I am more-or-less comfortable now about handling ES modules in TypeScript and NodeJS, including back-and-forth compatibility, I know hardly anything about ts-node --- and nothing works so far: not as a REPL, neither as an interpreter. Here's a dead-end branch:

As such, just in order to allow ts-node to work as REPL and interpreter so that I can continue my development, I might have to switch my TypeScript compilation output to CommonJS modules, and work everything else out from there.

Luckily, Rollup seems pretty smart and easy to use, and seems to be able to handle whatever I'm throwing at it --- it even appears to be able to back-transpile CommonJS modules into ES modules (why would you ever need that???), so there are no visible downstream consequences of switching to CommonJS/ES5 as the interchange format.

Clone this wiki locally