Skip to content

Improve ESM package entrypoints #1597

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

drwpow
Copy link

@drwpow drwpow commented May 30, 2025

Changes

The packages’ entrypoints could be improved. Specifically:

  • top-level module is not a valid entrypoint (and has never been—it’s simply been “allowed” but never been officially a standard). It’s now-replaced with exports
  • The official Node.js-supported ESM entrypoint is "import", not "module" (docs) (however, just to not break anything, "module" was left alone)
  • "./*": "./*" was added to preserve backwards-compatible behavior. Whenever "exports" is specified, all imports are forbidden by default, and this explicitly re-allows manual importing.
  • "main" was also left alone to preserve backwards-compatible support for … well, everything should be listening to exports now, but y’never know

All this will result in free, improved backwards-compatible ESM support for all packages. This shouldn’t cause any breaking changes for anyone, only improve bundler compatibility today and for the future.

Note: I was originally starting on #1588, but got distracted when I noticed the package ESM entrypoints needed updating

Feedback

  • Tests should pass, obviously
  • This shouldn‘t result in any breaking changes for everyone, however, please request changes if anything feels “off”!

Copy link

changeset-bot bot commented May 30, 2025

🦋 Changeset detected

Latest commit: b9fbff2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 16 packages
Name Type
@vanilla-extract/babel-plugin-debug-ids Patch
@vanilla-extract/parcel-transformer Patch
@vanilla-extract/esbuild-plugin Patch
@vanilla-extract/jest-transform Patch
@vanilla-extract/webpack-plugin Patch
@vanilla-extract/rollup-plugin Patch
@vanilla-extract/next-plugin Patch
@vanilla-extract/vite-plugin Patch
@vanilla-extract/sprinkles Patch
@vanilla-extract/compiler Patch
@vanilla-extract/dynamic Patch
@vanilla-extract/private Patch
@vanilla-extract/recipes Patch
@vanilla-extract/css-utils Patch
@vanilla-extract/css Patch
@vanilla-extract/integration Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@@ -10,9 +10,11 @@
"./package.json": "./package.json",
".": {
"browser": {
"import": "./dist/vanilla-extract-css-adapter.browser.esm.js",
"module": "./dist/vanilla-extract-css-adapter.browser.esm.js",
Copy link
Author

Choose a reason for hiding this comment

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

Where package entrypoints were already specified, they were left alone, "import" was merely added to ensure ESM gets picked up

Copy link
Author

@drwpow drwpow May 30, 2025

Choose a reason for hiding this comment

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

IMO "module" should just be removed—it’s usually ignored—but I’d wait for a breaking version in the future to remove it. There’s no harm to keeping it around short-term

"import": "./dist/vanilla-extract-compiler.cjs.js",
"default": "./dist/vanilla-extract-compiler.esm.js"
},
"./*": "./*"
Copy link
Author

@drwpow drwpow May 30, 2025

Choose a reason for hiding this comment

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

For net-new exports, it prevents importing anything other than the default. "./*": "./*" allows everything to be imported, which preserves backwards-compatible behavior for everyone (i.e. this only guides the default ESM import to the correct location, without disrupting anything else)

@drwpow drwpow force-pushed the pkg-exports branch 2 times, most recently from 7dc7119 to 4a0ff4d Compare May 30, 2025 05:41
@askoufis
Copy link
Contributor

@drwpow Updating entrypoints has been on my TODO list for a while, but I never got around to doing it I didn't want the update to result in a breaking change (without code changes to go with it). Thanks for getting the ball rolling.

The package exports are primarily handled by preconstruct, though there has been some manual changes made here and there. I have been trying out tsdown, which can also manage package exports, which I'd prefer over manual changes.

I'm honestly not too fussed about maintaining backwards compatibility as far as importing from ./* goes, as well as node16 compatible entrypoints, so if it's possible to just remove the ./* exports without causing a breaking change (for anyone on Node LTS), that would be great.

@drwpow
Copy link
Author

drwpow commented May 30, 2025

The package exports are primarily handled by preconstruct, though there has been some manual changes made here and there. I have been trying out tsdown, which can also manage package exports, which I'd prefer over manual changes.

Dunno if you’ve checked out unbuild, but it’s hands-down my favorite packager at the moment. The thing I love about it explicitly is it uses package.json exports as your entrypoints, i.e. as it builds, it actually checks to make sure you’re shipping the right thing (and will raise warnings or errors if not!). Also its ESM <> CJS support is great, too.

I’ll have to check out tsdown. I’m a big fan of how Rolldown is shaping up, but I know it still has a few papercuts. And I’ve had issues with tsup (around entrypoints, funny enough), so not sure if tsdown fixes them, but that’d be great if it did. Very excited about anything built on Rolldown in general

The package exports are primarily handled by preconstruct

Yeah I might have missed something here in regards to autogenerating—if there’s deeper work here then feel free to close! This could just be used as a suggestion for later, that’s fine.

I'm honestly not too fussed about maintaining backwards compatibility as far as importing from ./* goes, as well as node16 compatible entrypoints, so if it's possible to just remove the ./* exports without causing a breaking change (for anyone on Node LTS), that would be great.

That’s good to know. For the most part, yeah, most folks won’t notice. The only thing I wasn’t sure about was the fact that some libraries seemed to have a .dev.cjs.js output. That would be unavailable for import without the ./* glob (unless we manually added an entry for that, too). But yeah if there aren’t any other files that folks may be importing, we could drop it (If we do, I like to add ./package.json as an export, just because that’s handy to import in a lot of scenarios).

@askoufis
Copy link
Contributor

askoufis commented Jun 2, 2025

Dunno if you’ve checked out unbuild.

I have. I do enjoy the package.json exports-first approach to managing entrypoints. I'll consider it when I get around to migrating off preconstruct.

Yeah I might have missed something here in regards to autogenerating—if there’s deeper work here then feel free to close!

I should've clarified. I think they were auto-generated a while ago, but have had some manual tweaks since then, but are mostly stock (I think). Happy with this PR doing some more manual tweaks, but ideally we'd move to a tool that's more hands-off.

The only thing I wasn’t sure about was the fact that some libraries seemed to have a .dev.cjs.js output. That would be unavailable for import without the ./* glob (unless we manually added an entry for that, too).

I'm not that concerned about the .dev.cjs.js entrypoints. They'll go away with other tooling anyway. Vanilla Extract doesn't contain any dev/prod environment-specific code as far as I know.

I like to add ./package.json as an export

That would be great too. I've gotten into the habit of doing this in other libraries too, so it would be much appreciated.

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.

2 participants