
Daniel Kelly
Teacher @ Vue School
Full Stack developer (10 years)
Husband and Father

What is Vite?
What is Vite?
Next generation front-end tooling that aims to provide a leaner and faster development experience

Current State of Development
Current State of Development
Current State of Development

Current State of Development


Vite to the Rescue

Dev Server Start Times: 259ms
HMR: Essentially instant
Development Server
- Browser Support for ES Modules
-
ESBuild
- TypeScript
- Vue SFC
ESBuild Benchmarks

Production Bundling
- Uses Rollup under the hood
-
Why Rollup?
- build speed
- tree-shaking
- output size
Why Vite
- Uses Rollup under the hood
-
Why Rollup?
- build speed
- tree-shaking
- output size

Vite to the Rescue
- Native ES Modules
- ESBuild - GO based JS bundler


Vite to the Rescue
- Native ES Modules
- ESBuild - GO based JS bundler
- How Vite Changes the Game for Vue and Web Developers - Alex Kyriakidis

Rapid Development with Vite


Process of Discovery
- Create brand new Vue CLI project
- Create brand new Vite Project
- Compare the differences
- Steps will cover 70% - 90%
- Don't look at the steps as something to memorize
Process of Discovery


Step # 1
Update Dependencies
// package.json
{
//...
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.2.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11"
}
}

Step # 1
Update Dependencies
// package.json
{
//...
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.2.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"vue-template-compiler": "^2.6.11"
}
}

Step # 1
Update Dependencies
// package.json
{
//...
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.2.1",
"sass": "^1.26.5",
"vue-template-compiler": "^2.6.11"
}
}

Step # 1
Update Dependencies
// package.json
{
//...
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"@vue/eslint-config-prettier": "^6.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.2.1",
"sass": "^1.26.5",
}
}

Step # 1
Update Dependencies
$ npm i -D vite

Step # 1
Update Dependencies
$ npm i -D vite-plugin-vue2

Step # 1
Update Dependencies
$ npm i -D @vitejs/plugin-vue

Step # 1
Update Dependencies
$ npm prune

Step # 2
Provide Support only For Modern Browsers

https://kangax.github.io/compat-table/es6/

Step # 2
Provide Support only For Modern Browsers


Step # 2
Provide Support only For Modern Browsers


// package.json
{
//...
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.2.1",
"sass": "^1.26.5",
}
}
Step # 2
Provide Support only For Modern Browsers

// package.json
{
//...
"dependencies": {
"vue": "^2.6.11",
"vue-router": "^3.2.0"
},
"devDependencies": {
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.2.1",
"sass": "^1.26.5",
}
}
Step # 2
Provide Support only For Modern Browsers

// .eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
parserOptions: {
parser: "babel-eslint",
},
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
},
};
Step # 2
Provide Support only For Modern Browsers

// .eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
},
};
Step # 2
Provide Support only For Modern Browsers

// .eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
},
};
Step # 2
Provide Support only For Modern Browsers

// .eslintrc.js
module.exports = {
root: true,
env: {
node: true,
es2021: true,
},
extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
},
};
Step # 2
Provide Support only For Modern Browsers

$ npm install eslint@8 eslint-plugin-vue@8
Step # 2
Provide Support only For Modern Browsers

$ npm prune
Step # 2
Provide Support only For Modern Browsers

Step # 3
Add Vite Config
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
//https://vitejs.dev/config/
plugins: [vue()]
})

Step # 3
Add Vite Config
// vite.config.js
import { defineConfig } from 'vite'
import { createVuePlugin as vue } from "vite-plugin-vue2";
export default defineConfig({
//https://vitejs.dev/config/
plugins: [vue()]
})

Step # 3
Add Vite Config
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
//https://vitejs.dev/config/
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})

Step # 4
Move the index.html


Step # 4
Move the index.html
<!--index.html-->
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Step # 4
Move the index.html
<!--index.html-->
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Step # 4
Move the index.html
<!--index.html-->
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Hard Coded Title</title>
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Step # 4
Move the index.html
<!--index.html-->
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Hard Coded Title</title>
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Step # 4
Move the index.html
<!--index.html-->
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="/favicon.ico">
<title>Hard Coded Title</title>
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Step # 4
Move the index.html
<!--index.html-->
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="/favicon.ico">
<title>Hard Coded Title</title>
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

Step # 4
Move the index.html
<!--index.html-->
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="/favicon.ico">
<title>Hard Coded Title</title>
</head>
<body>
<noscript>
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

Step # 5
Update Scripts in package.json
// package.json
{
//...
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
//...
}

Step # 5
Update Scripts in package.json
// package.json
{
//...
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
},
//...
}

Step # 5
Update Scripts in package.json
// package.json
{
//...
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
},
//...
}

Step # 6
Update Environment Variables
.env # loaded in all cases
.env.local # loaded in all cases, ignored by git
.env.[mode] # only loaded in specified mode
.env.[mode].local # only loaded in specified mode, ignored by git

Step # 6
Update Environment Variables
// /src/router/index.js
//...
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes,
});

Step # 6
Update Environment Variables
// /src/router/index.js
//...
const router = new VueRouter({
mode: "history",
base: import.meta.env.BASE_URL,
routes,
});

Step # 6
Update Environment Variables
// .env
VUE_APP_MY_HEADLESS_CMS_API_KEY=123

Step # 6
Update Environment Variables
// .env
VITE_MY_HEADLESS_CMS_API_KEY=123

Step # 7
Add .vue extension to SFC imports
// Home.vue
// .vue is required
import HelloWorld from "@/components/HelloWorld.vue";

Step # 7
Add .vue extension to SFC imports
// vite.config.js
//...
export default defineConfig({
plugins: [vue()],
resolve: {
extensions:
['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
//...
},
});

Step # 8
Clean Up Magic Comments
// router/index.js
//...
{
path: "/about",
name: "About",
component: () =>
import( /* webpackChunkName: "about" */ "../views/About.vue"),
},

Step # 8
Clean Up Magic Comments
// router/index.js
//...
{
path: "/about",
name: "About",
component: () =>
import("../views/About.vue"), // About.37a9fa9f.js,
},

Step # 9
Enjoy an improved developer experience




Vue School Courses

Other Great Courses
#1 Training Platform for Vue.js
800+ Video Lessons
140,000 users






Alex Kyriakidis
Daniel Kelly
Debbie O'Brien
Maria Lamardo
Roman Kuba
Filip Rakowski
Lydia Hallie


Anthony Fu


Workshops
Interested? Talk to our team at the conference or send us an email
💌 team@vueschool.io


💌 team@vueschool.io
1 day $3,500
2 day $6,000
- Vue.js Fundamentals
- Migrating from Vue 2 to Vue 3
- Vue 3 Composition API
- State Management with Pina
- TypeScript + Vue
2 days $6,000
🔥
Berlin Conf Workshop Special
- Migrating from Nuxt 2 to Nuxt 3













Grab Some Swag 🤗




Vue Corporate Training
NEW
📺
Vue Video
Courses
👨🏫
Live Workshops
💬
Bi-weekly Support
Sessions
🧑🔧
Database for hiring
Vue devs
Nuxt Nation
NEW



Thank You!
How to Migrate to Vite
By Daniel Kelly
How to Migrate to Vite
- 2,090