昨天用了一天时间完整开发了一个vite插件,其实这个插件我大概一年以前就写了第一版,然后经历了辞职,减肥之后,最近突然看见github里有几个issue,这才准备把它重写一下。
我先把仓库放这里,懒得看文章的可以直接移步github:
第一步:寻找轮子
为什么要开发这个插件?这个插件有没有现成的? 每次造轮子之前一定要记得先寻找轮子,不要做重复劳动。
为什么要开发这个插件?
由于之前我的项目都是在nginx上部署了,公司并没有什么CI,所以每次都要登陆堡垒机,打开xshell,上传文件,移动文件,修改nginx配置,然后就是部署成功了。还忘了说,服务器设置了权限,只有一个文件夹允许直接上传,其他文件夹是不可以的,这也是为什么每次上传完还得移动
在这个步骤里,能够优化的不多,上传文件就是一个方面。如果能够打成一个压缩包,既能加速上传,也方便移动文件然后再解压缩。
这个插件有没有现成的?
当时我在webpack的时候,曾写过一个类似的打包插件,因此当vite出现之后,我也一直想把它迁移到vite上,那时候vite的插件并不多,也没有类似的。
第二步:整理需求
这一步其实是在思考逻辑,正所谓意在笔先,胸有成竹,先把插件的逻辑考虑清楚,才能更好的编写代码。其实我一直认为,软件工程里最简单的一步就是写代码,最复杂的一步就是设计代码
话说回来,我这个插件需要实现哪些功能,参考我上面说的,就是要在vite打包之后,把打包出来的文件压缩为zip格式,因此我就有一个简单的逻辑
但是这样比较粗放的,还有很多细节需要考虑。比如说压缩哪个文件夹,这个跟vite配置有关,也和用户自己的配置有关。压缩完成后的文件名,这个也应该让用户自己设置。所以我们需要再增加一个 步骤,读取vite配置
第三步:新建项目,安装依赖
这一块其实没什么好讲的,每个前端其实都知道,只需要注意一下,这里需要新建一个空的node项目,而非什么vue,react就行了,操作也很简单
先生成一个package.json文件
npm init -y
然后新建一些基础配置,比如src目录放源码。之前那个插件是用js写的,干脆这次换成ts,然后用rollup打包,这也是我第一次用rollup,于是自然而然就有这些基础依赖
json
{
"dependencies": {
"@types/node": "^20.10.6",
"jszip": "^3.5.0",
"rimraf": "^5.0.5",
"rollup": "^4.9.2",
"rollup-plugin-typescript2": "^0.36.0",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"vite": "^5.0.10"
}
}
其中,rollup
自然不用说
@types/node
是写node需要用的,因为你压缩文件涉及到了文件的读写,自然需要用到node的fs模块。
rimraf
是用来删除文件夹的
安装vite
也只是用了一下它内部的ts声明文件,vite打包node项目还是有点小问题。
jszip
则是用了生成压缩文件的,这是在npm找的下载量最大那个。
第四步:编码
首先我们新建一个文件src/index.ts
,这里我给出一个基本模版
typescript
import {Plugin} from 'vite'
export default function MyPlugin(): Plugin {
return {
name: 'vite-plugin-test',
closeBundle() {
}
}
}
使用的时候和其他插件一样
typescript
//vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import MyPlugin from 'vite-plugin-xxx'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(),MyPlugin()],
})
vite中的插件本质上就是一个函数,然后return出一个配置项,这样能更方便让插件执行相应代码,更加灵活。 需要注意点是,由于vite本质上rollup+esbuild,因此它会有rollup和vite的钩子周期,因此你可能还需要rollup的一些文档。
rollup文档:rollupjs.org/plugin-deve...
vite文档:cn.vitejs.dev/guide/api-p...
第五步 rollup打包配置
这一块我其实也不是很懂,在网上查询了一些资料之后,我自己写了这样一个配置,但是这个配置无法准确的生成dts,所以我用了一点hacks。
php
// rollup.config.ts
import {defineConfig} from 'rollup';
import typescript from "rollup-plugin-typescript2";
const name = 'vite-plugin-test'
export default defineConfig({
input: 'src/index.ts',
output: [
{
file: `dist/${name}.js`,
format: 'es',
},
],
plugins: [
typescript({
tsconfig: 'tsconfig.json',
tsconfigOverride: { //这里需要设置不产生dts
compilerOptions: {
declaration: false,
declarationDir: null,
composite: false
}
},
// 保留 declaration 选项
declaration: false,
}),
],
external: ['jszip', 'node:fs', 'node:path']
})
rollup不产生dts文件,通过tsc去生成,因此你需要一个tsconfig,这块我是用gpt生成的
json
{
"compilerOptions": {
"target": "es6",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationDir": "./types",
"rootDir": "src"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"dist"
]
}
因此,我们可以用一条命令去生成dts rimraf -rf ./types && mkdir ./types && tsc -p ./tsconfig.json
第五步:发布
当你做完编码之后,你就可以发布npm了,具体过程你们可以看到很多文章,我只说一下我踩过的坑
没有设置入口文件
需要在package.json里设置main
不自动安装依赖
不要把依赖放到devDependencies
里