Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exports support, dynamic import from CJS support, package boundary emission #129

Merged
merged 27 commits into from
Jul 4, 2020

Conversation

guybedford
Copy link
Contributor

@guybedford guybedford commented Jun 26, 2020

This PR implements three new features

  • Support for the exports field as per Node.js, including conditional exports and package name self-resolution
  • Support for emitting package.json files when they inform the module format interpretation of a file - this results in more package.json files being emitted, as can be seen in the unit test updates here
  • Support for dynamic import in CJS files being traced

Exports support is by default disabled, and enabled by setting the exports: true option or providing a custom condition list.

For example, if building for Node.js 10, you'd want the exports support to be disabled since the "main" resolution would still apply - which would not be traced if enabling exports (when exports overrides it).

src/node-file-trace.js Outdated Show resolved Hide resolved
src/node-file-trace.js Outdated Show resolved Hide resolved
src/resolve-dependency.js Outdated Show resolved Hide resolved
Copy link
Member

@styfle styfle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are only passing on Windows.

Both macOS and Linux appear to be stuck in an infinite loop.

@guybedford
Copy link
Contributor Author

@styfle I've implemented an alternative that separates "exports" from "exportsOnly" as a separate feature.

The default behaviour now will trace both exports and the main.

Setting exports allows changing the list of exports conditions that are traced.

Then setting exportsOnly: true is a mode for Node.js 12+ only which will no longer trace the legacy main.

@guybedford
Copy link
Contributor Author

The remaining windows failures here are pretty odd - I can't replicate them on my Windows machine running the same Node.js version...

@guybedford
Copy link
Contributor Author

Finally traced the issue... this should be good to merge.

@styfle
Copy link
Member

styfle commented Jun 28, 2020

@guybedford This doesn't work with es-get-iterator@1.1.0.

For example:

mkdir example && cd example
yarn init -y && yarn add es-get-iterator@1.1.0
echo 'require('es-get-iterator')' > start.js
nft print start.js

I would expect node_modules/es-get-iterator/index.js to be included but it is not.

Can we add an integration test for es-get-iterator?

@guybedford
Copy link
Contributor Author

Nicely spotted, ok I've added the integration test and also included a unit test for the array fallback case.

package.json Outdated
@@ -26,6 +26,7 @@
"acorn-numeric-separator": "^0.3.0",
"acorn-static-class-features": "^0.2.1",
"bindings": "^1.4.0",
"es-get-iterator": "^1.1.0",
Copy link
Member

@styfle styfle Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be devDependencies and the version number should be pinned 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not currently pinning any versions in this repo! I forget that's the preferred pattern, let's get a separate PR up for that.

src/resolve-dependency.js Outdated Show resolved Hide resolved
@@ -90,11 +90,14 @@ function getExportsTarget (exports, conditions, cjsResolve) {
condition === 'import' && !cjsResolve ||
conditions.includes(condition)) {
const target = getExportsTarget(exports[condition], conditions, cjsResolve);
if (target !== undefined)
if (target !== undefined && (target === null || target.startsWith('./')))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it expected that this if statement does not match the one on line 82 above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes they should be the same - fixed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guybedford They are a little different still. Why use continue with one and not the other?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, they are written differently but do the same thing. So the definition of the array fallback is that it will continue on invalid items, which is supposed to be different from the object conditions form. But I just realise now we're not actually doing that either! Done.

Note the extreme exports edge cases get pretty complex but aren't needed in 99% of cases... so we are just rattling out the "exports": [{}, { "asdf": null }, null] kinds of odd behaviours here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guybedford I don't see a test for the array of exports like you mentioned above? They are all object exports as far as I see. Can we add a test for array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readme.md Outdated Show resolved Hide resolved
guybedford and others added 3 commits July 1, 2020 23:38
Copy link
Member

@styfle styfle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

@styfle styfle added the automerge Automatically merge PR once checks pass label Jul 4, 2020
@kodiakhq kodiakhq bot merged commit c0cfb7a into master Jul 4, 2020
@kodiakhq kodiakhq bot deleted the exports branch July 4, 2020 00:26
"test/unit/yarn-workspaces/input.js",
"test/unit/yarn-workspaces/node_modules/x",
"test/unit/yarn-workspaces/node_modules/x/package.json",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guybedford I think this file was incorrectly emitted since this line is a symlink pointing to the last line in the output here. See PR #135 for the fix.

styfle added a commit that referenced this pull request Jul 16, 2020
PR #129 emits `package.json` files but it should not be emit if package.json is inside a symlinked directory. This is a common pattern for yarn workspaces.

This PR fixes yarn workspaces and adds a new test for yarn workspaces using ESM imports/exports.

Co-authored-by: Guy Bedford <guybedford@gmail.com>
kodiakhq bot pushed a commit that referenced this pull request Nov 4, 2022
This PR fixes a bug where TS input was not considering ESM with `type:
module` in package.json

Related to #129 which added package.json emission but only for JS input.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge Automatically merge PR once checks pass
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants