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

Decide how to publish CJS bundles #1

Open
43081j opened this issue Feb 13, 2024 · 15 comments
Open

Decide how to publish CJS bundles #1

43081j opened this issue Feb 13, 2024 · 15 comments

Comments

@43081j
Copy link
Contributor

43081j commented Feb 13, 2024

We need to decide how best to create these bundles.

Basically, the current PoC script in the repo does the following (roughly):

  • Create a new package
  • Install the target ESM package as a dependency
  • Create a bundle which exports everything from the ESM package's bare specifier
  • Copy important package.json fields from the dependency to the new package
  • Publish the new package

This is easier than forking every repo and doing the CJS build in each individual repo (since we can just run this script with a target module).

However, things where it starts getting sketchy:

  • How to copy types across? (there may be a types, or exports may have types, and those types may import types themselves)
  • How to deal with exports? (we don't really care about supporting anything other than the bare specifier at least)

Alternatively, we could just fork each individual package and manually setup a commonjs bundle build, change the name, etc.

To summarise:

  • Option 1 - download the target package, bundle it, imitate the package.json
  • Option 2 - fork the target repo, actually add a CJS build script, publish however the target repo publishes

maybe cc @thepassle in case you have any thoughts

@43081j 43081j changed the title Publish script Decide how to publish CJS bundles Feb 13, 2024
@JounQin
Copy link

JounQin commented Feb 22, 2024

Is this on schedule? I want to bundle import-meta-resolve and publish as cjs to use in stylelint/stylelint#7532, I may have to do it manually?

@43081j
Copy link
Contributor Author

43081j commented Feb 22, 2024

any help would be much appreciated, especially in technical discussion here

basically im trying to decide between these two options:

  • write a script which bundles the target package as CJS and do best effort to copy any shipped types etc across
  • just fork the repo, automatically catch it up from the source repo but use esbuild to turn it into cjs

to be honest, there's enough edge cases im leaning more towards just forking the target repos for now at least

ill have a look this weekend at just forking chai as an example, and having it auto-catch up somehow

@JounQin
Copy link

JounQin commented Feb 22, 2024

I would recommend to only bundle and publish first, it would be good enough for most cases.

@43081j
Copy link
Contributor Author

43081j commented Feb 22, 2024

the difficulty is mapping across various package manifest things.

for example, type definitions in particular are tough.

if a package ships its own types, we would need a reliable way to bundle all the exported types into a single dts file. or follow the tree and copy across all referenced dts files (from the entrypoint)

@JounQin
Copy link

JounQin commented Feb 22, 2024

I was saying that we should not consider type definitions at the first time. We can't finish all tasks at once, and single entry without types should be good enough for most cases already.

The future is ESM, @cjs-bundle should not aim at targeting all things IMO, this should only be temporary solution between migration.

I changed to use vendor solution at stylelint/stylelint#7535

@43081j
Copy link
Contributor Author

43081j commented Feb 22, 2024

i do agree it should be a temporary fix, and people should be urged to migrate to esm sooner rather than later

i think its important we don't break typescript support though, but do understand it may not be worth the time if it blocks us

ill have another look at the script we already have in this repo this weekend 👍

@JounQin
Copy link

JounQin commented Feb 22, 2024

My two cents, for a pure ESM package, we should transform it as dual instead of commonjs only, so that the ESM entry will still be preferred.

So, my solution would be, download the pure ESM npm package, bundle the ESM entry as commonjs, add it into exports field and then publish it. And then import and types will still be available.

So maybe @dual-bundle is a better name/solution.

@43081j
Copy link
Contributor Author

43081j commented Feb 23, 2024

the reason i disagree with that is that it reduces the motivation/need to still move to ESM

we're leaning into maintaining the source package as well as the CJS bundle of it then, too. so it becomes a larger burden on us

i think we should keep it simple. since we already had an esm-bundle in the wild for years now, a cjs-bundle seems to make sense and isn't quite permanent enough for people to give up on moving to ESM

@JounQin
Copy link

JounQin commented Feb 23, 2024

Hmmm... Then what's the purpose of cjs-bundle? It will definitely reduce the motivation/need to still move to ESM already?

@43081j
Copy link
Contributor Author

43081j commented Feb 27, 2024

the purpose is to provide a CJS bundle of packages which have since moved to pure ESM

importantly, as a temporary solution to consumers who just didn't have the time yet to move to ESM themselves

if we provide dual packages, it will mostly just result in consumers sticking to these bundles indefinitely as there's little motivation to move back to the source package. if we only provide CJS, any ESM migrations will also mean moving away from this project (a good thing).

@43081j
Copy link
Contributor Author

43081j commented Feb 27, 2024

ok, temporarily at least, im going to manually fork some repos for now so i can get them published.

however, i'd still like to solve scripting this rather than maintaining a fork if possible.

the types are important since many consumers use TS these days and the build will immediately fail when using the CJS bundle unless we solve this (as the types will be missing). that isn't an easy problem to solve since types can reference other DTS files.

@JounQin
Copy link

JounQin commented Feb 28, 2024

@43081j The issue of commonjs only solution is: if I want to support commonjs + ESM at the same time, I can only use commonjs version via your fork then?

@JounQin
Copy link

JounQin commented Feb 28, 2024

the types are important since many consumers use TS these days and the build will immediately fail when using the CJS bundle unless we solve this (as the types will be missing). that isn't an easy problem to solve since types can reference other DTS files.

In my solution with dual package, although the types are only for ESM, but it should be compatible with commonjs at the same time for most cases, and I believe:

So, my solution would be, download the pure ESM npm package, bundle the ESM entry as commonjs, add it into exports field and then publish it. And then import and types will still be available.

The above solution is much easier to maintain.

@43081j
Copy link
Contributor Author

43081j commented Feb 28, 2024

@43081j The issue of commonjs only solution is: if I want to support commonjs + ESM at the same time, I can only use commonjs version via your fork then?

yes exactly.

we've had esm-bundle for some time to provide ESM-only bundles of CJS-only projects. now this is providing the opposite since many projects are ESM-only but consumers still sit on CJS-only stacks.

providing a dual package is more of a permanent solution, pulling people away from the source package. whereas this is meant to be a very temporary solution while people move to ESM.

ESM users should use the source package. CJS users should temporarily use the cjs-bundle package. Why would we want to provide ESM users with our own ESM bundle when the source package does that itself?

@JounQin
Copy link

JounQin commented Feb 28, 2024

See stylelint/stylelint#7532

stylelint itself is a dual package, so it cant use pure ESM import-meta-resolve, and don't want commonjs only bundle, so I just published @dual-bundle/import-meta-resolve at https://github.com/un-es/import-meta-resolve

When stylelint migrates to pure ESM only in the next major version, it will change to use the original import-meta-resolve instead.

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

No branches or pull requests

2 participants