持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
2.5 vite 插件
2.5.1 EJS 标签
vite-plugin-html 是一个针对 index.html,提供压缩和基于 ejs 模板功能的 vite 插件。通过搭配 .env 文件,可以在开发或构建项目时,对 index.html 注入动态数据,例如替换网站标题。
安装
pnpm install --save-dev vite-plugin-html
在 vite.config.js 添加如下配置。VITE_GLOB_APP_TITLE 在全局环境变量中配置。
import { createHtmlPlugin } from 'vite-plugin-html'
...
plugins: [
createHtmlPlugin({
minify: isBuild,
inject: {
data: {
title: VITE_GLOB_APP_TITLE,
},
// 将 app.js 文件注入到模板html中
tags: isBuild
? [
{
tag: 'script',
attrs: {
src: '<path/app.js>',
},
},
]
: [],
},
}),
],
...
在 index.html文件中添加代码, 就可以动态的注入网站标题啦:
<title><%= title %></title>
tags 选项,可以向 html 文件中注入一些 js 文件。
2.5.2 Tsx 支持
@vitejs/plugin-vue-jsx 提供了 tsx 支持,为我们在模板文件中写 tsx 代码提供了可能。
安装依赖:
pnpm install --save-dev @vitejs/plugin-vue-jsx
在 vite.config.js 中添加配置
...
plugins: [
vueJsx(),
],
...
2.5.3 配置自定义 svg
vite-plugin-svg-icon 用于生成 svg 雪碧图,方便在项目中使用 .svg 文件。 按照文档配置好后,搭配阿里巴巴矢量图标库使用,只需把下载好的 svg 文件丢到指定目录,然后就可以项目中愉快的使用了。
安装依赖:
npm i vite-plugin-svg-icons -D
在 vite.config.ts 文件中做如下配置:
import path from 'path';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; // 版本不同引入方式不同
export default defineConfig({
...
plugins: [
...
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]'
})
]
});
创建文件夹,并将svg 文件放到此处,如图:
在components中创建 SvgIcon.vue :
<template>
<svg :style="getStyle" aria-hidden="true" :class="[$attrs.class]" class="insudio-svg-icon">
<use :href="symbolId" />
</svg>
</template>
<script lang="ts">
import type { CSSProperties } from 'vue'
import { defineComponent, computed } from 'vue'
export default defineComponent({
name: 'SvgIcon',
props: {
prefix: {
type: String,
default: 'icon',
},
name: {
type: String,
required: true,
},
size: {
type: [Number, String],
default: 16,
},
},
setup(props) {
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
const getStyle = computed((): CSSProperties => {
const { size } = props
let s = `${size}`
s = `${s.replace('px', '')}px`
return {
width: s,
height: s,
}
})
return { symbolId, getStyle }
},
})
</script>
<style>
.insudio-svg-icon {
display: inline-block;
overflow: hidden;
vertical-align: -0.2em;
fill: currentColor;
}
</style>
在main.ts 引入:
// 注册所有图标
import 'virtual:svg-icons-register'; // 引入注册脚本
import SvgIcon from '@/components/SvgIcon.vue';
app.component('SvgIcon', SvgIcon);
使用:
// 自定义的svg图标
<svg-icon name="iconName" size="24"></svg-icon>
2.5.4 配置使用 windicss
安装依赖:
pnpm install vite-plugin-windicss -D
在 vite.config.ts 文件中做如下配置:
import windiCSS from 'vite-plugin-windicss'
export default defineConfig({
...
plugins: [
...
windiCSS(),
]
});
在根目录创建 windi.config.ts :
import { defineConfig } from 'vite-plugin-windicss'
export default defineConfig({
darkMode: 'class',
plugins: [createEnterPlugin()],
preflight: false,
theme: {
extend: {
zIndex: {
'-1': '-1',
},
screens: {
sm: '576px',
md: '768px',
lg: '992px',
xl: '1200px',
'2xl': '1600px',
},
},
},
})
/**
* Used for animation when the element is displayed.
* @param maxOutput The larger the maxOutput output, the larger the generated css volume.
*/
function createEnterPlugin(maxOutput = 6) {
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)',
},
},
// h1: { fontSize: '2rem' },
// h2: { fontSize: '1.5rem' },
// h3: { fontSize: '1.17rem' },
})
}
return { handler }
}