I literally just spent days trying out Vite and comparing it to Webpack 5, and I can comfortably say that they are in two very distinct leagues. It isn't fair to compare Vite to a CRA build with Webpack. You can greatly improve Webpack's performance by:
* Making sure `mode` is set to "development" (don't specify it all if in doubt)
* Ditching babel-loader and using esbuild-loader instead
* Adjusting build targets and making sure polyfills are not added in development
* Making sure you don't import the entirety of libraries like Lodash and MomentJS (prefer date-fns)
* [FUTURE] We'll soon be able to tell Webpack to output ES modules just like Vite [1]
Vite still has many problems:
* It just isn't suitable for proper server-side rendering, we'd need access to chunk names at build time
* It has a weird mix of own and Rollup config settings that seems somewhat unpredictable
* Many open issues regarding module imports, for ex, when a CJS module imports an ES one [2]
Our current bottleneck with Webpack is actually sass-loader, taking at least 70% of the time during a fresh build, and we'd have the same problem with Vite.
Something else that is worth pointing out is the ecosystem: Webpack's community has built tons of plugins for basically any use case you can imagine, and version 5 supports module federation, persistent caching, externals (very handy when doing SSR), customizable filename generators, performance hints, etc etc. Totally different game.
Try to keep your build config simple, avoid too many loaders, plugins, and you should be fine 99% of the time. If you hit a wall, install speed-measure-webpack-plugin to get some help.
>* It has a weird mix of own and Rollup config settings that seems somewhat unpredictable
Oh god, this is a giant red flag. This is precisely one of my biggest gripes with Quasar (a Vue framework), which, on top of webpack/vue adds its own config that are intermingled with vue's and webpack's, and its honestly a mess, and oftentimes just straight up makes problems harder to solve.
I am obviously not railing against config dedicated to a single tool in a toolchain, but the way you described it rings a bell, especially the "unpredictability".
>* Many open issues regarding module imports, for ex, when a CJS module imports an ES one
This also seems to confirm my and other's suspicion, that the tool isn't really "deliver-grade".
>If you hit a wall, install speed-measure-webpack-plugin to get some help.
But on the other hand, this is at least the fifth plugin I have heard someone recommend, dedicated just to profiling Webpack.
What do you think about the time difference shown in the article? I sort of feel it's a bit disingenuous since the test included a lot of other variables, but it seems hard to argue against it if it's this plain. Is this a config issue, or a "most commonly used loader" issue...?
I'd be dishonest if I told you I was able to compare them 1-to-1. I couldn't finish my Vite setup because of bugs and lack of proper SSR support.
I believe that, at this point, people are just nitpicking. When working on a client-side-only app, Vite is faster, but not by that much. In one of our apps, I saw it starting up in 1s compared to 2s with Webpack, and reloads in 100ms compared to 250ms. This is a Preact/TS/Emotion app that outputs almost 7MB of assets, 61 files to be precise, and works on IE11. And I hadn't even tried persistent caching with it yet. Webpack 5 with esbuild is a fast-enough solution.
NextJS is a well-established tool now and version 10.2 uses Webpack 5 under the hood. V11 is looking insanely fast (I suspect they replaced Babel with esbuild, and did some witchery): https://twitter.com/shuding_/status/1378086219708473344.
So yeah, slow performance with Webpack is definitely caused by a bad set of loaders/plugins. Eject a CRA app and you'll see a monster coming out.
If you figure out how to get Webpack to solve all these issues, that makes one working Webpack installation. When Vite solves their issues, all Vite installations will have the issues solved.
Vite is not a completely opinionated tool. You can still customise its behaviour and use plugins, so both installations would have very similar vulnerabilities at the end. For SSR, you need a self-written server entry point.
Webpack 5 has introduced asset modules, so now you can safely ditch raw-loader, url-loader and file-loader. [1]
> It just isn't suitable for proper server-side rendering, we'd need access to chunk names at build time
You can at later rollup hooks (it doesn't make sense to access chunks that don't exist yet).
Actually, there are SSR frameworks being built on top of Vite such as SvelteKit [1] or vite-plugin-ssr [2] (vite-plugin-ssr is not a framework but gives you a similar DX than Nuxt/Next.js; I'm its author), and many people are implementing custom SSR solutions.
Have you seen SvelteKit's source code? It looks like a toy project. [1]
vite-plugin-ssr can't even be integrated with Vue Router (I saw you're working on deep integration though). They're both very rigid, early stage endeavours. [2] What happens, for ex, if you used nested lazy components in those pages, are they going to be included in the server render as well?
I mean, fair enough that there are people trying to do better, but it's extremely hard to find the right abstractions for such complex builds and Webpack is definitely on top here.
I mean, if you think vite-plugin-ssr to be rigid, then Next.js should feel like a 2sqm prison cell to you ;-).
If you want more flexibility than vite-plugin-ssr then use Vite's native SSR API.
Whereas with webpack: good luck with 1. using two webpack configs (one for Node.js and one for the browser), 2. synchronising between these 2 webpack configs, 3. implementing server-side HMR; it's incredibly painful and can cost you many weeks of dev time... whereas Vite's SSR API does all of this for you for free.
Sure, things are early stage, but saying that webpack is "definitely" on top for SSR is wrong in virtually any possible way.
* Making sure `mode` is set to "development" (don't specify it all if in doubt)
* Ditching babel-loader and using esbuild-loader instead
* Adjusting build targets and making sure polyfills are not added in development
* Making sure you don't import the entirety of libraries like Lodash and MomentJS (prefer date-fns)
* [FUTURE] We'll soon be able to tell Webpack to output ES modules just like Vite [1]
Vite still has many problems:
* It just isn't suitable for proper server-side rendering, we'd need access to chunk names at build time
* It has a weird mix of own and Rollup config settings that seems somewhat unpredictable
* Many open issues regarding module imports, for ex, when a CJS module imports an ES one [2]
Our current bottleneck with Webpack is actually sass-loader, taking at least 70% of the time during a fresh build, and we'd have the same problem with Vite.
Something else that is worth pointing out is the ecosystem: Webpack's community has built tons of plugins for basically any use case you can imagine, and version 5 supports module federation, persistent caching, externals (very handy when doing SSR), customizable filename generators, performance hints, etc etc. Totally different game.
Try to keep your build config simple, avoid too many loaders, plugins, and you should be fine 99% of the time. If you hit a wall, install speed-measure-webpack-plugin to get some help.
[1] https://github.com/webpack/webpack/issues/2933
[2] https://github.com/vitejs/vite/issues?q=is%3Aissue+is%3Aopen...