Vite 从入门到精通 | 插件系统
Vite 从入门到精通 | 插件系统
介绍
命名规范
rollup-plugin-xxx
vite-plugin-xxx
Vite 兼容 Rollup 钩子
服务启动时 (启动 server 时执行一次, 与文件更新无关)
options
buildStart
模块 (找到对应的文件,->加载->转变目标代码)
resolveId
load
transform
服务关闭时
buildEnd
closeBundle
modulePased 是不会被调用的, 防止 Vite 整体对代码执行 AST 解析
rollup 插件可以在 build中配置
// vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // 引入 jsx 依赖 import vueJsx from '@vitejs/plugin-vue-jsx' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ // 使用插件 vue(), vueJsx(),// 使用 vue-jsx ], build: { rollupOptions:{ plugins } } }) 复制代码
条件: rollup插件符合 vite 使用条件
没有使用 moduleParsed 钩子
在打包钩子和输出钩子之间没有很强的耦合
Vite 钩子
config
configResolved
configureServer
transformIndexHtml
handleHotUpdate
Vite 插件执行时机
Pre: 最先被执行的插件 , vite 使用 rolluo alias 插件之后就会按照plugin数组中定义的顺序的去执行
Normal: vite 核心插件执行之后, vite build 插件执行之前执行
post: vite build 插件 之后执行
实操
vite 项目创建 plugins/test-plugin.ts
// test-plugin.ts export default (enforce?: 'pre' | 'post') => { return { name: 'test', enforce, buildStart() { console.log("buildStart", enforce) }, resolveId(){ console.log('resolveId',enforce) } } } 复制代码
vite.config.js 配置
// vim vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // 引入 jsx 依赖 import vueJsx from '@vitejs/plugin-vue-jsx' import testPlugin from './plugins/test-plugin' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), vueJsx(), testPlugin('post'), testPlugin(), testPlugin('pre') ] }) 复制代码
输出结果
$ yarn dev yarn run v1.22.4 warning package.json: No license field $ vite buildStart pre buildStart undefined buildStart post vite v2.6.2 dev server running at: > Local: http://localhost:3000/ > Network: use `--host` to expose ready in 415ms. > Pre > normal > post 复制代码
Vite 插件 API (钩子)
config: return 一个新的 config 与 vite.config.js deepMerge
import { Plugin } from "vite"; export default (enforce?: "pre" | "post"): Plugin => { return { name: "test", // userConfig vite.config.js 中的配置项 config(userConfig) { // return 一个新的 config 与 vite.config.js deepMerge return { resolve: { alias: { "@img": '/src/img' } } } }, }; }; 复制代码
configResolved
import { Plugin } from "vite"; export default (enforce?: "pre" | "post"): Plugin => { return { name: "test", // config: 最终的 config configResolved(config){ // 打印 最终 config 中的 plugins console.log(config.plugins) } }; }; 复制代码
得到结果
[ { name: 'vite:pre-alias', }, { name: 'alias', }, { name: 'vite:modulepreload-polyfill', }, { name: 'vite:resolve', }, { name: 'vite:html', }, { name: 'vite:css', }, { name: 'vite:esbuild', }, { name: 'vite:json'}, { name: 'vite:wasm', }, { name: 'vite:worker', }, { name: 'vite:asset', }, { name: 'vite:vue', handleHotUpdate: [Function: handleHotUpdate], config: [Function: config], configResolved: [Function: configResolved], configureServer: [Function: configureServer], resolveId: [AsyncFunction: resolveId], load: [Function: load], transform: [Function: transform] }, { name: 'vite:vue-jsx', }, { name: 'test', }, { name: 'vite:define',}, { name: 'vite:css-post', }, { name: 'vite:client-inject',}, { name: 'vite:import-analysis', } ] 复制代码
configureServer
configureServer(server){ // 增加中间件 // 会在 Vite 中间件之前执行 server.middlewares.use((req,res,next)=> { if (req.url === "/test") { res.end("Hello Vite Plugin") } else { next() } }) } 复制代码
transformIndexHtml
transformIndexHtml(html) { // 在这里可以处理 index.html console.log(html) } 复制代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite App</title> </head> <body> <div id="app"><!--APP_HTML--></div> <script type="module" src="/src/main.js"></script> </body> </html> 复制代码
// 处理 html transformIndexHtml(html) { return html.replace('app','root') } 复制代码
handleHotUpdate
handleHotUpdate (ctx) { // 文件更新的所有信息 console.log(ctx) } 复制代码
作者:墩墩大魔王丶
链接:https://juejin.cn/post/7015862335076040717