今日
身为中国人,恐怕没有不知道的,今天是七夕节,属于我们自己的情人节!
在读这篇文章的朋友,如果你已经有了另一半,那么恭喜你,祝愿你们度过一个浪漫温馨的七夕节。
没有的话,还是好好学习,再去赢取你心目中的白富美吧~
前言
我们在上一篇文章主要讲了vite
日常开发的几个基础插件,这篇文章讲下另外几个常用的进阶插件
一、vite-plugin-windicss
1.说明
在Vite上单独使用Tailwind
时,渲染速度很慢。
vite-plugin-windicss
比Tailwind
快20到100倍。
2.安装
yarn add vite-plugin-windicss --dev
复制代码
3.创建Windicss
配置文件
(1)windicss的配置
(2)tailwind的配置
tailwind.config.ts
:
import lineClamp from 'windicss/plugin/line-clamp';
import colors from 'windicss/colors';
import { defineConfig } from 'vite-plugin-windicss';
import { primaryColor } from './build/config/themeConfig';
export default defineConfig({
darkMode: 'class',
plugins: [lineClamp, createEnterPlugin()],
theme: {
extend: {
colors: {
...colors,
primary: primaryColor,
},
screens: {
sm: '576px',
md: '768px',
lg: '992px',
xl: '1200px',
'2xl': '1600px',
},
},
},
});
/**
* 用于元素显示时的动画
* @param maxOutput 输出越大,生成的css体积越大
*/
function createEnterPlugin(maxOutput = 10) {
const createCss = (index: number, d = 'x') => {
const upd = d.toUpperCase();
return {
[`*> .enter-${d}:nth-child(${index})`]: {
transform: `translate${upd}(50px)`,
},
[`*> .-enter-${d}:nth-child(${index})`]: {
transform: `translate${upd}(-50px)`,
},
[`* > .enter-${d}:nth-child(${index}),* > .-enter-${d}:nth-child(${index})`]: {
'z-index': `${10 - index}`,
opacity: '0',
animation: `enter-${d}-animation 0.4s ease-in-out 0.3s`,
'animation-fill-mode': 'forwards',
'animation-delay': `${(index * 1) / 10}s`,
},
};
};
const handler = ({ addBase }) => {
const addRawCss = {};
for (let index = 1; index < maxOutput; index++) {
Object.assign(addRawCss, {
...createCss(index, 'x'),
...createCss(index, 'y'),
});
}
addBase({
...addRawCss,
[`@keyframes enter-x-animation`]: {
to: {
opacity: '1',
transform: 'translateX(0)',
},
},
[`@keyframes enter-y-animation`]: {
to: {
opacity: '1',
transform: 'translateY(0)',
},
},
});
};
return { handler };
}
复制代码
3.创建配置文件
build/vite/plugin/windicss.ts
:
import type { Plugin } from 'vite';
import windiCSS from 'vite-plugin-windicss';
export function configWindiCssPlugin(): Plugin[] {
return windiCSS({
safelist: 'no-select',
preflight: {
enableAll: true,
},
});
}
复制代码
4.应用配置
build/vite/plugin/index.ts
:
// ...
import { configWindiCssPlugin } from './windicss';
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
// ...
// vite-plugin-windicss
vitePlugins.push(configWindiCssPlugin());
return vitePlugins;
}
复制代码
5.导入样式
src/main.ts
:
// ...
import '@virtual/windi.css';
// ...
复制代码
二、vite-plugin-mock
1.说明
根据我自己的试验:
localEnabled
用来控制mock开发环境是否启动。- 如果生产环境想要使用
mock
,只有prodEnabled
为true,injectCode
注入指定代码时才会生效。
2.安装 mockjs
和 vite-plugin-mock
# node version: >=12.0.0
# vite version: >=2.0.0
yarn add mockjs -S
yarn add vite-plugin-mock -D
# 或者:
npm install mockjs -S
npm install vite-plugin-mock -D
复制代码
3.编写Mock用例
这里直接将根目录下的mock
目录拷贝出来就行。
mock/_util.ts
:里面封装的是数据请求结构类型。mock\_createProductionServer.ts
:用于配置生产环境动态Mock的js文件,文档中有说。其他的
:都是Mock用例。每一个js
、ts
。都要默认导出一个MockMethod
类型的数组。每一项MockMethod
就是拦截的一个方法。MockMethod
的response
对应方法的return
将会被Mock
实例处理。也就是说,你可以在return
的对象中使用Mock规则
不过
_createProductionServer.ts
中使用了Glob 导入。
在根目录下新建两个文件:
mock/demo/user.ts
mock/_createMockServer.ts
user.ts
:
import { MockMethod } from 'vite-plugin-mock';
export default [
// mock userInfo
{
url: '/api/v1/userInfo',
timeout: 200,
method: 'get',
response: ({ body }) => {
console.log('body', body);
return {
code: 0,
message: 'OK',
data: {
userName: 'admin',
headThumb: 'http://xxx/avatars/profile.gif',
},
};
},
},
] as MockMethod[];
复制代码
_createMockServer.ts
:
经试验,这个mock文件名称最好这样命名,否则会有不可预料的错误
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
const modules = import.meta.globEager('./**/*.ts');
const mockModules: any[] = [];
Object.keys(modules).forEach((key) => {
if (key.includes('/_')) {
return;
}
mockModules.push(...modules[key].default);
});
/**
* 在生产环境中使用。 需要手动导入所有模块
*/
export function setupProdMockServer() {
createProdMockServer(mockModules);
}
复制代码
⚠️ 注意:此时 import.meta.globEager
可能会有类型错误提示:
修改 tsconfig.json
配置的 include
属性就正常了:
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"mock/**/*.ts" //++ 新增
]
复制代码
4.配置使用 vite-plugin-mock
build/vite/plugin/mock.ts
:
import { viteMockServe } from 'vite-plugin-mock';
export function configMockPlugin(isBuild: boolean) {
return viteMockServe({
// eslint-disable-next-line no-useless-escape
ignore: /^\_/,
mockPath: 'mock',
localEnabled: !isBuild,
prodEnabled: isBuild,
injectCode: `
import { setupProdMockServer } from '../mock/_createMockServer';
setupProdMockServer();
`,
});
}
复制代码
5.配置进Vite
build/vite/plugin/index.ts
:
// ...
import { configMockPlugin } from './mock';
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, pkg: any) {
// ...
const {
VITE_USE_MOCK: shouldUseMock,
} = viteEnv;
// vite-plugin-mock
shouldUseMock && vitePlugins.push(configMockPlugin(isBuild));
return vitePlugins;
}
复制代码
6. 测试 mock
在 src
目录下新增:
api/user/index.ts
import http from '@/utils/http/index';
enum UserAPI {
getUserInfo = '/api/v1/userInfo',
}
/**
* 获取用户信息
*/
export async function getUserInfo(): Promise<any> {
return http.get({
url: UserAPI.getUserInfo,
});
}
复制代码
src/views/demo/index.vue:
<template>
<div>
<div>demo</div>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, reactive } from 'vue';
import { getUserInfo as getUserInfoApi } from '@/api/user/index';
export default defineComponent({
setup() {
// ------------------------------------------ reactive ------------------------------------------
const getUserInfo = async () => {
try {
const result = await getUserInfoApi();
if (result && result.code === 0 && result.data) {
console.log(result.data);
}
} catch (error) {
console.log('error', error);
}
};
onMounted(() => {
getUserInfo();
});
return {
userInfo,
};
},
});
</script>
<style lang="scss">
</style>
复制代码
终端效果如下:
说明 mock
是成功的
三、vite-plugin-purge-icons
1.说明
这个插件是可以让我们很方便高效的使用Iconify中所有的图标。
这里要讲的是Iconify
各个版本插件的区别:
- Vue3版Iconify插件:使用时需要安装指定库的图标,然后静态引用。每一次引用都会产生一次
http
请求。 - PurgeIcons:将我们所使用的
Iconify
图标都已html
的dom
节点形式保存在html
中,这样我们就可以不发送http
请求就可以使用图标了。 - vite-plugin-purge-icons:就是
Vite
版的PurgeIcons
。
2.安装
yarn add @iconify/iconify
yarn add vite-plugin-purge-icons @iconify/json --dev
复制代码
3.配置Vite
build/vite/plugin/index.ts
:
// ...
import PurgeIcons from 'vite-plugin-purge-icons';
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
// ...
// vite-plugin-purge-icons
vitePlugins.push(PurgeIcons({
/* PurgeIcons Options */
}));
// ...
return vitePlugins;
}
复制代码
4.main
中导入
src/main.ts
:
import { createApp } from 'vue'
import App from './App.vue'
// 导入 icons
import '@purge-icons/generated'
createApp(App).mount('#app')
复制代码
六、rollup-plugin-visualizer
1.说明
- rollup-plugin-visualizer:依赖分析插件。
- cross-env:命令行配置环境变量
2.安装visualizer
yarn add rollup-plugin-visualizer @types/rollup-plugin-visualizer --dev
复制代码
3.配置插件
build/vite/plugin/visualizer.ts
:
/**
* 包文件体积分析
*/
import visualizer from 'rollup-plugin-visualizer';
import { isReportMode } from '../../utils';
import type { Plugin } from 'vite';
export function configVisualizerConfig() {
if (isReportMode()) {
return visualizer({
filename: './node_modules/.cache/visualizer/stats.html',
open: true,
gzipSize: true,
brotliSize: true,
}) as Plugin;
}
return [];
}
复制代码
4.配置Vite
build/vite/plugin/index.ts
:
// ...
import { configVisualizerConfig } from './visualizer';
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean, pkg: any) {
// ...
// rollup-plugin-visualizer
vitePlugins.push(configVisualizerConfig());
return vitePlugins;
}
复制代码
5.安装cross-env
yarn add cross-env --dev
复制代码
6.添加脚本
package.json
:
{
// ...
"scripts": {
// ...
"report": "cross-env REPORT=true npm run build"
// ...
}
// ...
}
复制代码
7. 执行脚本查看报告
npm run report
复制代码
生成报告后会自动打开浏览器,就像下面这样 ??
很明显可以看出来哪些依赖包占用体积最大,接下来就可以根据项目情况来优化下项目体积啦~