开发一个 vite-plugin-terminal 插件

介绍
插件功能:在开发时,将服务器的 url 转换为二维码,实现手机扫码就能访问的功能。
写在项目里
插件实现:plugin/index.ts
ts
import {
Plugin,
ResolvedConfig,
ResolvedServerOptions,
ServerOptions
} from 'vite'
import qrcode from 'qrcode-terminal'
import { getAllHost } from './util.js'
export interface PluginOption {
content?: string;
small?: boolean;
}
import chalk from 'chalk'
const allHost = getAllHost()
export function vitePluginQrcodeTerminal(params: PluginOption = {}): Plugin {
let config: ResolvedConfig
return {
name: 'vite-plugin-qrcode-terminal',
apply: 'serve',
enforce: 'post',
configResolved(resolvedConfig) {
config = resolvedConfig
},
configureServer(server) {
server.middlewares.use((req, res, next) => {
createQrcode(params, config.server);
next();
});
}
}
}
function createQrcode(
params: PluginOption,
server: ServerOptions & ResolvedServerOptions
) {
const { small } = params;
const content = getInputContent(params, server);
const urls = renderUrl(content, server);
urls.forEach((each) => {
qrcode.generate(each, { small: small ?? true }, (qrcode) => {
console.log(('------------qrcode------------'));
console.log(`${chalk.green('[url]')} ${chalk.blue(each)} `);
console.log(qrcode);
});
});
}
function getInputContent(
params: PluginOption,
server: ServerOptions & ResolvedServerOptions
): string[] {
const { content } = params;
const { host } = server;
let input: string[] = [];
if (content) {
input = [content];
} else {
if (typeof host === 'boolean') {
input = host ? allHost : ['localhost'];
}
if (typeof host === 'string') {
input = host === '0.0.0.0' ? allHost : [host];
}
if (host === undefined) {
input = ['localhost'];
}
}
return input;
}
function renderUrl(
input: string[],
server: ServerOptions & ResolvedServerOptions
) {
const { https, port, open } = server;
const protocol = https ? 'https://' : 'http://';
const postUrl = typeof open === 'string' ? open : '';
return input.map((item) => {
return postUrl.startsWith('/')
? `${protocol}${item}:${port}${postUrl}`
: `${protocol}${item}:${port}/${postUrl}`;
});
}工具函数:
ts
import os from 'os';
const network = os.networkInterfaces();
export function getAllHost() {
const keys = Object.keys(network);
return keys.reduce<string[]>((prev, curr) => {
const element = network[curr] ?? [];
const IPv4Item = element?.filter((item) => item.family === 'IPv4');
prev.push(IPv4Item?.[0]?.address);
return prev;
}, []);
}作为插件上传到 npm 包
下载依赖:
js
pnpm i tsup typescript vite -D创建 tsconfig.json 文件:
shell
tsc --init执行脚本:
json
{
"build": "rm -rf dist/ && tsup src/main.ts --dts --no-splitting"
}修改 package.json:
json
{
"types": "dist/main.d.ts",
"main": "dist/main.js",
"files": [
"dist"
],
}最后,可以使用 pnpm link <dir> 在本地进行调试。如果无误,再 npm publish 上传到 npm 上。