-
-
Notifications
You must be signed in to change notification settings - Fork 958
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
[WIP] chore: use NodeNext
module resolution and use tsc
for builds
#250
Conversation
|
@fubhy is attempting to deploy a commit to the wagmi Team on Vercel. A member of the Team first needs to authorize it. |
To also show what I meant about code navigation and source map publish I added another commit that publishes the source code and source maps & declaration maps too. This allows library consumers to navigate to the original source code from the type declarations (d.ts) files. I find that immensely helpful when working with libraries like these. |
Thanks for the PR! Love the super pragmatic approach, and agree that developing in an environment similar to the consumer's environment would be nice. Haven't had much time yet to dig closer into this, but from a high-level, I have a few questions (I am not too familiar with
Agree that declaration maps will definitely be a nice addition, but I don't think |
@jxom Excellent questions! And I love that you are concerned about tree-shakability! A lot of libraries simply don't care or make subtle mistakes that are hard to fix later without introducing breaking changes (reorganizing exports, removing side effects, etc.). A lot of documentation out there is super outdated, confusing or outright wrong though so I can't blame anyone. To your questions:
Tree shaking is the job of the bundler used by the consuming application. The only thing we have to do here is:
Yep,
Viem is currently free of side-effects. At least I didn't see anything yet that would suggest otherwise. Yai!
You are already doing this. Yai! https://github.com/wagmi-dev/viem/blob/main/package.json#L122
This might be obvious but I'm pointing this out because in your questions you referred to "bundling" several times and I wasn't sure whether you used it colloquially or not. So apologies if I'm stating the obvious here: You do not want to bundle your library code (webpack, parcel, etc.)! We just want to transpile / compile it from typescript to javascript (CJS or ESM). Whether you do that with There are exceptions of course. For instance, if you wanted to provide a plug & play UMD bundle, which can be handy in some situations. I would suggest to also test for that within the examples packages: set up vite, turbopack, esbuild, swc, etc. examples and see how well they deal with eliminating dead code from their imports. Not sure how to best go about that... We could dump the output of TL;DR: bundling is the job of the consuming application. Imho, your best option for publishing both your js modules & types (and maps) is I went around shopping for solid blog posts that further discuss this whilst sticking to the point. I think this one does a good job at that without going too much into the weeds: https://blog.theodo.com/2021/04/library-tree-shaking/
I think I answered that in the previous answer: As long as we cleverly set up our barrel exports (btw. I would advise to not use imports from barrel files within the library itself, it has bitten me before), and don't break tree shakability by (incorrectly) bundling our ESM exports, we should get the ideal result for downstream applications to optimize their bundle sizes.
There's no denying that
Requiring the I agree that it looks a bit odd at first after years and years of not using any file extension in your imports in js & ts land ... Takes a bit of time to get used to it. But IDEs already widely support it and I haven't had any issues with it so far. I haven't experimented with the upcoming |
Btw. for full transparency regarding my stance on publishing source maps & declaration maps... It is controversial and it's matter of taste. I'm personally leaning pretty strongly towards publishing source code & source maps & declaration maps together with the package. You've got two options:
There's not really a middleground because publishing source maps without source code basically leaves you with references to files (in your sourcemaps) that aren't included in your package. That has the potential to trip up tooling that tries to parse your source maps (e.g. for stack traces, etc.) and can potentially break things. So here are the benefits & downsides of publishing all of this with the package (my recommendation): Benefits
Downsides
For a plain typescript library, the increase in package size isn't significant enough, imho, to really argue against doing this. If your src directory had any large binary (or other) files in it (e.g. images, etc.), I'd simply exclude those from being published. Related discussion: googleapis/google-cloud-node#2867 |
Btw. is there a discord server that you guys hang out in? |
Sorry, excuse my language of using the term “bundling”! I definitely meant “compiling” (I was writing that response half awake 😜). Also definitely want to move away from the index/barrel imports from within viem itself as you said — we just recently discovered this has some nuances with tree-shaking (for example, importing a simple util pulls in 10kB gzipped or something when it should be much lower depending on the util). Open to adapting to the Definitely down to publish declaration maps as well, no brainer in terms of DX of digging into viem source code as a consumer. |
Superceded by #265 . Will come back to |
Fixes #244
NOTE: For now, this is just meant to help illustrate what I'd suggest for the build setup and type config. Feel free to reject this if you'd rather stick with
tsup
. There are some other tsconfig options (seetsconfig.base.json
) that I'd suggest to enable too if you decide to roll with this (some of them currently fail if enabled, would require a bit of refactoring).ALSO: This is still a work in progress of course. I've also removed the
import from package.json
to load the version to keep and force/restrict the build root tosrc
. This means we'd now need a small script orprebuild
command to copy & replace the version insrc/errors/version.ts
.Happy to discuss and continue this further if you want to explore this more.