Modules: [web-interop] Parsing Goal vs MIME

Created on 8 Feb 2018  路  2Comments  路  Source: nodejs/modules

Even if the MIME has been considered non-blocking issue for the first iteration, I'm sure it'll come back in every possible occasion so I'd rather dedicate a single thread for this discussion in order to understand the direction, as opposite of underling this concern in other strictly unrelated threads.

Current Status

Node always used file extensions to distinguish parsing goals, and this worked well.

However, the assumption when a JavaScript file is encountered, as regular .js, is that such file would be an application/node like MIME type.

This is already conflicting with the meaning .js files had for the last 20+ years on the Web, where JS was born.

Current ESM Status

The proposed workaround to prevent parsing resolution conflicts with JavaScript files, is to use another extension that would conflict with the browser ecosystem built around .js.

Not only .mjs will need adoption by all existing software, operating systems, and static servers, the extension solution is in conflict with the web because the parse goal on the web is provided by the <script type> or by the usage of dynamic import(ESM).then(...) from non-module content.

The MIME on the web is equivalent for both ESM and non module JavaScript and the resolution has no conflict thanks to explicit opt-in defined by publishers.

Explicit Parsing Goal as ESM

I understand that .mjs is a workaround to solve parsing goal ambiguity, even if it still requires filesystem discovery and rules if there are two files with same name and both .js and .mjs extensions when imports omit such extension, but I would not understand an explicit ESM opt in flag that is incapable of loading as ESM regular .js files like every other player is already capable of:

  • <script type=module src=esm.js>
  • jsc -m esm.js
  • js52 -m esm.js

Explicit Parsing Goal Proposal via Flag

Whenever the command node -m esm.js is executed, the loaded JavaScript file will be handled as ESM and never as CJS. The -m is a name borrowed from others, it can be different if needed.

If the loaded file is CJS the program will throw an error because module and exports are unavailable in ESM and this is also undefined.

Whatever mechanism we'll decide to have to import CJS from an explicit ESM opt in executed program, will use application/node assumption for required and required files only.

Everything else that is imported via ESM syntax will be 100% ESM without any possible ambiguity: it's explicitly ESM.

Explicit Parsing Goal Proposal via npm

Whenever the package.json explicitly opts in as ESM, all its JavaScript files should be handled as ESM and never as CJS.

Benefits for the community

If we have 2 options to resolve forever ESM dispute in terms of what's ambiguous and what is not, I believe the effect could be summarized in these points:

  • explicit migration pattern. node will be 100% backward compatible without the flag
  • when there is no flag, the ambiguity could be resolved via MIME or, if really necessary, .mjs extension
  • the community will have a way to ignore the extension, go full in with the flag, or adopt the extension. We don't decide here for them, we listen instead.
  • bundlers can take better hints of how the targets should be handled.

I would like to understand if there's a chance to have consensus here or, in general, what is missing to make node ship ESM and its community decide the best way to move forward.

Thank You.

Most helpful comment

this is already happening in https://github.com/nodejs/node/pull/18392

All 2 comments

this is already happening in https://github.com/nodejs/node/pull/18392

so I can assume there is already consensus on this directly from core? If that's the case, I can close this already. Thanks for the link.

Was this page helpful?
0 / 5 - 0 ratings