0


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

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

实现一个经常用的 alias 插件

首先执行

npm init

命令初始化一个

package.json

文件,由于插件使用了

typescript

作为类型校验,需要执行

tsc --init

命令去生成一个ts的配置文件

tsconfig.json

,执行完上述的命令之后安装项目依赖。

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

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

// src/index.tsimport{ Plugin }from'rollup'exportfunctionalias(): Plugin {return{
    name:'alias',resolveId(source:string, importer:string|undefined){console.log('resolveId', source, importer)return source
    }}}

接下来需要将

index.ts

编译成可执行的

js

文件,新增一个配置文件

rollup.config.js

,指定输入以及输出:

// rollup.config.jsimport{ defineConfig }from'rollup'import typescript from"@rollup/plugin-typescript"exportdefaultdefineConfig({
  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

指定类型即可:

// 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

写入相关的测试代码:

// example/index.jsimport{ add }from'./utils/add.js'
console.log(add(1,2))// example/utils/add.jsexportfunctionadd(a, b){return a + b;}

example

里面新增配置文件

rollup.config.js

,并且补充

build

命令,具体操作和上文类似:

// example/rollup.config.jsimport{ defineConfig }from'rollup'exportdefaultdefineConfig({input:'index.js',// 入口文件output:{file:'./dist/index.js',// 输出文件format:'es'}})

通过在

example

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

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

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

// example/package.json"scripts":{"build":"rollup -c rollup.config.js"},"devDependencies":{"rollup":"^3.26.2","rollup-alias":"link:.."//  新增的依赖}

在这里插入图片描述

example/rollup.config.js

里面引入我们编写的

alias

插件,完整的代码如下:

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

在此执行

pnpm build

可以发现已经成功的打印出了

log

在这里插入图片描述

为插件添加TS类型提示

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

// rollup.config.jsimport{ Plugin }from'rollup'interfaceAliasOptions{entries:{[key: string]: string }}exportfunctionalias(options: AliasOptions): Plugin {const{ entries }= options
  return{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 source
      return source.replace(key, entries[key])+'.js'}}}

执行

build

之后在我们会发现

alias

插件在传参的时候并没有对应的参数类型提示:

在这里插入图片描述

  • 需要在根目录下的 tsconfig.json 文件中开启 "declaration": true 功能
  • 设置 "outDir": "./dist"
  • package.json 里面添加 "types": "./dist/index.d.ts"
  • 执行完上述操作之后再次执行 pnpm build

在这里插入图片描述

补充单元测试

安装

pnpm i vitest -D

,补充单元测试文件

index.spec.ts

,添加测试命令:

// src/index.spec.tsimport{ 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 支持数组格式

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

// rollup.config.jsimport{ Plugin }from'rollup'interfaceAliasOptions{entries:{[key: string]: string }|{find: string,replacement: string }[]}exportfunctionalias(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 source

      return entry.replace(source)}}}functionnormalizeEntries(entries: AliasOptions["entries"]){if(Array.isArray(entries)){return entries.map(({ find, replacement })=>{returnnewEntry(find, replacement)})}else{return Object.keys(entries).map((key)=>{returnnewEntry(key, entries[key])})}}classEntry{constructor(privatefind: string,privatereplacement: string){}match(filePath: string){return filePath.startsWith(this.find)}replace(filePath: string){return filePath.replace(this.find,this.replacement)}}

以上就简单的实现了一个

rollup

插件开发的大致流程。

标签: rollup vitest

本文转载自: https://blog.csdn.net/AXBNMD/article/details/131738036
版权归原作者 Avicli 所有, 如有侵权,请联系我们删除。

“实现 Rollup 插件alias 并使用vitest提高开发效率”的评论:

还没有评论