feat: switch to vite & tsdown for bundling
Summary
This PR introduces a modernized build setup by switching to Vite and tsdown, as discussed in #2742. The change significantly improves developer experience and build performance, while paving the way for better TypeScript tooling and future consolidation.
Highlights
- Build time reduced from ~60 s to ~5 s (with potential to reach ~1 s using Rolldown).
- Simplified setup — removes a large amount of build boilerplate.
- Vite-powered bundler provides modern, fast dev and production workflows.
- Legacy build systems (gulp, babel, webpack) are still retained temporarily for side-by-side comparison.
Next Steps
- Gradually remove old tooling once parity is confirmed.
- Migrate tests to Vitest for a unified Vite-based toolchain.
Thanks for starting this initiative!
- Great idea to replace Webpack with something faster! 🚀
- I noticed that the browser bundle is bigger than the current bundle. Maybe related to what polyfills are included. I guess we can configure that similar to the current bundle.
- Renaming files to
.cjsand.mjswould be a breaking change. I'm fine with the change if there is an important reason for it. In that case we can best do that change in a separate PR and schedule that for the first next major version. - I would love to migrate the tests to Vitest. It would be quite some work though, and we have to see if it is worth the effort. And I think best to address that in a separate PR too.
- Can your remove the Yarn files and changes from the PR?
Hi Jos, yes we are on the same page here.
- Great idea to replace Webpack with something faster! 🚀
so if you are happy I will proceed and remove webpack and gulp altogether.
- I noticed that the browser bundle is bigger than the current bundle. Maybe related to what polyfills are included. I guess we can configure that similar to the current bundle.
I didn't want to break anything, so went with more compatible version first, which is understandably bit bigger. The good thing this can be easily configured from tsdown.config.js. Another benefit is that now we can completely remove all the babel stuff.
- Renaming files to
.cjsand.mjswould be a breaking change. I'm fine with the change if there is an important reason for it. In that case we can best do that change in a separate PR and schedule that for the first next major version.
This is tsdown default, behavior and in line with latest node conventions, but for sake of minimising api changes we can configure it to produce js files. As for major version change, let's try to get this in current version with backward support and then once we complete TS migration we will include all the breaking changes there. For now the compatibility is priority, then in next major we can take advantage of this new bundler to do proper optimisation
- I would love to migrate the tests to Vitest. It would be quite some work though, and we have to see if it is worth the effort. And I think best to address that in a separate PR too.
I had a look at that as well. You are right it can be done in a separate PR.
- Can your remove the Yarn files and changes from the PR?
Do you mean pnpm? yes, will update with npm version. For some reason, i thought this library was using pnpm.
I noticed that the browser bundle is bigger than the current bundle. Maybe related to what polyfills are included. I guess we can configure that similar to the current bundle.
here is the main config we use (similar for cjs)
{
entry: ['src/**/*.js', 'src/**/*.mjs', 'src/**/*.cjs'],
format: "esm",
name: "esm",
platform: "node",
target: 'es2019',
outDir: "lib/esm",
unbundle: true
},
We can change target (see here) and other parameters to make good defaults. I currently set it es2019
Sounds good, thanks! Let's take one step at a time and try to keep things backward compatible :)
Yeah sorry I meant pnpm.
bundling & test harness are really @josdejong's province, not anything I particularly know about, so I will leave those topics to you two to make sure that the resulting library works as well and is not too much bigger anyway and is just as thoroughly tested. On file names, I would definitely prefer not to have to rename all of the source files we work with directly, but don't much care about file names of auto-generated files.
Finally on the idea of migrating all of mathjs's internal code to typescript: a long series of proof of concept efforts have made me, and I think Jos, skeptical of that as the best strategy for handling mathjs' very flexible runtime handling of arguments of different types. I think our goal ultimately is to have the implementations of individual operations be in TypeScript, and of course the resulting bundle have an airtight automatically-generated .d.ts file, but we expect that some portions of the internal engine will remain JavaScript as the turn out to be extremely difficult to coax TypeScript into typing properly.