iter-tools: Concerning ES Modules: `node --experimental-modules` cannot load `iter-tools/es2018/index.mjs` due to import URLs lacking .mjs extension

iter-tools provides *.mjs files alongside *.js files as an ES module alternative. However, Node.js cannot load it due to import URLs lacking extension, which is required for ES modules.

Take this example repo:

  • If you run npm run import-iter-tools-and-print-it, it will emit an error.
  • However, if you run npm run import-tsfun-and-print-it, it will succeed. (@tsfun/* are packages that I made which support both CommonJS modules and ES modules)

I also doubt that bundlers (such as parcel, webpack) are going to prioritize loading *.mjs first.

Proposal

Use @make-mjs/main to convert *.mjs files that import URLs without extension to *.mjs files that import URLs with proper suffixes (either .mjs, /index.mjs or others depend on importing targets).

Example Code:

import main, { EventType } from '@make-mjs/main'
import path from 'path'

// main() returns an async iterator
const events = main({
  dirname: 'src',
  getNewPath: filename => path.join('dist/es2018', path.basename(filename)),
  /* more options */
})

for await (const event of events) {
  if (event.type === EventType.BeforeWrite) {
    console.log('Making', event.file.path)
  }

  if (event.type === EventType.AfterWrite) {
    console.log('Made', event.file.path)
  }
}

How does @make-mjs/* work?

It uses @babel/parser to convert a file into AST, then find import/export URLs within that AST and correct it, and then uses @babel/generator to create output code.

Be aware

  • I just completed that package yesterday, feature is lacking (enough for my use case).
  • I did not have iter-tools in mind when I created @make-mjs/*. I only made it for my own packages (such as @tsfun/*). As such, it won’t adapt to iter-tools’s need unless developers of iter-tools submit pull requests to it.
  • I am lazy, and I am busy with other things, so while feature requests is welcomed, pull requests is more welcomed.
  • Tests are barely enough: While I am confident that my package works when all tests passed, when they fail, I am not sure if I know where it went wrong. For this reason, pull requests that add tests are most welcomed.
  • May not work properly on Windows: It is because the difference between URL separator (always be /) and filesystem path separator (/ on POSIX and \ on Windows), combined with the fact that I do not use Windows. If someone can ensure it works on Windows, I will gladly accept pull requests.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 20 (10 by maintainers)

Most upvoted comments

Ah, right. OK. I’ll do a similar setup iter-tools then, though I think I’ll just write a babel plugin if I end up needing to, since I’m using babel already.