So, a few months later I was ready to give this another shot, and I decided to try working on the Redux Thunk library first because it's really small. But it was still being built with Babel and Rollup, and I wanted to switch over to using ESBuild, so I found a really nice wrapper called TsUp. And I was able to get that set up pretty quickly, and it works pretty well. It's a wrapper around ESBuild aimed at TypeScript libraries. It also has the ability to generate a bundled ts TypeDefs file for you. So I ended up with this package, and it's better, although it probably still needs a bit of work from there.
Now, I mentioned earlier that we shipped ES modules, CommonJS and UMD file formats. What's a UMD file? Universal Module Definition is a really bizarre module format that can simultaneously be used as an AMD file, a CommonJS file, or a global script tag. And it's not that much more effort to maintain, but it felt legacy, and I didn't know if we should keep it. So I looked around, kept asking for advice. And the best advice I could find was a couple people saying, eh, you probably don't need it anymore. Even for something like CodePen, it has support for ES modules these days, you probably don't need it. So I made the decision to drop UMD files from our packages, although I did replace that with a special ESM build that's been pre-compiled to production mode, so it ought to work okay in browsers.
Then I found out that Webpack 4 didn't like the setup, because number one, it doesn't support the exports field, it also doesn't support parsing ES 2018 objects with spread syntax, or optional chaining syntax. And for that matter, you can't have a .mjs file in the main field, it'll choke on that too, so you have to switch to a .js extension just for that. And the problem is that Webpack 4 is still pretty widely used by a number of older build setups. So in order to try to keep from breaking the ecosystem, I reluctantly decided that I'm going to ship an additional build artifact, ESM format, but compiled to ES 2017 in a .js extension, just to keep Webpack 4 happy.
What about typedefs? Well, the version of tsup that I was using at the time will generate a bundled typedef file, but it always gives it a .d.ts extension. And this is a problem, because it turns out that, are the types wrong, reports that as a false CJS warning when you're using Module Resolution Node 16. And talking to Andrew Branch, it turns out that you really should have separate files with actually a .d.mts and a .d.cts extension, so that TypeScript fully knows here's what the types look like when you're running in ESM mode versus common JS mode, because there can actually be some differences. I decided to punt on solving that problem for now. It's still a thing I need to go back and look into. Andrew Branch did go and file a PR for .tsup, so that it will try to generate different bundled TypeScript definition files. That came out in a later version of .tsup, and I still need to try that out myself.
So, here's what some of the packages look like after the second attempt, and this is better, I think, but it probably still needs a couple more tweaks. I probably need to do some nesting for the import and default conditions to specify different type definition files for each of those. Now, Michel Westray, author of the Imer library, had been working on developing Imer-10 during the spring, and he was also trying to modernize that package and dropping some backwards compatibility stuff, and Redux Toolkit relies heavily on Imer. So, I was very eager to try out Imer-10 Beta, but I noticed that the bundle size actually went up a little bit. That seemed weird. So, I actually pulled down, cloned Imer-Repo, pulled down the Beta branch, and was looking at it, and I found that it was using an older build tool called TSDX, and it was still generating a lot of ES5 build syntax and a lot of weird cruft in there.
Comments