Skip to content

Ill-formed exports field lacks clear error message when using ESM and self-resolve #31510

Description

@aduh95
  • Version: v14.0.0-pre (master)
  • Platform: any
  • Subsystem: esm

Let's take this package.json:

{
  "name":"pkgname",
  "exports" : {
    "import": "./file.mjs",
    "require": "./file.cjs",
    "./custom-export" : "./another/file.js"
  }
}

When I try to use a self-resolve import, the error I get doesn't give any clue on why it has failed:

$ echo "import 'pkgname'" > entry.mjs
$ node entry.mjs
(node:95454) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/resolve.js:58
  let url = moduleWrapResolve(specifier, parentURL);
            ^

Error: Cannot find package 'pkgname' imported from .../entry.mjs
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:58:13)
    at Loader.resolve (internal/modules/esm/loader.js:85:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:188:40)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:42:40)
    at link (internal/modules/esm/module_job.js:41:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

When using require, the error is quite clear on what the problem is and what solution to apply:

$ node -e "require('pkgname')"
internal/modules/cjs/loader.js:481
      throw new ERR_INVALID_PACKAGE_CONFIG(basePath, '"exports" cannot ' +
      ^

Error [ERR_INVALID_PACKAGE_CONFIG]: Invalid package config for '...', "exports" cannot contain some keys starting with '.' and some not. The exports object must either be an object of package subpath keys or an object of main entry condition name keys only.
    at isConditionalDotExportSugar (internal/modules/cjs/loader.js:481:13)
    at applyExports (internal/modules/cjs/loader.js:497:7)
    at trySelf (internal/modules/cjs/loader.js:451:23)
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1013:22)
    at Function.Module._load (internal/modules/cjs/loader.js:913:27)
    at Module.require (internal/modules/cjs/loader.js:1097:19)
    at require (internal/modules/cjs/helpers.js:72:18)
    at [eval]:1:1
    at Script.runInThisContext (vm.js:120:20)
    at Object.runInThisContext (vm.js:311:38) {
  code: 'ERR_INVALID_PACKAGE_CONFIG'
}

Also, I find the documentation not very clear when it comes to package.json formatting; there are some information on the ES Modules page, and a (somewhat outdated) guide on the nodejs.org website, but other than that, I failed to find a clear explanation on how I can make self resolve work (other than the error message).

CC @jkrems

Activity

  1. hybrist commented on Jan 26, 2020

    @hybrist
    Contributor

    Thanks for the report! We should definitely aim for parity in these error messages. This sounds like the error message isn't specifically about self resolve but about exports. I assume the same behavior would apply when trying to import the package from the outside..?

    [...] but other than that, I failed to find a clear explanation on how I can make self resolve work (other than the error message).

    Yeah, unfortunately the docs are still lacking in terms of proper guides. The TL;DR of self resolve is: It should roughly work as if the package was installed as a dependency of itself, as long as the package is using exports. But the only thing we really document right now is how it integrates into the overall resolution algorithm: https://nodejs.org/api/modules.html#modules_all_together

  2. changed the title [-]Package self resolve lacks clear error message when using ESM[/-] [+]Ill-formed exports field lacks clear error message when using ESM[/+] on Jan 26, 2020
  3. aduh95 commented on Jan 26, 2020

    @aduh95
    ContributorAuthor

    I assume the same behavior would apply when trying to import the package from the outside..?

    No it seems to be related to self-resolve; I moved the test repository in a node_modules folder, and try to to import it, I got a clearer error message:

    $ mkdir -p node_modules/pkgname
    $ mv package.json node_modules/pkgname
    $ node entry.mjs
    (node:74691) ExperimentalWarning: The ESM module loader is experimental.
    internal/modules/esm/resolve.js:58
      let url = moduleWrapResolve(specifier, parentURL);
                ^
    
    SyntaxError: Cannot resolve package exports in .../node_modules/pkgname/package.json, imported from .../entry.mjs. "exports" cannot contain some keys starting with '.' and some not. The exports object must either be an object of package subpath keys or an object of main entry condition name keys only.
        at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:58:13)
        at Loader.resolve (internal/modules/esm/loader.js:85:40)
        at Loader.getModuleJob (internal/modules/esm/loader.js:188:40)
        at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:42:40)
        at link (internal/modules/esm/module_job.js:41:36) {
      code: 'ERR_INVALID_PACKAGE_CONFIG'
    }
  4. changed the title [-]Ill-formed exports field lacks clear error message when using ESM[/-] [+]Ill-formed exports field lacks clear error message when using ESM and self-resolve[/+] on Jan 26, 2020
  5. aduh95 commented on May 1, 2020

    @aduh95
    ContributorAuthor

    Fix landed in 58de9b4.

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