首页 > 其他分享 >关于我写了一个vite插件那些事

关于我写了一个vite插件那些事

时间:2023-01-25 20:09:16浏览次数:57  
标签:插件 code return style 关于 import const vite

关于我写了一个vite插件那些事_Vue.js

为什么要写这个插件 解决了什么问题

在我们开发的过程中有​​开发模式​​​和​​生产模式​​​,那有些测试代码会在开发模式的时候使用,在生产环境要删掉,一般是手动删除,另一种就是判断环境变量,但是环境变量不好处理​​template​​​代码以及​​css​​代码,为此我写了一个插件将解决以上问题。

插件文档 插件下载地址 开源地址

npm 地址 ​​www.npmjs.com/package/vit…​​

插件下载地址

npm i vite-plugin-isdev

开源地址 ​​github.com/message163/…​​

插件用法

安装插件 npm i vite-plugin-isdev

vite.config.ts 引入

import comments from 'vite-plugin-isdev'
//plugins注册插件
plugins: [vue(),comments({
prefix:"xm",
debugger:false
})],
接受两个配置项
1.prefix 自定义前缀 默认​​dev​
2.debugger 调试该插件是否生效 生效可以看到​​<!--条件注释-->​​这一段代码 false则看不到默认false

使用条件注释语法

在template 里面使用 ​​<!--if-dev-->​​​ 被包裹的代码将会在生产环境删除 ​​<!--#end-dev-->​

在script tsx ts less 使用 ​​//#if-dev​​​ ​​//#end-dev​

tips 注意如果你设置了自定义前缀例如我上面设置了xm 那代码就应该是这样子 ​​<!--if-xm-->​​​ ​​<!--#end-xm-->​​​ 不设置默认为 ​​dev​

案例演示

开发环境dev

<template>
<div>
<div>扰乱</div>
<!--#if-xm-->
<div>dev1</div>
<div>dev2</div>
<!--#end-xm-->
</div>
<h2>
<!--#if-xm-->
<div>dev</div>
<!--#end-xm-->
</h2>
<xxxx></xxxx>
</template>

<script lang="ts" setup>
import random from "random-words"
import xxxx from './App'
console.log(123)
const a = random(5)
//#if-xm
var b = "__dev__"
//#end-xm
console.log('动次打次')
//#if-xm
console.log(a)
//#end-xm
</script>

<style lang="less">
//#if-xm
body{
background: red;
}
//#end-xm
</style>

<style scoped>
div{
color:white
}
</style>

编译之后的代码 ​​生产环境​

<template>
<div>
<div>扰乱</div>

</div>
<h2>

</h2>
<xxxx></xxxx>
</template>
<script setup lang='ts' >
import random from "random-words"
import xxxx from './App'
console.log(123)
const a = random(5)

console.log('动次打次')

</script>
<style lang='less'>

</style>
<style scoped >
div{
color:white
}
</style>

源码演示

import type { Plugin } from 'vite'
import { parse } from '@vue/compiler-sfc'//vue 处理sfc 的专用库
import type { SFCStyleBlock, SFCScriptBlock } from '@vue/compiler-sfc' //sfc 类型
import { Options, ScriptCode, StyleBlocks } from './type' //类型
let nodeEnv; //当前环境
export default function comments(options: Options = { prefix: "dev", debugger: false}): Plugin {

//处理template
const tempReg = new RegExp(`<!--#if-${options.prefix}-->(.*?)<!--#end-${options.prefix}-->`, 'igs');
const replaceTemplate = (code: string): string => {
return code.replace(tempReg, options.debugger ? '<!--条件注释template-->' : '');
}


const scriptOrStyleOrTsReg = new RegExp(`//#if-${options.prefix}(.*?)//#end-${options.prefix}`, 'igs');
//处理script
const replaceScript = (code: SFCScriptBlock): ScriptCode => {
return {
content: code.content.replace(scriptOrStyleOrTsReg, options.debugger ? '//条件注释js' : ''),
setup: code.setup,
lang: code.lang
}
}

//style 可以有多个
const replaceStyle = (codes: SFCStyleBlock[]): StyleBlocks[] => {
return codes.map(style => ({
content: style.content.replace(scriptOrStyleOrTsReg, options.debugger ? '//条件注释css' : ''),
scoped: style.scoped,
lang: style.lang,
attr: style.attrs
}))
}
//最后重新生成template
const AssemblyCode = (temp, script: ScriptCode, style: StyleBlocks[]) => {
let str = ``;
str += `<template>${temp}</template>\n`;
str += `<script ${script?.setup ? 'setup' : ''} ${script?.lang ? 'lang=' + `'${script.lang}'` : ''} >${script.content}</script>\n`;
style.forEach(style => {
str += `<style ${style?.scoped ? 'scoped' : ''} ${style?.lang ? 'lang=' + `'${style.lang}'` : ''}>${style.content}</style>\n`
})
console.log(str)
return str;
}

//处理ts
const replaceTsOrTsx = (code: string) => {
return code.replace(scriptOrStyleOrTsReg, options.debugger ? '//条件注释ts' : '')
}

return {
name: "vite-plugin-vue-comments",
enforce: "pre",
config(this, config, env) {
nodeEnv = env //获取环境
},
transform(code, id) {
//code 就是代码 id就是文件路径
if (/.vue$/.test(id)) {
const { descriptor } = parse(code)
const temp = descriptor.template?.content
const script = descriptor?.scriptSetup;
const styles = descriptor?.styles

if(temp && script && styles){
const tempCode = replaceTemplate(temp)
const scriptCode = replaceScript(script)
const styleCode = replaceStyle(styles)
const template = AssemblyCode(tempCode, scriptCode, styleCode)
return nodeEnv.mode == 'development' ? code : template
}else{
return code
}

}
//处理ts文件
if (/.ts$/.test(id)) {
return nodeEnv.mode == 'development' ? code : replaceTsOrTsx(code)
}
//处理tsx文件
if(/.tsx$/.test(id)){
return nodeEnv.mode == 'development' ? code : replaceTsOrTsx(code)
}

return code
}
}
}

标签:插件,code,return,style,关于,import,const,vite
From: https://blog.51cto.com/u_13463935/6022751

相关文章