当前位置: 首页 > news >正文

实现 Rollup 插件alias 并使用vitest提高开发效率

本篇文章是对 实现 Rollup 插件 alias | 使用 TypeScript 实现库的基本流程 | 使用单元测试提高开发效率 的总结。其中涉及到开发一个组件库的诸多知识点。

实现一个经常用的 rollup 插件 alias

首先执行npm init命令初始化一个package.json文件,因为插件使用了typescript作为类型校验,所以需要执行tsc --init命令去生成一个ts的配置文件tsconfig.json,执行完上述的命令之后安装项目依赖。

pnpm i rollup typescript @rollup/plugin-typescript tslib -D

先简单实现一下这个插件,插件要求导出一个方法并且返回一个对象

import { Plugin } from 'rollup'
export function alias(): Plugin {return {name: 'alias',resolveId(source: string, importer: string | undefined) {console.log('resolveId', source, importer)return source}}
}

接下来需要将index.ts编译成可执行的js文件,新增一个rollup配置文件rollup.config.js,指定输入以及输出

import { defineConfig } from 'rollup'
import typescript from "@rollup/plugin-typescript"export default defineConfig({input: './src/index.ts',output: {file: './dist/index.js',format: 'es'},plugins: [typescript({module:'esnext'})]
})

在package.json里面新增一条命令,并执行pnpm build

"scripts": {"build": "rollup -c rollup.config.js"},

一般执行到这里会有一个CommonJS和ES module的类型冲突,如图所示
在这里插入图片描述
我们只需要在package.json指定类型即可

"type": "module",

再次运行pnpm build可以发现在dist目录下会生成打包完成之后的index.js文件。

当别人去安装你的包的时候需要所指定执行的文件在哪,即修改package.json里面的main字段,由"main": "index.js"改为"main": "./dist/index.js"

使用开发的 alias 插件

新增一个example文件夹新增index.js、add.js写入相关的测试代码

import { add } from './utils/add.js'
console.log(add(1, 2))
export function add (a, b) {return a + b;
}

在example里面执行初始化并且新增rollup配置文件rollup.config.js,并且补充build命令,具体操作和上文类似

import { defineConfig } from 'rollup'
export default defineConfig({input: 'index.js',output: {file: './dist/index.js',format: 'es'}
})

通过在example目录下执行如下命令就可以使用我们开发的插件

// ../上层目录
pnpm i ../ -D

执行完之后会新增如下代码

"devDependencies": {"rollup": "^3.26.2","rollup-alias": "link:.." //  新增的依赖
}

在这里插入图片描述
example/rollup.config.js里面引入我们编写的 alias 插件,完整的代码如下

import { defineConfig } from 'rollup'
import { alias} from 'rollup-alias'export default defineConfig({input: 'index.js',output: {file: './dist/index.js',format: 'es'},plugins: [alias()]
})

在此执行pnpm build可以发现已经成功的打印出了log
在这里插入图片描述

为插件添加TS类型提示

首先补充插件的参数类型提示并且完善一下插件逻辑

import { Plugin } from 'rollup'
interface AliasOptions {entries: { [key: string]: string }
}export function alias(options: AliasOptions): Plugin {const { entries } = optionsreturn {name: 'alias',resolveId(source: string, importer: string | undefined) {console.log('resolveId', source, importer)const key = Object.keys(entries).find((e) => {return source.startsWith(e)})if (!key) return sourcereturn source.replace(key, entries[key]) + '.js'}}
}

执行build之后在我们会发给 alias 传参的时候并没有对应的参数类型提示
在这里插入图片描述
这里需要在tsconfig.json文件中开启 "declaration": true 功能,以及设置"outDir": "./dist"
package.json里面添加"types": "./dist/index.d.ts",执行完上述操作之后再次执行 pnpm build
在这里插入图片描述
在这里插入图片描述

补充单元测试

安装vitest,补充单元测试文件index.spec.ts,添加测试命令

pnpm i vitest -D
// index.spec.ts
import { describe, it, expect } from 'vitest'
import { alias } from '.'describe('alias', () => {it('should replace when match successful', () => {const aliasObj:any = alias({entries: {'@': './utils'}})expect(aliasObj.resolveId('@/add')).toBe('./utils/add.js')})it('should not replace when match fail', () => {const aliasObj: any = alias({entries: {'@': './utils'}})expect(aliasObj.resolveId('!/add')).toBe('!/add')})
})
"scripts": {"test": "vitest"},

我们需要在 build 的时候排除掉我们的测试文件可以在 tsconfig.json 补充如下代码 "exclude": ["./src/*.spec.ts"]
然后执行pnpm test 可以看到这里的测试用例是通过的也可以证明我们写的代码是没问题的。
在这里插入图片描述

entries 支持数组格式

这里直接贴完成之后的代码

import { Plugin } from 'rollup'interface AliasOptions {entries: { [key: string]: string } | { find: string, replacement: string }[]
}export function alias(options: AliasOptions): Plugin {const entries = normalizeEntries(options.entries)return {name: 'alias',resolveId(source: string, importer: string | undefined) {console.log('resolveId', source, importer)const entry = entries.find((e) => e.match(source))if (!entry) return sourcereturn entry.replace(source)}}
}function normalizeEntries(entries: AliasOptions["entries"]) {if (Array.isArray(entries)) {return entries.map(({ find, replacement }) => {return new Entry(find, replacement)})} else {return Object.keys(entries).map((key) => {return new Entry(key, entries[key])})}
}class Entry {constructor(private find: string, private replacement: string) { }match(filePath: string) {return filePath.startsWith(this.find)}replace(filePath: string) {return filePath.replace(this.find, this.replacement)}
}

以上就简单的实现了一个rollup插件开发的大致流程

http://www.lryc.cn/news/95098.html

相关文章:

  • 【DSL】ES+DSL 查询语法
  • Vue第三篇:最简单的vue购物车示例
  • MFC 基于数据库的管理系统
  • EfficientNet论文笔记
  • 系统学习Linux-SSH远程服务(二)
  • PyTorch训练RNN, GRU, LSTM:手写数字识别
  • 基于深度学习的高精度道路瑕疵检测系统(PyTorch+Pyside6+YOLOv5模型)
  • 【裸辞转行】是告别,也是新的开始
  • 了解交换机接口的链路类型(access、trunk、hybrid)
  • Android系统启动流程分析
  • 如何在Ubuntu上安装OpenneBula
  • 解决MySQL中分页查询时多页有重复数据,实际只有一条数据的问题
  • 【数据结构】时间复杂度---OJ练习题
  • 京东自动化功能之商品信息监控是否有库存
  • 【SwitchyOmega】SwitchyOmega 安装及使用
  • CentOS5678 repo源 地址 阿里云开源镜像站
  • 【LLM】Langchain使用[二](模型链)
  • 简单机器学习工程化过程
  • 【MongoDB】SpringBoot整合MongoDB
  • 关于游戏引擎(godot)对齐音乐bpm的技术
  • 【Go】实现一个代理Kerberos环境部分组件控制台的Web服务
  • Spring Security 6.x 系列【63】扩展篇之匿名认证
  • 供应链管理系统有哪些?
  • 如何在PADS Logic中查找器件
  • Android 生成pdf文件
  • Kafka 入门到起飞 - 生产者发送消息流程解析
  • 基于单片机智能台灯坐姿矫正器视力保护器的设计与实现
  • 欧姆龙以太网模块如何设置ip连接 Kepware opc步骤
  • PLEX如何搭建个人局域网的视频网站
  • java学习02