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

[ENHANCEMENT] Publish package as standard JS modules #712

Open
1 task done
justinfagnani opened this issue May 8, 2024 · 13 comments
Open
1 task done

[ENHANCEMENT] Publish package as standard JS modules #712

justinfagnani opened this issue May 8, 2024 · 13 comments
Labels
Bug thing that needs fixing Needs Triage needs an initial review

Comments

@justinfagnani
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

This package is currently published as CommonJS modules only. This makes it impossible to use in browsers and other environments that don't support Common JS, without a build step.

Expected Behavior

This should just work with a suitable import map:

import semver from 'semver';

This could be done as part of a migration to standard JS modules only, or a dual-mode package, possibly as part of #498

Steps To Reproduce

  1. In a browser
  2. With dev server that can rewrite bare module specifiers to URLs (such as @web/dev-server with the --node-resolve flag)
  3. Load a module script with import semver from 'semver';
  4. See error...

Environment

  • npm:
  • Node:
  • OS:
  • platform: All browsers, Cloudflare Workers, more...
@justinfagnani justinfagnani added Bug thing that needs fixing Needs Triage needs an initial review labels May 8, 2024
@ljharb
Copy link
Contributor

ljharb commented May 8, 2024

I’d hope an ESM-only migration is out of the question, since that would make semver unusable for the vast majority of ecosystem users.

@SebastianBock83
Copy link

SebastianBock83 commented Jun 4, 2024

With version 5.0 the minified browser useable file was removed. That means 4.3.6 is the last version where the minified browser usable files are available.

4.3.6 and several other version until 7.5.2 have a known CVE issue inside.
https://nvd.nist.gov/vuln/detail/CVE-2022-25883

Is there any possibility that a new version of semver contain the minified browser version again or at least some kind of build script, to build the browser version again.

Best Regards,
Sebastian

@ljharb
Copy link
Contributor

ljharb commented Jun 4, 2024

@SebastianBock83 why can't you build it yourself, locally, to use in whatever format you need?

@SebastianBock83
Copy link

@SebastianBock83 why can't you build it yourself, locally, to use in whatever format you need?

The project where the lib is used is a quite "old" implementation without the usage of modules and any kind of build environment. Pure JavaScript and HTML with script tags.

Rework to a module / build version would of course be possible but would take time and ressources.
The question is just for decision making.

Or is there any easy way to build the minified browser useable file via a script / library?
If this is a general procedure and I am lacking of knowledge, sorry for the question.
In case this is not the right place for that question, is there any possibility of having a private discussion out of this issue?

Best Regards,
Sebastian

@ljharb
Copy link
Contributor

ljharb commented Jun 4, 2024

To clarify, I'm not asking why you don't convert to a modern workflow, I'm asking why you can't use node locally to make a dist file, and vendor that in your repo manually. In other words, yes, there's lots of easy ways to make a minified browser-usable file yourself, containing any number of npm packages. A package should never need to provide a pre-built file for you to use it in this way.

Feel free to find me on Twitter or Slack or Discord, or just look on StackOverflow, if you need more help with this.

@SebastianBock83
Copy link

Thanks for clarification. I will check on my own - just a lack of knowledge from my side. I will contact you if necessary.

Best Regards

@Hyperkid123
Copy link

Hello.

There are other questions, such as tree shaking. It can be challenging with commonjs modules and bundles like webpack or rollup. Having es module variant of the library (alongside others) will help with that.

I realize that would introduce additional dependencies in the form of some transpiler like babel which is always somewhat controversial. But now with native support of the es module in node.js or browsers, I'd seriously consider adding module output. Not just because tree shaking, but because of the environment in general.

@ljharb
Copy link
Contributor

ljharb commented Jun 6, 2024

@Hyperkid123 you don't need treeshaking if you deep import the files you need, and CJS is identically treeshakeable as ESM from a technical standpoint.

@Hyperkid123
Copy link

you don't need treeshaking if you deep import the files you need,

I am aware of that. I'll bet any amount of money that a lot of people do not.

and CJS is identically treeshakeable as ESM from a technical standpoint

Yes but in reality this does not happen. Specifically when bundlers/transpilers are used. And they are everywhere these days. I can provide a sample repo if necessary.

@ljharb
Copy link
Contributor

ljharb commented Jun 7, 2024

Then it sounds like the best solution is to remove the barrel file in a major, and force deep imports, rather than add a build process?

@SimonAlling
Copy link

Then it sounds like the best solution is to remove the barrel file in a major, and force deep imports, rather than add a build process?

That might very well be the case for the tree shaking problem mentioned by @Hyperkid123.

But it doesn't address the problem of being able to use this library in non-Node contexts (where require is not defined). I'm not saying it's easy to solve that problem — it definitely isn't — but I believe that's a perfectly reasonable use case that should be considered.

If it's not feasible to adapt the package, do you perhaps know of a workaround to be able to use it in an ESM context?

@ljharb
Copy link
Contributor

ljharb commented Jun 19, 2024

That use case has been addressed by bundlers for well over a decade (also, you can import CJS modules in node perfectly fine). If you're trying to use it in a browser ESM context (which is slower at runtime than bundling to Script, btw), or in something like Deno or Cloudflare Workers, then I believe you can use any of the bundlers out there to provide an ESM module for a package that isn't using node-specific capabilities.

@SimonAlling
Copy link

@ljharb: For reference, this was how I ran into the problem:

  1. Added semver as a dependency.
  2. Wrote the TypeScript code that used semver until it compiled and I was happy with it. If it compiles, it works, right? ¯\_(ツ)_/¯
  3. Ran my @web/test-runner-based test suite, which failed with ReferenceError: require is not defined.

I don't know if or how I can use a bundler to solve that. And it would have to be solved for when I build my package as well, not just for the test suite. And I would also need to know that it's acceptable for me to publish bundled code.

So it really would be super-nice if this package were available as ESM in addition to CJS. I'm painfully aware of how non-trivial it is to make that happen and the caveats entailed by it; I'm just saying it would be useful. 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Needs Triage needs an initial review
Projects
None yet
Development

No branches or pull requests

5 participants