Skip to content

Loaders and exports field #43

Open
@arcanis

Description

@arcanis

As a practical example, let's say that we have:

/node_modules/foo/package.json

{
  "name": "foo",
  "exports": {
    "./utils": "./sources/utils"
  }
}

/node_modules/foo/sources/utils.ts

// Content doesn't matter

/index.js

import 'foo/utils';

And let's say that we have a composed pipeline:

  • The PnP resolver

    • will get foo/utils as input
    • will want to turn the foo segment into /node_modules/foo (and leave the rest untouched)
  • The TS resolver

    • will want to add the.ts extension to whatever foo/utils resolves into

What should return the PnP resolver?

a. "/node_modules/foo/utils"
b. "/node_modules/foo/sources/utils"
c. "/node_modules/foo/sources/utils.js"
d. ["/node_modules/foo", "./utils"]

Option A is incorrect; the exports field doesn't apply when a file is loaded through an absolute path:

It is not a strong encapsulation since a direct require of any absolute subpath of the package such as require('/path/to/node_modules/pkg/subpath.js') will still load subpath.js.

Option B is good, but requires the PnP loader to not only resolve foo into node_modules/foo, but also ./util into ./sources/utils. To do that requires either to reimplement the exports resolution (with the risks in terms of correctness that come with it), or Node to provide a import.meta.resolveExports('foo/utils', '/node_modules/foo') utility that would do the job for us. This is what we currently do, by embedding a copy of resolve.exports into our loader.

Option C essentially prevents the TS loader from working, since the extension is already resolved.

Option D (which isn't supported by Node at the moment) lets the PnP loader resolves the bare identifier part which Node would presumably process through the same import.meta.resolveExports function described earlier, but keeping it internal.

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