Vite ⚡️ is the Eminem of frontend tooling.
Why? Because is crazy fast and delivers well.
In mid-February Evan You announced the release of the latest iteration of Vite
Vite (French word for "fast", pronounced
/vit/
) is a new kind of build tool for front-end web development. Think a pre-configured dev server + bundler combo, but leaner and faster. It leverages browser's native ES modules support and tools written in compile-to-native languages likeesbuild
to deliver a snappy and modern development experience.
With this tutorial, you're going to learn how to set up a Vue3 app with Vite in no-time, some cool plugins to improve the DX (Developer Experience), and more importantly, understand how does it work and why is so fast.
Scaffolding your first Vite project
Open your favorite terminal and run:
npm init @vitejs/app
Or if you prefer Yarn:
yarn create @vitejs/app
And follow the prompts:
Vite supports multiple templates presets such as:
vanilla
vue
vue-ts
react
react-ts
preact
preact-ts
lit-element
lit-element-ts
You can also scaffold with one command via additional command-line options for name and template. In this tutorial, we're going to build a Vue project.
yarn create @vitejs/app awesomely-fast --template vue
And let the magic be... ok it's already installed.
Structure of a Vite project
The first thing you probably have noticed is that index.html
is no longer in the public
folder but in the root directory.
That's because Vite treats the index.html
as source code and part of the module graph. Similar to static HTTP servers, Vite has the concept of a "root directory" from which your files are served from.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
The rest of the structure it's pretty standard inside an src
folder with an App.vue
as your root component and a main.js
to bootstrap your Vue App.
Dev server
Your package.json
will come with three (3) built-in scripts:
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
Go ahead and run yarn dev
.
Exactly, around ~344ms to cold start a dev server. To give you an idea of how fast it is, using vue-cli the dev server would take around a second and a half.
When cold-starting the dev server, a bundler-based (webpack) setup has to eagerly crawl and build your entire application before it can be served.
Vite improves the dev server start time by first dividing the modules in an application into two categories
- dependencies: Essentially plain javascript that would not change during development
- source code: Yeap, your code, all your Vue components, and CSS that you often edit.
Vite serves source code over native ESM. This is essentially letting the browser taking over part of the job of a bundler
Do you remember the <script type="module" />
tag at the beginning? That's is using native ESM approach.
How does it work?
Let's have a look at the Network Tab
of a Vite app vs vue-cli
(webpack)
vue-cli
In the image above, vue-cli
bundles the code into two main chunks:
- app.js which contains the bundle of your code
- chunk-vendors.js containing all the code from third-parties.
Around 2.4 MB in 2 requests with a total load time of 301ms
Bundle-based dev-servers take the job of packaging all modules and different files into one static bundle that is served on mostly all the cases an express server. Similar to this image
The more complexity inside the box, the more time will need the server to start.
Now let's compare that with the Vite one.
Vite dev-server
As you can see, Vite loads every file (.vue
, .js
) as a module, been able of doing it parallel, and reduce the total load time to around ~190ms
.
Notice the size transferred, it didn't reach 1 MB compared to the 2.4MB of the bundle-based.
This speed is because native ESM transfers part of the responsibility of the job of a bundler to the browser itself. It basically transforms and serves code on-demand while the browser requests it via HTTP.
This comparison, of course, is done with a small app with one (1) component, I suggest you try the same with a bigger/complex one and you will be amazed by the results.
The struggle of slow updates
Before Vite, as your application evolve and start holding hundreds of components, It would incrementally increase the time to pack them into a bundle, that's why many bundlers run the building on memory and others use Hot module Replacement (HMR) to increase the speed between updates.
In Vite, HMR is performed over native ESM. When a file is edited, Vite only needs to precisely invalidate the chain between the edited module and its closest HMR boundary (most of the time only the module itself), making HMR updates consistently fast regardless of the size of your application.
That means that no matter how big is your app, it will not affect the speed when serving.
If you want to see a real comparison test of speed between bundle-based vs Vite check this article I wrote earlier
Article No Longer Available
What, no loaders for styling?
One of the things that impressed me the most is that Vite does provide built-in support for .scss
, .sass
, .less
, .styl
, and .stylus
files.
There is no need to install loaders or Vite-specific plugins for them, but the corresponding pre-processor itself must be installed:
# .scss and .sass
yarn add -D sass
# .less
yarn add -D less
# .styl and .stylus
yarn add -D stylus
That way you can concentrate on plugins that really matter, like the ones we're gonna check in the next section
Plugins, plugins, plugins
To enhance your Vite app, here is a list of my top plugins available:
@vitejs/plugin-vue
This is an official plugin packaged inside the Vite repo to support Vue3 SFC components.
It makes sense is optional due to the fact that Vite is framework agnostic.
To use it, add the following to your vite.config.js
// vite.config.js
import vue from '@vitejs/plugin-vue'
export default {
plugins: [vue()]
}
antfu/vite-plugin-pwa
vite-pwa / vite-plugin-pwa
Zero-config PWA for Vite
Provides quick zero-config for PWA support
npm i vite-plugin-pwa -D
yarn add vite-plugin-pwa -D
Add it to vite.config.js
// vite.config.js
import { VitePWA } from 'vite-plugin-pwa'
export default {
plugins: [
VitePWA({
manifest: {
// content of manifest
},
workbox: {
// workbox options for generateSW
}
})
]
}
antfu/vite-plugin-md
antfu / vite-plugin-md
Markdown with Vue for Vite
This loader for markdown allows you to use Markdown as Vue components and use your Vue components in Markdown files
Install
npm i vite-plugin-md -D
yarn add vite-plugin-md -D
Add it to vite.config.js
// vite.config.js
import Vue from '@vitejs/plugin-vue'
import Markdown from 'vite-plugin-md'
export default {
plugins: [
Vue({
include: [/\.vue$/, /\.md$/], // <--
}),
Markdown()
],
}
antfu/vite-plugin-icons
unplugin / unplugin-icons
🤹 Access thousands of icons as components on-demand universally.
Access thousands of icons as Vue components in Vite
- 90+ iconsets powered by Iconify
- Browser the icons
Install
npm i vite-plugin-icons @iconify/json -D
yarn add vite-plugin-icons @iconify/json -D
Add it to vite.config.js
// vite.config.js
import Vue from '@vitejs/plugin-vue'
import Icons from 'vite-plugin-icons'
export default {
plugins: [
Vue(),
Icons()
],
}
<script setup>
import IconAccessibility from '/@vite-icons/carbon/accessibility'
import IconAccountBox from '/@vite-icons/mdi/account-box'
</script>
<template>
<icon-accessibility/>
<icon-account-box style="font-size: 2em; color: red"/>
</template>
It also allows auto-importing
Nuxt/vite 😍
What about using Vite with Nuxt? That's cover.
Install nuxt-vite: (nuxt >= 2.15.0 is required)
yarn add --dev nuxt-vite
# OR
npm i -D nuxt-vite
Add to buildModules:
// nuxt.config
export default {
buildModules: [
'nuxt-vite'
]
}
antfu/vite-plugin-components
Tired of importing manually your components? Say no more.
unplugin / unplugin-vue-components
📲 On-demand components auto importing for Vue
npm i vite-plugin-components -D
#OR
yarn add vite-plugin-components -D
Add it to vite.config.js
// vite.config.js
import Vue from '@vitejs/plugin-vue'
import ViteComponents from 'vite-plugin-components'
export default {
plugins: [
Vue(),
ViteComponents()
],
};
That's all.
Tailwind on-demand with windicss
windicss / vite-plugin-windicss
🍃 Windi CSS for Vite ⚡️
npm i vite-plugin-windicss -D
#OR
yarn add vite-plugin-windicss -D
// vite.config.js
import WindiCSS from 'vite-plugin-windicss'
export default {
plugins: [
WindiCSS()
],
};
// main.js
import 'windi.css'
That's all. Build your app just like what you would do with Tailwind CSS, but much faster! ⚡️
If you want to check more plugins they are all listed here
vitejs / awesome-vite
⚡️ A curated list of awesome things related to Vite.js
Awesome Vite.js
A curated list of awesome things related to Vite.js
Table of Contents
Use the "Table of Contents" menu on the top-right corner to explore the list.
Resources
Official Resources
Get Started
- create-vite - Scaffolding Your First Vite Project.
- create-vitawind - Scaffolding for TailwindCSS project.
- create-electron-vite - Scaffolding Your Electron + Vite Project.
- create-vite-app - Scaffolding Your Out Of The Box Vite Project.
- create-nx-workspace - Scaffolding a Nx + React + Vite + Vitest.
- bati - Scaffolding a Vike project.
- create-awesome-node-app - Scaffolding your project choosing between different templates.
Templates
Vanilla
- vite-vanilla-ts-lib-starter - Starter for library (CJS, ESM, IIFE) with TypeScript, ESLint, Stylelint, Prettier, Jest, Husky + lint-staged.
- vite-tailwind-nojs-starter - NoJS Tailwind CSS starter template.
- vite-tailwind-stimulus-starter - Starter template for Tailwind CSS and Stimulus controllers.
- vite-phaser-ts - Starter template with Phaser and Typescript.
- vite-tinybase - Starter…
Are you ready to step up with your frontend tooling?
Top comments (1)
Vite can not reload page after us file change