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

add support for esm named exports #325

Closed
wants to merge 2 commits into from
Closed

Conversation

MylesBorins
Copy link
Contributor

Through an ESM wrapper and package.exports this change allows the
semver module to be both imported and required while still supporting
legacy versions of Node.js. An important advantage to this change is that
semver will now support named imports, which are unsupported in commonjs
modules.

One thing to note. This change introduces the package.exports field
which locks down what modules can be deeply imported.

Currently support is maintained to allow deep imports of all files
currently included in package.files to keep the change Semver Minor.
In the future this interface could be further locked down.

esm-wrapper.mjs Outdated Show resolved Hide resolved
esm-wrapper.mjs Outdated Show resolved Hide resolved
esm-wrapper.mjs Outdated Show resolved Hide resolved
@MylesBorins
Copy link
Contributor Author

MylesBorins commented May 7, 2020 via email

Copy link
Contributor

@isaacs isaacs left a comment

Choose a reason for hiding this comment

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

This LGTM, assuming that it still has full coverage after making the requested modification to the tests.

package.json Outdated Show resolved Hide resolved
test/esm/test-default.mjs Outdated Show resolved Hide resolved
test/esm/test-default.mjs Outdated Show resolved Hide resolved
@isaacs
Copy link
Contributor

isaacs commented May 8, 2020

Just added a test for map.js, which wasn't getting tested right now.

Rebase this onto master, and let the test guide you, and all will be good :)

@coveralls
Copy link

coveralls commented May 8, 2020

Coverage Status

Coverage remained the same at 100.0% when pulling 8b3684d on MylesBorins:add-esm into e79ac3a on npm:master.

@MylesBorins
Copy link
Contributor Author

Updated based on all the feedback. Currently have the single test per file but this is now going to fail on all version of node lower than 14 out of the box (for now). Before I was using a proxy cjs module to sniff the semver and skip the esm test on node.js older than 14. How would you suggest to unbreak older versions without compromises the 1 test per file system?

@coreyfarrell
Copy link
Contributor

This LGTM, assuming that it still has full coverage after making the requested modification to the tests.

On it's own nyc will not produce coverage for ES modules loaded by node.js core. To get that you would need the experimental @istanbuljs/esm-loader-hook. I'm not sure getting coverage reported for the one statement in the esm wrapper is worth the trouble/risk of future breakage by using --experimental-loader.

@coreyfarrell
Copy link
Contributor

One more comment on ESM coverage, the experimental module I mentioned does not work with nyc 14 (used by the current version of tap). It's @isaacs call but I think not having automated coverage for the esm wrapper should be fine, being a single statement means that we can see that it's fully covered.

As for the issue with ignoring the test in node.js < 13 I think you could:

  • Add "test-ignore": "test/esm-wrapper.mjs" to package.json#tap
  • Add to test/index.js:
if (semver.gte(process.version, '14.0.0')) {
  t.spawn(process.execPath, require.resolve('./esm-wrapper.mjs'))
}

Personally I would lean towards renaming the esm-wrapper.mjs files to index.mjs. AFAIK the map.js settings are applied per test run directly by tap and not to tests run by t.spawn. Doesn't make a difference now but eventually we'll be able to get coverage. Since test/index.js will filter coverage to index.js and index.mjs, that same filter would be inherited in the t.spawn of test/index.mjs.

package.json Outdated
@@ -21,8 +21,8 @@
"./package": "./package.json"
},
"scripts": {
"test": "tap --no-esm",
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused, why did you remove the --no-esm?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the t.spawn shells out to node not tap so it doesn't end up using the built in runner (and esm). At least that is my understanding

Copy link
Contributor

Choose a reason for hiding this comment

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

It'd be better to put "tap": { "esm": false } in the package.json than have it hard-coded in the command, imo.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough. I was just seeing the esm module as unnecessary but I guess it's also not strictly required to disable it in this repository.

@isaacs
Copy link
Contributor

isaacs commented May 8, 2020

Yeah, missing coverage for a one-line file is not the end of the world, especially if we can be reasonably sure that it's working properly by some other means.

You can add the test file but include it in test-ignore like @coreyfarrell suggests, and then load it on versions that will do the right thing, that's fine. The nice/hazardous thing about a coverage-map is that if the test isn't run, it's as if its covered file just doesn't exist, so you still get 100%.

@MylesBorins
Copy link
Contributor Author

MylesBorins commented May 8, 2020 via email

@mbruning24
Copy link

Currently working on an upgrade to angular 10 for our application, and node-semver is a dependency we have, it's throwing a lot of errors not having named exports, seems like the PR is basically good to go, can we get a bump?

@basz
Copy link

basz commented Nov 14, 2020

Not sure this is related, but I'm seeing an error in production builds only.

"Error: Cannot find module './ranges/outside'"

When I compare the node_modules/semver/ranges directories it is indeed missing an outside.js file.

Any way around this?

v7.3.2

@basz
Copy link

basz commented Nov 14, 2020

nvm. It was an incorrect ignore in ember-electron, filtering all files staring with 'out'...

@cawa-93
Copy link

cawa-93 commented May 13, 2021

Is there any updates? It seems to me that this could help the packages above to get around the problem of cyclic dependencies.

MylesBorins and others added 2 commits May 13, 2021 09:37
Through an ESM wrapper and package.exports this change allows the
semver module to be both imported and required while still supporting
legacy versions of Node.js. An important advantage to this change is that
semver will now support named imports, which are unsupported in commonjs
modules.

One thing to note. This change introduces the package.exports field
which locks down what modules can be deeply imported.

Currently support is maintained to allow deep imports of all files
currently included in package.files to keep the change Semver Minor.
In the future this interface could be further locked down.
@MylesBorins
Copy link
Contributor Author

Closing in lieu of #383

@MylesBorins MylesBorins closed this Oct 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

https://semver.org/.v2.0.0 require('semver')
8 participants