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

RFC 2.0: Consider using esbuild and Ava instead of Vite #6716

Open
KeyboardSounds opened this issue Jan 9, 2024 · 7 comments
Open

RFC 2.0: Consider using esbuild and Ava instead of Vite #6716

KeyboardSounds opened this issue Jan 9, 2024 · 7 comments

Comments

@KeyboardSounds
Copy link
Contributor

KeyboardSounds commented Jan 9, 2024

Topic

Proposal: Use esbuild instead of Vite, which provides a similarly good developer experience with less complexity, fewer extraneous features that we won't use, and no need to add Rollup as an extra dependency.

More detail

Do we need Vite's extensive featureset? Is using something more minimal going to cause fewer issues and still meet p5.js's needs? Let's discuss whether we should use esbuild instead.

At the time of writing, the RFC 2.0 proposal suggests using Vite and Vitetest for building and testing p5.js. (at the Vite is a comprehensive tool that provides an excellent developer experience out of the box. However, that comprehensiveness leads to complexity that can make it harder to fix when something breaks. The horrors of fixing broken Webpack setups comes to mind, although Vite seems significantly more stable.

An alternative to Vite is esbuild. It sets out to do the bare minimum to build a project, while retaining flexibility to accomodate many workflows. The developer experience is slightly less smooth — there's no Hot Module Refreshing (HMR), for example — but it compensates for these by being extremely fast. If rebuilding is almost instant, does HMR matter? While there are Rollup plugins available, having multiple build inputs and outputs is well-supported without them.

If we choose to use esbuild instead, it doesn't make sense to use Vitest, and so we'll need another test runner. Ava looks good, but there are many other options.

Comparison

Some criteria for choosing a build and test system:

  • Speed
  • Easy to configure
  • Easy to understand
  • Easy to fix
  • Introduce as few new dependencies as possible
  • The ability to rerun only the tests that recently failed or have changed

Vite and Vitest

Pros:

  • Large and rapidly growing community
    • Well supported, easier to find solutions to problems
    • Developers coming from other projects are more likely to be familiar with Vite
  • Fast loading of code changes [https://vitejs.dev/guide/features.html#hot-module-replacement]
  • Test runner that is developed as part of the same project and designed to work with Vite means that build and test processes are easier to integrate
  • Lots of features such as Static Asset Handling, dependency pre-bundling

Cons:

  • Complexity - even though Vite is relatively easy to configure, it does a lot behind the scenes, which can make it harder to troubleshoot problems than more minimal tools. Even though build problems are relatively rare, they can be nightmarish to debug.

esbuild

Pros:

  • Very, very fast. Possibly the fastest available build tool?
  • Flexible enough that we might not need to use Rollup as well
  • Watch mode - because esbuild is so fast, watch mode is also fast even without HMR
  • Well supported — most projects don't use esbuild directly, but most modern build tools use it internally (including Vite)

Cons:

  • No HMR
  • No integrated test runner

ava

Pros:

  • Watch mode automatically only reruns the tests that have been changed
  • Magic assert makes it easier to see why tests are failing

Cons:

  • Less popular than Vitetest, so there's a greater risk of it becoming unmaintained - but it's been around for 10 years, and the repo shows a healthy amount of activity
  • No HMR, so responding to code changes will be slower than Vitest (although probably not by much)
@KeyboardSounds
Copy link
Contributor Author

PS: If the consensus is "shrug, the difference between the two is splitting hairs", then we should use Vite just because it's more widely used.

@limzykenneth
Copy link
Member

As you noted, Vite is using ESBuild behind the scenes and to be precise, it is using ESBuild when running watch mode and in practice it makes the speed difference between Vite and ESBuild negliable in watch mode. In the case of p5.js there are also not very much that needs to be transpiled in watch mode (no use of typescript and, for now, no plan for complex transpilation for 2.0) so speed will likely not be a problem.

For build, Vite uses Rollup underneath but it lacks certain flexibility which is why the current proposal is to use Rollup directly instead. It might also be worth looking at the reasoning Vite does not use ESBuild for bundling as well. Vite itself also have plans to create a Rollup compatible tool for bundling that will repalce Rollup, which will be written in Rust that will give very good bundling performance as well, so I anticipate things may further speed up in the near future as well.

I have not tried ESBuild for this part mainly because Rollup/Vite seems to have a larger momentum currently and I want to future proof this build as much as possible (assuming if such a thing is even realistic). I would welcome some tests being done to see how ESBuild performs. The current build with Rollup that generates both unminified and minified builds takes about 5-7 seconds.

The reason Vite is included instead of just Rollup, is that for development, Vite can greatly help with the preview process by providing an index.html file that we can author test sketch in. This streamlines the process of making changes, building a version of the library, copy the built file to a sketch folder, run a local server on the sketch folder, and repeat.


The reason Vitest is chosen as a test runner is mainly because Vite is included so there are relatively less moving parts since the transpilation will be handled by Vite the same as under watch mode. Vitest also has a Jest like/compatible syntax which can improve overall experience. Ava I think has their own test syntax.

Vitest also supports running test in browsers, which we need for p5.js, out of the box. I'm not sure how well Ava support this if at all. Although again, test implementation for investigation are definitely welcomed, you can use the development branch as a starting point if necessary.

@asukaminato0721
Copy link
Contributor

there is another build tool similar to esbuild called https://github.com/swc-project/swc

@limzykenneth
Copy link
Member

@asukaminato0721 SWC is a great project as well, however it is not quite a complete build tool. It is more similar to Babel, ie. a code transpiler and it does not do bundling. It is possible to configure Rollup to use SWC for transpiling as well and if we need transpiling that would be my preference. From testing though I don't see significant difference at this stage.

@asukaminato0721
Copy link
Contributor

ok, seems that bundling function is not so well. https://swc.rs/docs/usage/bundling

still under construction

@mattdesl
Copy link
Contributor

I like both vite and esbuild, but I worry vite will at some point become the next webpack in terms of configuration complexity, and IMHO it is better suited as a frontend development tool (for things like CSS, assets) rather than a library authoring tool. However, if p5 v2 ends up requiring a lot of web assets (like SVG loaders, CSS files, WASM, worker scripts, etc) that is where Vite might be a superior choice.

In an ideal world, the bundler would be rather agnostic and not too tightly coupled with the whole project, so that we could imagine a future where 5 years from now moving from one bundler to another wouldn't be too cumbersome. I worry this would not be the case with vite/vitest—just as it has been painful for webpack projects to migrate away—whereas if using esbuild + TAP or another test framework, I feel it would be relatively easy to change to another tool like swc/rollup/bun whatever. I could be wrong, though.

@limzykenneth
Copy link
Member

@mattdesl Thanks for chiming in. A few things I think got a bit confused here.

The main build tool that is currently proposed to be used to build p5.js 2.0 is Rollup and not Vite, as you mentioned Vite is better suited for frontend development specifically developing web apps. Vite is only used for that purpose in p5.js 2.0 with an index.html file to enable quick development feedback locally (do checkout the dev-2.0 branch where much of this are worked out in proof of concept).


In my opinion, Vite is not at risk of becoming Webpack. Webpack is difficult to transition out of mainly because of when it was created and the JS landscape around then, ES modules doesn't quite exist at that time and CommonJS being the way node.js does modules means that bundlers at that point in time pretty much default to CommonJS. The behavior of CommonJS vs ES modules are different in some key ways, making projects that heavily invested into CommonJS hard to transition out of it.

Vite is not likely to become Webpack because 1. it uses esbuild and Rollup under the hood with many Rollup configurations directly usable with Vite if necessary; 2. because Vite is using esbuild/Rollup, it is using ES modules which is the main thing that will enable easy transition to another tool if necessary as long as it supports ES modules (Rollup/esbuild/Parcel/Bun/Rolldown/not bundling at all/whatever comes up few years down the line).

It also doesn't matter that much that p5.js 2.0 is using Rollup, again because of ES module and ES module centric toolings (eg. I might switch to Rolldown once it stabalizes and there should be no need for any code change).


Vitest uses Vite underneath (which uses esbuild/Rollup underneath) and is so far giving very good result in that there is no need for a build/transpile step to run any tests, tests runs in the same environment as I would be using for local development. The whole flow is more intuitive and it is also a very straightforward transition from Mocha, Chai assertions are already built in too + I can remove additional dependency on Sinon for mocks and spies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Out of Scope
Development

No branches or pull requests

5 participants