Skip to content
This repository was archived by the owner on Sep 2, 2023. It is now read-only.
This repository was archived by the owner on Sep 2, 2023. It is now read-only.

Feature: Named exports when importing CJS #81

Closed
@giltayar

Description

@giltayar

Currently in NodeJS, if I import from a CJS module,

import ns from `./cjs-module.js`

It will allow this, but won’t allow named exports, i.e. the following is not allowed:

import {namedSomething} from `./cjs-module.js`.

This is called transparent interop.
The reason that NodeJS doesn’t allow named exports is that determining what those exports are MUST happen in the parsing phase of the ESM Spec (according to some, although there is contention about that too), and executing code is not allowed at or prior to that phase. But a CJS module’s exports can only be determined by evaluating the code in it (static analysis of JS is not an option as it is not determined to always give the correct results).

This would maybe have been cool if NodeJS was the first ESM implementation, but people are used to the babel way of doing modules, and in the babel world, named exports from CJS modules are allowed. This is because babel does not conform to the ESM spec to the letter (it can’t, because it just transpiles ESM to CJS).

And, good or bad, developers expect to use named exports when importing CJS.

I see these options:

  1. Continue the existing way (no named exports for CJS)
  2. Don’t conform to the spec when importing CJS
  3. Do late-linking/shaping of named modules based on late evaluation of CJS module
  4. Disallow transparent interop, and enable import.meta.require (or equivalent) to enable importing CJS from ES modules
  5. Enable metadata in the CJS module that can statically describe the exports for ESM, e.g. something like //export default; export foo, bar; at the head of the CJS file, thus enabling named exports when importing the file.

I am sure there are others options, so if you have another option besides those four, please add it here.

It would be great if for each options you specify pros and cons, or at least if you don’t like the option, specify a clear and simple use case that would be problematic if the option was chosen.

Edit by @GeoffreyBooth: Use case 12.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions