Why I'm not switching to vite yet

Why I'm not switching to vite yet
Photo by Erik Mclean / Unsplash

Twisted paths

While searching for a markdown based Static-Site Generation (SSG) to build a documentation page I came across vuepress, first I started with vuepress 1 but since I wanted to install it in my existing project (which uses vue 3 and vuepress 1 does not support vue 3) I switched to the vuepress 2 beta which supports it.

Vuepress 2 is maintained in a seperate repository called vuepress-next. In order to make an educated guess about the longevity I checked the roadmap only to find out that the Vue.js Team is planning to replace VuePress with VitePress totally

This left me with two unsatisfying solutions:

  • Using vitepress from the beginning which is still in v1 alpha state
  • Using vuepress v2 beta even though it will be replaced at some point or become a community-maintained project

To further add to the confusion it seems like the vue.js team isn't even sure if vitepress beta/stable will become vuepress 3 or vitepress. So the current situation felt a bit like "everything is deprecated except our new super cool vitepress project which is still in the alpha stage and subject to change"

Why not use vite and webpack at the same time?

I like to keep things clean, mixing two different frontend bundling environments does not feel right.

In my vue projects I use webpacks require.context to load and register all vue components in a folder which makes life a lot easier. I also use this feature in my own vue component library which is included in my projects.

vite offers a similar solution using import.meta.glob but in this point vite and webpack are mutually exclusive

vite also favors to use ES modules, so import and export, no require and module.exports

Since there is only one package.json the nodejs server code also needs to run with type: "module"

I was used to prefixing node module dependencies with ~ but this is a webpack-only feature, vite does not resolve packages if they are prefixed with ~

I chose to give vite a chance because even laravel switched to it in the latest version and it looks promising. Sadly it was not as fun as I hoped for.

Dev vs prod

My current webpack setup of the example project I chose has a dev and a prod build, both bundle the assets into a output folder so that they can be served by a nodejs express server.

The express server uses express.static and for the index.html file I replace some things in the raw html string serverside before sending it to the client.

Vite does offer a production build command and a dev server but it does not offer a dev build that writes a dev bundle to the disk and does not plan to add it. There is a --mode option but it does not seem to change much (bundle is still minified, no sourcemap, ...)

The main problem I struggled with is that the vue application is build in production mode even with --mode development and NODE_ENV=development

This means no devtools and no runtime errors/warnings.

Devtools can be forced by defining a special __VUE constant but I did not find a way to build the vue app in dev mode.

The dev server

"Okay fine." I thought, let's use the vite dev server, it runs blazingly fast so it might be the better option right? – Kind of.

While it does build fast, enables vue dev mode and vue devtools it does not write files to the disk for the backend server to use and there is no option to activate it, the only and presumably preferred option is to integrate vite directly into the backend server.

This means the backend server will proxy requests to assets to the dev server and you have to include the vite dev client js but if it is running in production mode it will use the dist files from disk. – This feels very fishy and invasive.

An "if prod do this else do that" solution is always weird.

For a node express server there is a vite-express  package which tries to streamline the process, but it needs to be installed and be part of the server code even if the application is in production. It automatically launches the vite dev server internally, with a hardcoded host "localhost" which doesn't work in my local docker setup.

HMR

Hot module replacement is a feature that is also available in webpack and it can make sense in some situations but in all my projects I disabled it because it is unreliable and annoying.

Especially when using vue it can sometimes lead to very confusing reactivity states which takes up time that could be solved by simply doing a full, clean, refresh of the page.

Require context

As mentioned above I had to replace my require.context approach and use vite's import.meta.glob which should do the same, except it doesn't.

Somehow the components are resolved sometimes but sometimes not.

At this point I gave up.

Conclusion

Vite is modern and fast and at some point in the future it may become the go-to solution for frontend development and bundling but currently it is very annoying to setup and just doesn't feel right yet or requires accepting vite's opinionated approach.

Webpack on the other hand may be a bit slow but it is still widely spread with a lot of plugins, and most importantly: it works.

What would be possible is continuing to use webpack for my projects but use vitepress with vite for my documentation page as a completely independent project.