npm init vite@latest my-vue-app -- --template vue-ts
查看 create-vite 以获取每个模板的更多细节:
vanilla
,vanilla-ts
,vue
,vue-ts
,react
,react-ts
,preact
,preact-ts
,lit
,lit-ts
,svelte
,svelte-ts
。
执行npm run dev
命令,启动项目。
观察index.html
文件可以看到,vite对项目使用module
方式引入,这是冷加载的基础。
<body style="background-color: grey;height: 100%;">
<div id="app">div>
<script type="module" src="/src/main.ts">script>
<script type="module">
import './module.js';
script>
body>
module
引入方式支持按需加载,不用实时去打包。对于一些安装的第三方包,会进行预打包,比如vue
。
新建assets/styles/index.scss
,代码如下:
$bg: grey;
//page1.vue中使用
define: {
__TRUE__: 'false',
},
//global.d.ts
interface window {
__TRUE__: boolean;
}
//调用
console.log(window.__TRUE__);
if (!window.__TRUE__) {
console.log('aaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
}
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
"/icon":"./src/assets/"
},
},
//导入 /src/components/layer/confirm.vue 文件
import confirm from "@/components/layer/confirm.vue";
//引入资源
<img alt="Vue logo" src="/icon/logo.png" />
在vite.config.ts
中配置完成后,tsconfig.ts
也要做别名配置,需要设置baseUrl
、paths
。
{
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": false,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": [
"esnext",
"dom"
],
"skipLibCheck": true,
"baseUrl": "./", //----这里
"paths": {
"@/*": [ //----这里
"src/*"
]
}
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue"
],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}
配置后,
main.ts
中引入@
别名路径还是会有找不到文件的代码提示,但是其他文件中已经正常。
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
实测:一个vite+vue3+ts初始化项目,仅仅安装了element-plus的情况下;
main.ts全部引入,dist包尺寸:1.1MB
vite.config.ts按需引入,dist包尺寸:110.8KB
使用rollup-plugin-visualizer
插件,查看每次npm run build
打包后输出的文件详细;
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins:[
visualizer(),
]
})
npm run build
后,会在项目根目录生产stats.html
文件,可以查看打包文件的详细,打开后如下图:import viteCompression from 'vite-plugin-compression';
export default defineConfig({
plugins:[
// 打包压缩,主要是本地gzip,如果服务器配置压缩也可以
viteCompression(),
]
})
export default defineConfig({
build:{
assetsDir: './static', //dist目录中静态资源的目录名称
chunkSizeWarningLimit: 500, //chunk 大小警告的限制(以 kbs 为单位)。
rollupOptions: {
output: {
manualChunks: {
// 拆分代码,这个就是分包,配置完后自动按需加载,现在还比不上webpack的splitchunk,不过也能用了。
vue: ['vue'],
echarts: ['echarts'],
"element-plus": ['element-plus'],
},
},
},
},
})
export default defineConfig({
build:{
minify: 'terser',
terserOptions: {
compress: {
drop_console: true, //打包时删除console
drop_debugger: true, //打包时删除 debugger
pure_funcs: ['console.log'],//指定只删除console.log,其他console开头的命令保留
},
output: {
comments: true, // 去掉注释内容
},
},
},
})
vite启动快的原理,也导致了他在加载依赖项很多,很复杂的页面时,页面打开慢。因为他要进行一系列的动态分析/动态资源引入/动态编译。
这里需要配置:预构建的依赖项。
node_modules/.vite:存储缓存文件的目录。
此目录下会存储预打包的依赖项或 vite 生成的某些缓存文件,使用缓存可以提高性能。如需重新生成缓存文件,你可以使用 --force 命令行选项或手动删除目录。此选项的值可以是文件的绝对路径,也可以是以项目根目录为基准的相对路径。配置如下:
{
optimizeDeps: {
include: [
'vue',
'map-factory',
'element-plus/es',
'element-plus/es/components/form/style/index',
'element-plus/es/components/radio-group/style/index',
'element-plus/es/components/radio/style/index',
'element-plus/es/components/checkbox/style/index',
'element-plus/es/components/checkbox-group/style/index',
'element-plus/es/components/switch/style/index',
'element-plus/es/components/time-picker/style/index',
'element-plus/es/components/date-picker/style/index',
'element-plus/es/components/col/style/index',
'element-plus/es/components/form-item/style/index',
'element-plus/es/components/alert/style/index',
'element-plus/es/components/breadcrumb/style/index',
'element-plus/es/components/select/style/index',
'element-plus/es/components/input/style/index',
'element-plus/es/components/breadcrumb-item/style/index',
'element-plus/es/components/tag/style/index',
'element-plus/es/components/pagination/style/index',
'element-plus/es/components/table/style/index',
'element-plus/es/components/table-column/style/index',
'element-plus/es/components/card/style/index',
'element-plus/es/components/row/style/index',
'element-plus/es/components/button/style/index',
'element-plus/es/components/menu/style/index',
'element-plus/es/components/sub-menu/style/index',
'element-plus/es/components/menu-item/style/index',
'element-plus/es/components/option/style/index',
'@element-plus/icons-vue',
'pinia',
'axios',
'vue-request',
'vue-router',
'@vueuse/core',
],
}
}
可以把需要配置的文件,手动配置进optimizeDeps.include
清单。
也可以使用下面的插件自动来实现,下面实现原理是在首次构建的时候自动检测需要构建的清单,加入到package.json
文件中的vite.optimizeDeps
配置项中,然后下载启动的时候,会自动走node_modules/.vite
目录下的缓存。
npm i -D vite-plugin-optimize-persist vite-plugin-package-config
// vite.config.ts
import OptimizationPersist from 'vite-plugin-optimize-persist'
import PkgConfig from 'vite-plugin-package-config'
export default {
plugins: [
PkgConfig(),
OptimizationPersist()
]
}
npm i vite-plugin-mock mockjs -D
import { viteMockServe } from 'vite-plugin-mock';
plugin:{
viteMockServe({
// default
mockPath: 'mock',
// localEnabled: command === 'serve',
}),
}
查看更多数据模板:mockjs官网地址
在项目根目录新建mock
目录;新建index.ts文件,代码如下:
import { MockMethod } from 'vite-plugin-mock'
import { mock, Random } from 'mockjs'
var data = mock({
'list|10': [
{
goods: Random.cname(),
prices: 3000
}
]
})
export default [
{
url: '/api/get',
method: 'get',
response: ({ query }) => {
return {
code: 0,
data: data,
}
},
},
{
url: '/api/echart/data1',
method: 'get',
response: ({ query }) => {
return {
code: 0,
data: mock({
'record|50-60': [
{
titleEn: "@title",
titleCh: "@csentence",
description: "@cparagraph(10)",
displayName: '@cname',
userName: '@name',
address: '@city(true)',
id: '@increment(1)',
datetime: "@datetime(yyyy-MM-dd HH:mm:ss)",
thumb: "@image('200x100', '#50B347', '#FFF', 'Mock.js')",
url: "@url",
ip: "@ip",
email: "@email",
guid: "@guid",
uid: "@float",
float: '@float(60, 100)'
}
]
})
}
},
}
] as MockMethod[]
import axios from "axios";
async function fn(){
const {data}=await axios("/api/get");
console.log(data);
}
fn();
在根目录下新建.env.development
,.env.production
,写入代码如下:
//.env.development
VITE_BASE_API=/dev/api/get
//.env.production
VITE_BASE_API=/prod/api/get
使用:
console.log(import.meta.env);
设置mode:“production”,切换到生产环境时,显示如下:
上面的vite环境变量是在运行时生效,编译时生效需要使用npm参数传参,修改package.json
脚本配置;
"scripts": {
"dev": "node server http://10.000.000.11:32000 http://10.000.000.11/api/pi-sso/login",
},
取值:
console.log(process.argv);
asset/styles/theme_reset.scss
文件// styles/element/index.scss
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss'with ($colors: ('primary': ('base': #e69a18,
),
),
$button-font-size:("default":12px),
$table-padding: ('default': 7px 0),
$button-border-radius:('default': 4px),
$table:('header-text-color':"#333",
'header-bg-color':"#FAFAFA",
'text-color':"#515455"
),
$table-font-size:('default': 12px),
$pagination:("button-bg-color":#ffffff));
// 如果只是按需导入,则可以忽略以下内容。
// 如果你想导入所有样式:
@use "element-plus/theme-chalk/src/index.scss"as *;
需要确保项目中存在scss语法,不然preprocessorOptions
预加载不会触发。
这两种方式都行:
1.引入scss
文件被;
2.存在;
//vite.config.ts
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
"/icon":"./src/assets/"
},
},
css: {
preprocessorOptions: {
scss: {
charset: false,
additionalData: `@use "@/assets/styles/theme-reset.scss" as *;`,
},
},
},
})
这种方式不推荐,每次启动或加载页面时,都会对页面中引入的scss文件进行预打包,非常慢。所以推荐下面方案二来进行主题修改;
element-plus
css变量//theme-reset.scss
:root {
--el-color-primary: #1C3DD7;
--el-color-primary-light-3: #6077e3;
--el-color-primary-light-5: #8e9eeb;
--el-color-primary-light-7: #bbc5f3;
--el-color-primary-light-8: #d2d8f7;
--el-color-primary-light-9: #e8ecfb;
--el-color-primary-dark-2: #1631ac;
}
.el-table{
--el-table-header-text-color: #333 !important;
--el-table-header-bg-color: #FAFAFA !important;
--el-table-text-color: #515455 !important;
}
.el-button--default{
font-size: 12px
}
.el-table .el-table__cell{
padding: 7px 0;
}
.el-pagination.is-background {
.number:not(.is-active) {
border: 1px solid #ebeef5;
background-color: white;
}
.btn-prev,
.btn-next {
border: 1px solid #ebeef5;
background-color: white;
}
}
.el-table--default{
font-size: 12px;
}
.el-table:not(.el-table--border) {
.el-table__header-wrapper {
.el-table__header>thead>tr {
&>th:not(:first-child):not(.is-first-column)>div.cell {
border-left: 1px solid #ddd;
}
}
}
}
//在main.ts中引入
import './assets/styles/theme-reset.scss'
需要确保项目中存在scss语法,不然preprocessorOptions
预加载不会触发。
这两种方式都行:
1.引入scss
文件被;
2.存在;
//vite.config.ts
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
"/icon":"./src/assets/"
},
},
css: {
preprocessorOptions: {
scss: {
charset: false,
additionalData: `@use "@/assets/styles/theme-reset.scss" as *;`,
},
},
},
})
<template>
<div>
<el-button mb-2 @click="toggle">Switch Language</el-button>
<br />
<el-config-provider :locale="locale">
<el-table mb-1 :data="[]" />
<el-pagination :total="100" />
</el-config-provider>
</div>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
const language = ref('zh-cn')
const locale = computed(() => (language.value === 'zh-cn' ? zhCn : en))
const toggle = () => {
language.value = language.value === 'zh-cn' ? 'en' : 'zh-cn'
}
</script>