Skip to content
This repository was archived by the owner on Apr 16, 2020. It is now read-only.
This repository was archived by the owner on Apr 16, 2020. It is now read-only.

Document behavior of ESM packages that lack main field #73

Closed

Description

@coreyfarrell

Example package.json:

{
  "name": "foo-bar",
  "type": "module"
}

Assuming index.js exists, what is the expected behavior of import something from 'foo-bar'? Is this expected to throw a resolve error due to "type": "module" as would happen trying to import from a directory? If "type": "module" where not specified (foo-bar is CJS) would the import statement follow the CJS resolution rules and find index.js?

I thought of this looking at #72, thinking about expected behavior when specifying "exports": {} without main. It seems like this could be uses to provide CLI only packages that intentionally do not provide an API.

Activity

  1. ljharb commented on Jul 4, 2019

    @ljharb
    SponsorMember

    In CJS, omitting a main and an index.js makes your package not requirable. I’d expect the same for ESM.

  2. coreyfarrell commented on Jul 4, 2019

    @coreyfarrell
    MemberAuthor

    My question is about omitting main but providing an index.js. I'd expect this to fail to resolve when the package type is module?

  3. hybrist commented on Jul 4, 2019

    @hybrist
    Contributor

    I would assume that ESM defaults to main being ./index (or ./index.js). The side effect of ./index would be that only CJS files would work (or an extensionless file in the case above... maybe?).

  4. hybrist commented on Jul 4, 2019

    @hybrist
    Contributor

    It seems like this could be uses to provide CLI only packages that intentionally do not provide an API.

    I'd love to define main in terms of exports. In which case setting main to an empty array or null would be perfectly valid once that syntax is supported in exports. And it would cleanly prevent an import of the package with a more meaningful error than "module not found".

  5. ljharb commented on Jul 4, 2019

    @ljharb
    SponsorMember

    I would expect it to work, with an index.mjs as well.

  6. hybrist commented on Jul 4, 2019

    @hybrist
    Contributor

    With extension resolution magic turned on - yes. Without - I wouldn't expect index.mjs to work in the case above.

  7. ljharb commented on Jul 4, 2019

    @ljharb
    SponsorMember

    In ESM even without extension resolution, I’d expect a literal index.mjs to work.

  8. coreyfarrell commented on Sep 10, 2019

    @coreyfarrell
    MemberAuthor

    I would assume that ESM defaults to main being ./index (or ./index.js). The side effect of ./index would be that only CJS files would work (or an extensionless file in the case above... maybe?).

    See https://nodejs.org/dist/latest/docs/api/modules.html#modules_all_together, specifically LOAD_AS_DIRECTORY. If "main" is a falsy value, GOTO 2. which is does LOAD_INDEX(x). So if main is falsy I'd expect ESM to fail here unless the target is a CJS module. An edge case is what happens if main is falsy and type: module is set but index.cjs, index.json or index.node exist.

    IMO https://nodejs.org/dist/latest/docs/api/esm.html#esm_package_entry_points should be explicit about what happens when main is not specified. The edge cases I can think of:

    1. type !== 'module' - use CJS resolution algorithm
    2. type === 'module' and index.cjs, index.json or index.node exist - use CJS resolution algorithm but excluding extension .js?

    Also noticed while looking at this https://nodejs.org/dist/latest/docs/api/modules.html#modules_all_together LOAD_INDEX and LOAD_AS_FILE list .js, .json and .node extensions. Should .cjs be listed here, and if so what priority does it have? Or is .cjs only resolved when --experimental-modules is enabled?

    Another related edge case is what happens when an in-package directory contains an index.cjs. Should import './some-directory'; find ./some-directory/index.cjs?

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions