Vite快速入门教程
2022-06-02 23:30:36
2024-11-20 15:01:44
完整配置(vite.config.js)
js
import { ConfigEnv, loadEnv, UserConfig } from "vite";
import { resolve } from "path";
import vue from "@vitejs/plugin-vue";
// import vitePluginAliOss from 'vite-plugin-ali-oss';
//自动导入组件
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import AutoImport from "unplugin-auto-import/vite";
//按需引入ElementPlus组件
import { createStyleImportPlugin, ElementPlusResolve } from "vite-plugin-style-import";
//提供压缩和基于 ejs 模板功能的 vite 插件
import { createHtmlPlugin } from "vite-plugin-html";
import { visualizer } from "rollup-plugin-visualizer";
import { webUpdateNotice } from "@plugin-web-update-notification/vite";
import viteCompression from "vite-plugin-compression";
import importToCDN from "vite-plugin-cdn-import";
function pathResolve(dir: string) {
return resolve(process.cwd(), ".", dir);
}
export default ({ mode }: ConfigEnv): UserConfig => {
// 获取 .env 环境配置文件
const env = loadEnv(mode, process.cwd());
const plugins = [
vue(),
webUpdateNotice({
logVersion: true,
notificationProps: {
title: "更新通知",
description: "网站内容有更新,请刷新页面,获取最新内容",
buttonText: "刷新",
dismissButtonText: "忽略"
}
}),
visualizer(),
//导入自定义组件
Components({
// 指定组件位置,默认是src/components
dirs: ["src/components"],
extensions: ["vue"],
// 配置文件生成位置
dts: "src/components.d.ts",
// ui库解析器,也可以自定义
resolvers: [ElementPlusResolver()]
}),
//导入vue函数
AutoImport({
imports: ["vue", "vue-router", "pinia"],
// 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
dts: "src/auto-import.d.ts",
// eslint报错解决
eslintrc: {
enabled: true, // Default `false`
filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json`
globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
}
}),
//按需引入vant组件样式
createStyleImportPlugin({
resolves: [ElementPlusResolve()]
}),
//ejs变量注入
createHtmlPlugin({
minify: true,
// entry: "src/main.ts",
// template: "index.html",
inject: {
data: {
title: env.VITE_APP_TITLE,
isProd: mode === "production"
}
}
}),
//oss
// vitePluginAliOss({
// region: env.VITE_OSS_REGION,
// accessKeyId: env.VITE_OSS_ACCESSKEYID,
// accessKeySecret: env.VITE_OSS_ACCESSKEYSECRET,
// bucket: env.VITE_OSS_BUCKET,
// }),
// 打包压缩,主要是本地gzip,如果服务器配置压缩也可以
viteCompression(),
importToCDN({
modules: [
{
name: "videojs",
var: "videojs",
path: "https://cdn.bootcdn.net/ajax/libs/video.js/8.2.0/video.min.js",
css: "https://cdn.bootcdn.net/ajax/libs/video.js/8.2.0/video-js.min.css"
}
]
})
]; // 可将其他插件放入该数组
return {
//开发或生产环境服务的公共基础路径
// base: mode === 'production' ? env.VITE_OSS_URL : './',
base: "./",
resolve: {
alias: [
{
find: /@\//,
replacement: pathResolve("src") + "/"
}
]
},
css: {
preprocessorOptions: {
//配置全局样式
// scss: {
// //设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
// charset: false,
// additionalData: ['@use "@/assets/css/globalstyle.scss" as *;'],
// },
}
},
server: {
host: "0.0.0.0",
port: Number(env.VITE_APP_PORT),
open: false, // 设置服务启动时是否自动打开浏览器
cors: true, // 允许跨域
proxy: {
[env.VITE_APP_BASE_API]: {
target: env.VITE_APP_BASE_API_URL,
changeOrigin: true,
secure: false,
//删除/api
rewrite: path => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), "")
}
}
},
plugins: plugins,
build: {
minify: "terser",
//限制的大小将500kb改成600kb
chunkSizeWarningLimit: 600,
terserOptions: {
compress: {
//生产环境时移除console
drop_console: true,
drop_debugger: true
},
output: {
// 去掉注释内容
comments: true
}
},
//指定生成静态资源的存放路径
assetsDir: "/",
rollupOptions: {
//打包目录区分优化
output: {
// manualChunks(id) {
// // if (id.includes('node_modules')) {
// // return id.toString().split('node_modules/')[1].split('/')[0].toString();
// // }
// },
//把echarts单独打包(按需引入分离出去)
manualChunks: {
echarts: ["echarts"]
},
chunkFileNames: "static/[name]-[hash].js",
entryFileNames: "static/[name]-[hash].js",
assetFileNames: "static/[name]-[hash].[ext]"
}
}
}
};
};
自动导入组件、hooks、样式
插件 | 作用 |
---|---|
unplugin-vue-components | 组件自动引入 |
unplugin-auto-import/vite | vue3等插件 hooks 自动引入 |
vite-plugin-style-import | 样式自动引入 |
vue-global-api | eslint插件 |
1.1 自动导入ui库,该插件内置了大多数流行库解析器
shell
npm install unplugin-vue-components -D
js
// vite.config.js,插件会生成一个ui库组件以及指令路径components.d.ts文件
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
import {
ElementPlusResolver,
AntDesignVueResolver,
VantResolver,
HeadlessUiResolver,
ElementUiResolver
} from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
Components({
// ui库解析器,也可以自定义
resolvers: [
ElementPlusResolver(),
AntDesignVueResolver(),
VantResolver(),
HeadlessUiResolver(),
ElementUiResolver()
]
})
]
})
1.2 自动导入自己的组件
js
// vite.config.js,插件会生成一个自己组件路径的components.d.ts文件
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
export default defineConfig({
plugins: [
Components({
// 指定组件位置,默认是src/components
dirs: ['src/components'],
// ui库解析器
// resolvers: [ElementPlusResolver()],
extensions: ['vue'],
// 配置文件生成位置
dts: 'src/components.d.ts'
})
]
})
2. unplugin-auto-import/vite
支持vue
, vue-router
, vue-i18n
, @vueuse/head
, @vueuse/core
等自动引入
js
// 引入前
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
//引入后
const count = ref(0)
const doubled = computed(() => count.value * 2)
// 引入前
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return <div>{ count }</div>
}
//引入后
export function Counter() {
const [count, setCount] = useState(0)
return <div>{ count }</div>
}
安装
shell
npm i -D unplugin-auto-import
js
// vite.config.js
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [
AutoImport({
imports: ['vue', 'vue-router', 'vue-i18n', '@vueuse/head', '@vueuse/core'],
// 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
// dts: 'src/auto-import.d.ts'
})
]
})
原理:
安装的时候会自动生成auto-imports.d文件(默认是在根目录)
3.vue-global-api解决eslint报错
在页面没有引入的情况下,使用unplugin-auto-import/vite来自动引入hooks,在项目中肯定会报错的,这时候需要在eslintrc.js中的extends引入vue-global-api,这个插件是vue3hooks的,其他自己找找,找不到的话可以手动配置一下globals
安装
shell
npm i vue-global-api -D
js
// .eslintrc.js
module.exports = {
extends: [
'vue-global-api'
]
};
它还为细粒度控制提供了相同的集合和单个 API 选项。
js
// .eslintrc.js
module.exports = {
extends: [
// collections
'vue-global-api/reactivity',
'vue-global-api/lifecycle',
'vue-global-api/component',
// single apis
'vue-global-api/ref',
'vue-global-api/toRef',
]
};
4.vite-plugin-style-import
当你使用unplugin-vue-components来引入ui库的时候
message, notification 等引入样式不生效 安装vite-plugin-style-import即可
这里以一些流行库为例
js
// vite.config.js
import { defineConfig } from 'vite'
import styleImport, {
AndDesignVueResolve,
VantResolve,
ElementPlusResolve,
NutuiResolve,
AntdResolve
} from 'vite-plugin-style-import'
export default defineConfig({
plugins: [
styleImport({
resolves: [
AndDesignVueResolve(),
VantResolve(),
ElementPlusResolve(),
NutuiResolve(),
AntdResolve()
],
// 自定义规则
libs: [
{
libraryName: 'ant-design-vue',
esModule: true,
resolveStyle: (name) => {
return `ant-design-vue/es/${name}/style/index`
}
}
]
})
],
// 引用使用less的库要配置一下
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true
}
}
}
})
5. 注意点
1. element-plus默认是英文
方案: 在app.vue加上ElConfigProvider
vue
<template>
<div id="app">
<el-config-provider :locale="locale">
<router-view></router-view>
</el-config-provider>
</div>
</template>
<script setup>
import zhCn from 'element-plus/lib/locale/lang/zh-cn'
const locale = zhCn
</script>
日期相关组件设置中文:
vue
<script setup>
// 日历等与dayjs相关的组件,不想显示中文可以不加
// 第一种方法 使用中国时区weekStart默认为1
import 'dayjs/locale/zh-cn'
// 第二种方法 使用 weekStart可配置(只能是0或者1)
import dayjs from 'dayjs'
// 引入英文即为英文
import cn from 'dayjs/locale/zh-cn'
dayjs.locale({
...cn,
weekStart: 1
})
const locale = zhCn
</script>
vite-plugin-ali-oss
打包自动上传打包文件到oss
js
import vitePluginAliOss from 'vite-plugin-ali-oss';
// 获取 .env 环境配置文件
const env = loadEnv(mode, process.cwd());
//oss plugins数组
vitePluginAliOss({
region: env.VITE_OSS_REGION,
accessKeyId: env.VITE_OSS_ACCESSKEYID,
accessKeySecret: env.VITE_OSS_ACCESSKEYSECRET,
bucket: env.VITE_OSS_BUCKET
})
vite使用cdn
vite-plugin-cdn-import
js
import importToCDN from 'vite-plugin-cdn-import';
importToCDN({
modules: [
{
name: 'vue',
var: 'Vue',
path: 'https://cdn.jsdelivr.net/npm/vue@3.2.25/dist/vue.global.prod.js'
},
{
name: 'vue-i18n',
var: 'VueI18n',
path: 'https://cdn.bootcdn.net/ajax/libs/vue-i18n/9.1.10/vue-i18n.global.prod.min.js'
},
{
name: 'vue-router',
var: 'VueRouter',
path: 'https://unpkg.com/vue-router@4.0.16/dist/vue-router.global.prod.js'
},
{
name: 'element-plus',
var: 'ElementPlus',
path: `https://unpkg.com/element-plus@2.2.6/dist/index.full.js`,
css: 'https://unpkg.com/element-plus/dist/index.css'
},
{
name: 'vue-demi',
var: 'VueDemi',
path: 'https://cdn.bootcdn.net/ajax/libs/vue-demi/0.13.1/index.iife.js'
},
{
name: 'pinia',
var: 'Pinia',
path: 'https://cdn.bootcdn.net/ajax/libs/pinia/2.0.14/pinia.iife.prod.min.js'
},
{
name: '@smallwei/avue',
var: 'AVUE',
path: 'https://cdn.jsdelivr.net/npm/@smallwei/avue@3.0.17'
}
]
}),
这上面的都有引用关系所以都需要通过cdn的方式引入
VueDemi这个是pinia用来判断是vue2还是vue3所需要的,要额外引入一下
第二种方案(通过rollup-plugin-external-globals)这个方式需要单独在index.html中引入cdn资源
js
import externalGlobals from 'rollup-plugin-external-globals';
let globals = externalGlobals({
vue: 'Vue',
'vue-i18n': 'VueI18n',
'vue-router': 'VueRouter',
'element-plus': 'ElementPlus',
pinia: 'Pinia',
'@smallwei/avue': 'AVUE'
});
//vite.config.ts(注意plugins的位置是在build下)
build:{
rollupOptions:{
// 忽略打包
external: ['vue', 'vue-i18n', 'pinia', 'vue-router', 'element-plus','@smallwei/avue'],
},
plugins: [globals],
}
// index.html
<script src="https://cdn.jsdelivr.net/npm/vue@3.2.25/dist/vue.global.prod.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-i18n/9.1.10/vue-i18n.global.prod.min.js"></script>
<script src="https://unpkg.com/vue-router@4.0.16/dist/vue-router.global.prod.js"></script>
<script src="https://unpkg.com/element-plus@2.2.6/dist/index.full.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-demi/0.13.1/index.iife.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/pinia/2.0.14/pinia.iife.prod.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@smallwei/avue@3.0.17"></script>
网页重新部署,通知用户-最佳实践
安装插件
language
pnpm add @plugin-web-update-notification/vite -D
原理
以 git commit hash (也支持 package.json version、build timestamp、custom) 为版本号,打包时将版本号写入 json 文件。客户端轮询服务器上的版本号(浏览器窗口的 visibilitychange、focus 事件辅助),和本地作比较,如果不相同则通知用户刷新页面。
vite.config.ts
language
import { webUpdateNotice } from '@plugin-web-update-notification/vite'
export default defineConfig({
plugins: [
vue(),
webUpdateNotice({
notificationProps: {
title: '更新通知',
description: '网站内容有更新,请刷新页面,获取最新内容',
buttonText: '刷新',
dismissButtonText: '忽略'
},
}),
]
})
目录