Skip to content

Instantly share code, notes, and snippets.

@thomasboyt
Created June 2, 2016 19:49
Show Gist options
  • Save thomasboyt/e8cccee512cb29989454a32e52ad831b to your computer and use it in GitHub Desktop.
Save thomasboyt/e8cccee512cb29989454a32e52ad831b to your computer and use it in GitHub Desktop.

No, .mjs is not a Python 3-like split

Seen a few tweets on this. I want to dispel some FUD.

Node is probably going to introduce a new file extension for JavaScript modules, .mjs. The reasons for this are long and perilous, and trying to summarize the discussion that led to it is maddening. The short version is that ES6 modules have different semantics from existing scripts, and need to be executed differently. In browsers, this is done with <script type="module">. In Node, this will be done by analyzing the file extension of the imported file.

I'll be honest: I don't love this solution! I was rooting for the TC39 counter-proposal. But I also understand the solution that the Node developers chose, and why they chose it.

The new file extension is a good enough solution. You can read the draft spec if you want the details of how it's implemented, it's a very simple spec. Here's a few cool things that it enables:

  • In new versions of Node, CommonJS modules can import .mjs modules, and ES modules can import CJS modules just as people already do with Babel, etc. This is actually awesome and I'm shocked it worked out; I always assumed Node would require CJS modules to be require()d and ES modules to additionally set module.exports to support CJS. It'll also ensure existing modules built with Babel won't break.
  • In existing versions of Node, CommonJS modules won't be able to accidentally import .mjs modules - it has no knowledge of the extension. However, they will be able to import "vanilla" .js modules shipped alongside them. This will make it easy for package authors to transpile ES6 modules to CommonJS for old versions of Node, if they want to support them.
  • All tooling has to do to support the new extension is know that mjs is a file extension that means "JavaScript module." Tools like ESLint should work fine out of the box, editors can have the extension added to their language-matching regexps, etc.

This is good! This is the opposite of a Python-like split. We've got interop between modules and existing scripts. Upgrading Node won't break existing scripts. For users who can't or won't upgrade Node, there's an incredibly simple transpilation step. There will be some tooling work required, but not much.

@liudonghua123
Copy link

nice work 💯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment