DEV Community

jkorichneva
jkorichneva

Posted on

Migrating single-spa monorepo to Vite with minimal changes in PR

I have been with webpack for quite a long time, starting with version 3, then 4, and finally 5. It is familiar and incredibly customizable. Nevertheless, when you have to wait about 30 seconds to get your build done and then about 5 seconds for your changes to become interactive, love for webpack slowly vanishes.

Usually there are three ways to deal with this tiring waiting:

  1. Optimize webpack to make it faster (e.g. try lazy compilation)
  2. Reduce bundle size (webpack-bundle-analyzer is useful for this)
  3. Look for an alternative solution

While I tried the second option, it didn't fully solve the issue. Vite has long been on everybody’s lips, promising quick builds and almost instant HMR. I decided to experiment with our single-spa monorepo and see the results.

About migration
There are many migration guides available online, so I won't repeat them here,as they are easy to find. Generally, these are the steps to follow:

  1. Install the necessary packages.
  2. Introduce an index.html file in the root folder.
  3. Add the Vite config and customize it for your build.
  4. Change the commands to use Vite.

While going through these steps, I encountered following issues in adapting my configs of build into vite:

Env-variables
Vite requires all env variables to have the VITE_ prefix, but changing all references would have resulted in a large PR that would be difficult to review. I found a solution in vite-plugin-environment, which allowed me to keep all process.env references untouched

Absolute ts imports
Many of our imports, like lib/exampleHook, were broken after switching to Vite. The issue was resolved just by adding vite-tsconfig-paths and all started working.

License generation
Webpack creates license files out-of-the-box, while rollup that is inside vite, doesn’t. This can be fixed by rollup-plugin-license, it has a lot of customization, but in the end, I found the text files not so fancy as webpack. Maybe I just did not get it right.

Npm-package, that is not a module
We used single-spa-html module for displaying some static errors, that was not a module, but a IIFE inside. I had to fork it and to put it inside my repo, changing it into a module.

Single-spa complications
When developing locally, we loaded some scripts from test environment, that are transpiled into commonjs and that was a complication, as local modules should have been handled by vite, whereas those modules had to be registered via System Js. It lead to ugly if else that I won’t even add here.

Another issue was that we had a module, that was used by all others externally. And again, the modules from test env needed commonjs version of sdk, while local needed es6 version, which also lead to pre-building it and serving from dist. I tried various configs, but didn’t succeed — vite was unstable when loading it and that sometimes affected the performance of the whole application.

Results with vite actually working:

  • Local startup was about 30s, with vite about 3–4 seconds
  • CI build time decreased by 30 seconds
  • HMR was almost instant

Conclusion
Vite is great, it really is a silver bullet for apps that take a long time building. However, if you have already codebase with customizations, the migration can be painful. As vite was working unstable with our external module and this issue required a lot of investigation, we decided to postpone the migration for now. Hopefully, after some other refactoring, we will get back to it.

Top comments (2)

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Hey, I am planning to migrate from CRA to Vite, so in preparation, I have been studying and practicing with Svelte, Vite and single-spa. I came up with this Vite plug-in that can configure any Vite + XXX project to be used with single-spa. It is quite painless.

Collapse
 
jkorichneva profile image
jkorichneva

Hey, thanks! This looks very promising!
Will definitely try it out