# vite-plugin-lesson **Repository Path**: qinchaobin/vite-plugin-lesson ## Basic Information - **Project Name**: vite-plugin-lesson - **Description**: vite插件学习demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-07-25 - **Last Updated**: 2024-08-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Vite插件 vite插件存在的主要目的是为了在开发/构建阶段,执行vite配置前/后要做的事情,开发者以函数的形式将编写好的插件在vite的plugins注入并执行插件函数。除了vite独有的钩子外,还继承了Rollup的钩子。 **Vite的独有钩子** - config:解析vite配置前调用; - configResolved: 解析vite配置后调用; - transformIndexHtml:转换index.html入口文件钩子(调用html模板之前钩子) - configureServer:开发环境服务器钩子,主要用于给connet(node服务器)添加自定义中间件(很少使用) - configurePreviewServer:预览服务器钩子,与 configureServer 钩子基本一致。 **Rollup钩子** - closeBundle:打包结束并生成结果文件后执行的钩子 - ... Rollup其实有很多钩子,目前个人用到的就只有 closeBundle,更多请查看 [Rollup文档](https://cn.rollupjs.org/plugin-development/#build-hooks) 。 ## config钩子使用场景 主要使用在解析vite配置之前进行修改(覆盖)用户配置,例如 用户的配置 vite.config.ts ```js import { defineConfig } from 'vite' import myPlugin from './vite-plugin/myPlugin' export default defineConfig(({mode}: {mode: 'development' | 'production'}) => { return { envDir: './', resolve: { alias: { '@/assets': './src/assets' } }, plugins: [myPlugin()] } }) ``` 自定义插件 myPlugin.ts ```js export default function myPlugin () { return { name: 'myPlugin', // 插件名称 config: (config, env) => { // config 用户配置 // env.mode 运行的模式 production / development // env.command 运行的命令 pnpm dev (server)、pnpm build (build) // 返回 Vite 及 Rollup 参数配置 return { envDir: './env', // envDir为vite里的配置,会覆盖用户的envDir resolve: { // 会覆盖用户的resolve.alias alias: { '~/assets': './src/assets' } } } } } } ``` ## transformIndexHtml钩子使用场景 该钩子为转换入口模板专用的,主要目的为在编译html模板入口html前进行修改其内容。例如通过配置修改标题: vite.config.ts ```js import { defineConfig } from 'vite' import vitePluginHtmlTitle from './vite-plugin/vite-plugin-html-title' // 插件方法 export default defineConfig(({mode}: {mode: 'development' | 'production'}) => { return { plugins: [ vitePluginHtmlTitle({title: '我是最新标题'}) ] } }) ``` vite-plugin-html-title.ts ```js export default ({ title }: { title: string }) => { // 配置网站标题插件 return { name: 'vitePluginHtmlTitle', transformIndexHtml(html: string) { return html.replace(/<%= title %>/g, title) } } } ``` ## closeBundle钩子使用场景 该钩子为Rollup中的钩子,也是可以写入pulgin中,closeBundle主要是在打包并输出结果文件后执行的钩子。此时我们可以对打包后的文件进行压缩成zip文件方便后续上传至服务器,无需手动压缩操作。 vite.config.ts ```js import { defineConfig, loadEnv } from 'vite' import vitePluginZip from './vite-plugin/vite-plugin-zip' export default defineConfig(({mode}: {mode: 'development' | 'production'}) => { // 需要将mode提供给打包插件,只允许 production 环境下打包,否则修改配置文件时也会触发打包的插件。 return { plugins: [vitePluginZip(mode)] } }) ``` vite-plugin-zip.ts ```js import { Plugin } from 'vite' import path from 'node:path' import compressing from 'compressing' import chalk from 'chalk' // 获取日期 function getLocalDate() { const date = new Date() const Y = date.getFullYear() const M = (date.getMonth() + 1).toString().padStart(2, '0') const D = date.getDate().toString().padStart(2, '0') const H = date.getHours().toString().padStart(2, '0') const Min = date.getMinutes().toString().padStart(2, '0') return Y + M + D + H + Min } // 压缩目录 const folderPath = './dist' function zip(src: string, dest: string) { return new Promise((resolve, reject) => { compressing.zip .compressDir(src, dest) .then(() => { resolve('压缩成功, 目录为:') }) .catch((err) => { reject(err) }) }) } // 插件方法 export default function vitePluginZip({mode}:{mode: 'development' | 'production'}): Plugin { return { name: 'vitePluginZip', closeBundle() { if (mode === 'production') { const outputName = `dist_${getLocalDate()}.zip` // 重命名带日期 const outputPath = path.join(process.cwd(), `./${outputName}`) zip(folderPath, outputPath).then((res) => { console.log(chalk.green('压缩成功' + outputPath)) }) } else { console.log(chalk.yellow('压缩功能仅在生产环境下生效')) } } } } ```