Awesome
Use Vite Today
out-of-the-box for vue-cli projects without any codebase modifications.
<a href="https://github.com/IndexXuan/vue2-final-boilerplate" target="_blank" rel="noreferer nofollow">demo/boilerplate</a>
<p align="center"> <img src="./logo.png" alt="logo" title="logo" width="300px" /> </p> <p align="center"> <!-- <a href="https://github.com/IndexXuan/vue-cli-plugin-vite/actions/workflows/npm-publish.yml"> --> <!-- <img alt="NPM Publish" src="https://github.com/IndexXuan/vue-cli-plugin-vite/actions/workflows/npm-publish.yml/badge.svg?branch=main" style="max-width:100%;"> --> <!-- </a> --> <img alt="wakatime" src="https://wakatime.com/badge/github/IndexXuan/vue-cli-plugin-vite.svg" /> <a href="https://www.npmjs.com/package/vue-cli-plugin-vite" rel="nofollow" target="_blank"> <img alt="npm version" src="https://img.shields.io/npm/v/vue-cli-plugin-vite.svg" style="max-width:100%;"> </a> <a href="https://www.npmjs.com/package/vue-cli-plugin-vite" rel="nofollow" target="_blank"> <img alt="downloads" src="https://img.shields.io/npm/dt/vue-cli-plugin-vite.svg" style="max-width:100%;"> </a> <a href="https://www.npmjs.com/package/vue-cli-plugin-vite" rel="nofollow" target="_blank"> <img alt="download monthly" src="https://img.shields.io/npm/dm/vue-cli-plugin-vite.svg" style="max-width:100%;"> </a> <br /> <a href="https://github.com/IndexXuan/vue-cli-plugin-vite/actions/workflows/ci.yml" target="_blank"> <img alt="CI" src="https://github.com/IndexXuan/vue-cli-plugin-vite/actions/workflows/ci.yml/badge.svg" style="max-width:100%;"> </a> <!-- <a href="https://github.com/IndexXuan/vue-cli-plugin-vite#readme"> --> <!-- <img alt="Documentation" src="https://img.shields.io/badge/Doc-yes-brightgreen.svg" style="max-width:100%;"> --> <!-- </a> --> <a href="https://github.com/IndexXuan/vue-cli-plugin-vite/graphs/commit-activity" target="_blank"> <img alt="Maintenance" src="https://img.shields.io/badge/Maintained-yes-green.svg" style="max-width:100%;"> </a> <a href="https://github.com/IndexXuan/vue-cli-plugin-vite/blob/main/LICENSE" target="_blank"> <img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" style="max-width:100%;"> </a> <!-- <a href="https://twitter.com/indexxuan" rel="nofollow"> --> <!-- <img alt="Twitter: IndexXuan" src="https://img.shields.io/twitter/follow/indexxuan.svg?style=social" style="max-width:100%;"> --> <!-- </a> --> </p>Table of Contents
<!-- toc -->- Usage
- Motivation
- Options
- Underlying principle
- Milestones
- Examples
- Troubleshooting
- Benefits
- Relevant Vite Plugins
Usage
# 1. first step
vue add vite
# 2. second step
# NOTE you cannot directly use `vite` or `npx vite` since it is origin vite not this plugin.
yarn vite // or npm run vite
# 3. add optimizeDeps#include (optional and will speedup devServer start time a lot)
# added in vue.config.js#pluginOptions.vite.optimizeDeps.include
# e.g.: ['vue', 'vue-router', 'vuex']
# all scanned deps(logged in terminal) can be added for speedup.
Motivation
- We have lots of exists vue-cli(3.x / 4.x) projects.
- In Production: vue-cli based on webpack is still the best practice for bundling webapp(with code spliting, legecy-build for old browsers).
- In Development: instant server start and lightning fast HMR by vite is interesting.
- Why not use them together ?
Options
// vue.config.js
{
// ...
pluginOptions: {
vite: {
/**
* Plugin[]
* @default []
*/
plugins: [], // other vite plugins list, will be merge into this plugin\'s underlying vite.config.ts
/**
* Vite UserConfig.optimizeDeps options
* recommended set `include` for speedup page-loaded time, e.g. include: ['vue', 'vue-router', '@scope/xxx']
* @default {}
*/
optimizeDeps: {},
/**
* type-checker, recommended disabled for large-scale old project.
* @default false
*/
disabledTypeChecker: true,
/**
* lint code by eslint
* @default false
*/
disabledLint: false,
}
},
}
Underlying principle
Compatibility
- NO EXTRA files, code and dependencies injected
- injected one devDependency
vue-cli-plugin-vite
- injected one line code in
package.json#scripts#vite
and one file atbin/vite
- injected one devDependency
- auto-resolved as much options as we can from
vue.config.js
(publicPath, alias, outputDir...) - auto reuse public/index.html as vite html entry template
- compatible the differences between vue-cli and vite(environment variables, special syntax...)
Differences between vue-cli and vite
Dimension | vue-cli | vite |
---|---|---|
Plugin | 1. based on webpack. <br />2. have service and generator lifecycles. <br />3. hooks based on each webpack plugin hooks | 1. based on rollup. <br />2. no generator lifecycle. <br />3. universal hooks based on rollup plugin hooks and vite self designed |
Environment Variables | 1. loaded on process.env. <br />2. prefixed by VUE_APP_ . <br />3. client-side use process.env.VUE_APP_XXX by webpack definePlugin | 1. not loaded on process.env. <br />2. prefixed by VITE_ . <br />3. client-side use import.meta.env.VITE_XXX by vite inner define plugin |
Entry Files | 1. main.{js,ts}. | 1. *.html |
Config File | 1. vue.config.js | 1. vite.config.ts. <br />2. support use --config to locate |
MPA Support | 1. native support by options.pages . <br />2. with history rewrite support | 1. native support by rollupOptions.input |
Special Syntax | 1. require(by webpack) <br /> 2. require.context(by webpack) <br />2. use ~some-module/dist/index.css (by css-loader ) <br />3. module.hot for HMR | 1. import.meta.glob/globEager <br />2. native support by vite, use module/dist/index.css directly <br />3. import.meta.hot for HMR |
Local devServer | 1. webpack dev-server <br />2. express-style middleware and many extension api. | 1. connect <br />2. connect middleware |
Type Checker | 1. fork-ts-checker-webpack-plugin | 1. No built-in, we can use vite-plugin-checker(based on vetur and vue-tsc) |
Lint | 1. @vue/cli-plugin-eslint | 1. No built-in we can use vite-plugin-eslint, |
Jest | 1. @vue/cli-plugin-jest | 1. will have first-class jest support |
Milestones
- Done ✅ vs WIP ⬜️ vs ❌ Won't support
- ✅ Plugin
- ✅ we can do nothing but rewrite corresponding vite-plugin, most code and tools can be reused
- ✅ Environment Variables Compatibility
- ✅ load to process.env.XXX (all env with or without prefix will be loaded)
- ✅ recognize
VUE_APP_
prefix - ✅ define as
process.env.${PREFIX}_XXX
for client-side
- ✅ Entry Files (we can do nothing)
- ✅ Config File (vue.config.js Options auto-resolved)
- ✅ vite#base - resolved from
process.env.PUBLIC_URL || vue.config.js#publicPath || baseUrl
- ✅ vite#css - resolved from vue.config.js#
css
- ✅ preprocessorOptions:
css.loaderOptions
- ✅ preprocessorOptions:
- ✅ vite#server- resolved from vue.config.js#
devServer
- ✅ host - resolved from
process.env.DEV_HOST || devServer.public
- ✅ port - resolved from
Number(process.env.PORT) || devServer.port
- ✅ https - resolved from
devServer.https
- ✅ open - resolved from
process.platform === 'darwin' || devServer.open
- ✅ proxy - resolved from
devServer.proxy
- ✅ before
- use middlewares to improve viteDevServer(connect instance) to express instance
- ✅ host - resolved from
- ✅ vite#build
- ✅ outDir - resolved from vue.config.js#
outputDir
- ✅ cssCodeSplit - resolved from
css.extract
- ✅ sourcemap - resolved from
process.env.GENERATE_SOURCEMAP === 'true' || productionSourceMap || css.sourceMap
- ✅ outDir - resolved from vue.config.js#
- ✅ Alias - resolved from configureWebpack or chainWebpack
- ✅ also resolved from
vue.config.js#runtimeCompiler
- ✅ also resolved from
- ✅ vite#base - resolved from
- ✅ MPA Support
- ✅ same development experience and build result
- ✅ Build Support (as of 1.0.0-rc.0, no real html entry file generated, just reuse public/index.html of vue-cli)
- ✅ Support SPA Build
- ✅ Support MPA Build
- ✅ Special Synatax
- ❌ require('xxx') or require('xxx').default, most of the case, it can be replaced by dynamicImport ( import('xxx') or import('xxx').then(module => module.default) )
- ✅ import '~some-module/theme/index.css' syntax for Import CSS supported by vite#2185)
- ✅ import '~@some-module/theme/index.css' syntax for Import CSS supported by vite#2185)
- ✅ ~public & ~/public support
- ✅ require.context compatibility
- ✅ module.hot compatibilite
- ✅ Type Checker
- ✅ Lint
- ⬜️ Eject and Codemod
- ⬜️ eject vite.config.ts
- ⬜️ eject vite deps
- ⬜️ remove vue-cli and webpack deps
- ⬜️ codemod webpack special syntax to vite-specific( import.meta.{hot, env} )
Examples
- simple vue-cli SPA project
- simple vue-cli MPA TypeScript project
- complex chrisvfritz/vue-enterprise-boilerplate project
you can clone/fork this repo, under examples/*
Troubleshooting
Benefits
Best development-experience right now
- Instant server start and lightning fast HMR
Migration to vite smoothly
- In the future, migration to vite is only the replacement of special syntax between webpack and vite
Lint the codebase
- lint dependencies, which is incorrectly use main/module/exports field in package.json
- lint codebase, which is more es-module compatible
- use import('xxx') not
require('xxx')
use import.meta.xxx notmodule.xxx
- use import('xxx') not
Use vue-cli ecosystem
- first-class eslint/stylelint integration
- first-class unit-test integration (by @vue/cli-plugin-unit-jest)
- first-class e2e integration (by @vue/cli-plugin-cypress)
- first-class xyz support by the official and community plugins
Relevant Vite Plugins
- vite-plugin-vue2@underfin - Vue 2 support for vite.
- @vitejs/plugin-vue - Official Vue 3 plugin.
- @vitejs/plugin-vue-jsx - Official Vue 3 jsx plugin.
- vite-plugin-vue-cli@IndexXuan - Infer vite config from vue.config.js.
- vite-plugin-html-template@IndexXuan - Like html-webpack-plugin for webpack.
- vite-plugin-mpa@IndexXuan - MPA support for vite.
- vite-plugin-checker@fi3ework - Type checker for vite.
- vite-plugin-eslint@gxmari007 - Eslint for vite.
- vite-plugin-env-compatible@IndexXuan - Env compatibility for vite with vue-cli.