Getting Started with Vite 2
Tags: vite, webdev, javascript, tutorial
Published: 2021-03-03 16:44:08

Vite ⚡️ is the Eminem of frontend tooling.

![Rap God](https://media.giphy.com/media/3ohs7QTNjLXMYNSc1O/giphy.gif)

Why? Because is crazy fast and delivers well. 

In mid-February [Evan You](https://dev.to/yyx990803) announced the release of the latest iteration of Vite

{% post https://dev.to/yyx990803/announcing-vite-2-0-2f0a %} 

> 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 like `esbuild` 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:

```bash
npm init @vitejs/app
```

Or if you prefer Yarn:

```bash
yarn create @vitejs/app
```

And follow the prompts:

![create-vite-app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c7m797daflzh61fz7f3w.png)

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.

```bash
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.

```html
<!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:

```json
 "scripts": {
    "dev": "vite",
    "build": "vite build",
    "serve": "vite preview"
  },
```

Go ahead and run `yarn dev`. 

![dev-server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4e33cb0050rbbzcqp17.gif)
 
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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) approach.

# How does it work?

Let's have a look at the `Network Tab` of a Vite app vs `vue-cli` (webpack)

## vue-cli

![vue-cli network](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0m1r2rdskr48l44lfsq9.png)

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**


![Screenshot 2021-03-03 at 10.15.52](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8tj1mh3tj6o3izihewtd.png)

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

![bundle-based-dev-server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8dsrdnbpmjd9xjjzijnu.png)

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

![vite network](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8o0jcrn5nz9ewo9sa0tn.png)
    
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.

![Screenshot 2021-03-03 at 10.19.24](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ybgmkim3idu05bl2oep.png)

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.

![vite-dev-server](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nqnluhb02pngl9ifva4.png)
 

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

![slow updates](https://media.giphy.com/media/Y3qrREWGFsechb940U/giphy.gif)

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](https://webpack.js.org/concepts/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

{% post alvarosaburido/vite-2-a-speed-comparison-in-vue-1f5j %}

#  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:

```bash
# .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](https://github.com/vitejs/vite/tree/main/packages/plugin-vue) 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` 

```javascript
// vite.config.js
import vue from '@vitejs/plugin-vue'

export default {
  plugins: [vue()]
}
```

## antfu/vite-plugin-pwa

{% github antfu/vite-plugin-pwa no-readme %}

Provides quick zero-config for PWA support

```bash
npm i vite-plugin-pwa -D 

yarn add vite-plugin-pwa -D
```

Add it to vite.config.js
```javascript
// 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 

{% github antfu/vite-plugin-md no-readme %}

This loader for markdown allows you to use Markdown as Vue components and use your Vue components in Markdown files

Install

```bash
npm i vite-plugin-md -D 

yarn add vite-plugin-md -D
```

Add it to vite.config.js

```javascript
// 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 

{% github antfu/vite-plugin-icons no-readme %}

Access thousands of icons as Vue components in Vite

- 90+ iconsets powered by [Iconify](https://github.com/iconify/iconify)
- [Browser the icons](https://icones.js.org/)

Install

```bash
npm i vite-plugin-icons @iconify/json -D 

yarn add vite-plugin-icons @iconify/json -D
```

Add it to vite.config.js

```javascript
// vite.config.js
import Vue from '@vitejs/plugin-vue'
import Icons from 'vite-plugin-icons'

export default {
  plugins: [
    Vue(),
    Icons()
  ],
}
```

```vue
<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](https://github.com/antfu/vite-plugin-icons#auto-importing)

## Nuxt/vite 😍

What about using Vite with Nuxt? That's cover.

{% github https://github.com/nuxt/vite no-readme%}

Install nuxt-vite: `(nuxt >= 2.15.0 is required)`

```bash
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.

{% github antfu/vite-plugin-components no-readme %}

```bash
npm i vite-plugin-components -D 
#OR 
yarn add vite-plugin-components -D
``` 

Add it to `vite.config.js`

```javascript
// 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](https://github.com/windicss/windicss)

{% github windicss/vite-plugin-windicss no-readme %}

```bash
npm i vite-plugin-windicss -D 
#OR 
yarn add vite-plugin-windicss -D
```

```javascript
// vite.config.js
import WindiCSS from 'vite-plugin-windicss'

export default {
  plugins: [
    WindiCSS()
  ],
};
```

```javascript
// 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 

{%  github vitejs/awesome-vite  %}

Are you ready to step up with your frontend tooling?