TS实现控制台实时快照日志的EventBus npm库

2024-05-30 13:06:53 浏览数 (2)

前言

本篇文章主要围绕如何正确的实现一个合格的npm包的教学。不会在具体的代码实现上花太多的时间。定位是偏授渔风格的,主要是让同学们知道如何该正确的处理代码实现以外的一些工作。有兴趣的小伙伴,可自行前往参考 monitor-event-emitter,麻雀虽小,五脏俱全。demo 在控制台可演示每次事件处理器执行时的日志信息。

背景

今年的目标之一是想深入学习下 Typescript

之前一直是以vue技术栈为主,去年公司开始用react antd typescript开发一个新后台。这对于一直以来习惯了javascript松散类型的我,是一个不小的挑战。很多时候,习惯性的用any去规避一切问题。现在回过头来看之前的一些业务代码,飘红一片,自己都禁不住的嫌弃

我不禁开始思考之前学习typescript的方式,大部分都是停留在的阶段。官方文档也好,技术文献也罢,看了一大堆,到最终自己实操的时候还是捉襟见肘

所以我决定痛改前非,准备尝试自己用 typescript 写一个库。正好,之前接触的业务代码中,经常能看到一个之前我司大牛用javascript写的事件触发器,所以准备着手推翻重新用typescript实现一遍。一来是为了加深对 typescript的理解和运用,二来是为了弥补很长时间以来,没有技术输出的空缺,同时寄希望于丰富下该库的功能

千好万好,不如动手撸一遍好

概述

由于涉猎的面比较广,对于一些老生常谈的东西,我会一笔带过。对于一些难以理解的点,可以参考 git commit 提交记录看我做了哪些工作,有兴趣的且不明白的地方可自行前往查阅官方文献。并且有些东西,我可能也是第一次接触,所以说的不对的地方,还请见谅。请给我多一些温柔

认真看完这篇文章后,我相信你一定能够有所收获,主要有以下几点

  • 大局观 知道从零开发一款属于自己的库的必经之路
  • 工程化思想 知道除了写功能代码,还有哪些是你必须要去关注和实现的工程化配置,它们将反哺你进行更加规范和标准的开发
  • 如何去写一个比较规范的文档
  • 了解一些有意思的技术点
    • excalidraw 手绘风格设计图,风格别具一格,程序猿必备
    • github action 大厂出品,必属精品。平时可以几行代码很多实现有意思的事,写博客必备
    • shields.io 让自己的库看起来更加正式的图标设计库

实现

第一步:创建项目

没什么好说的,先创建一个仓库,这里由于后面我们写的库要发布到npm官网上,让其他人可以自由的下载和使用,所以重点是起一个好名字,何为好名字,我的理解是有两点

  • 避免包名重复
  • 见名知意
代码语言:javascript复制
mkdir monitor-event-emitter // 创建文件夹
cd monitor-event-emitter // 进入文件夹

git init // 变成git 仓库
npm init -y // 初始化包,会生成一个package.json包配置文件

这里我刚开始的包名并不叫这个,发布了第一版本之后,随着我的库的核心功能(控制台实时打印日志快照)的实现,我才重新改了名字。为了就是让别人看到这个包名的时候,就能大概知道它是什么,有什么特点,有没有吸引我去下载使用的欲望

第二步:完善包配置文件

完善package.json文件,这个文件的意义非凡,它是别的人从了解你的包到能正确使用你的包的核心,挑几点说下

  • main库的入口文件,你配置了啥,最终别人安装使用该库的时候,就会去寻找该文件,避免冗余的文件路径引入
  • description库的描述文件,一句话,越精炼越好,突出库的亮点,吸引别人用它才是关键
  • types该库的声明文件,由于是typescript开发的包,别人用的时候,为什么会有代码提示和参数类型纠错功能,就是该文件提供的能力
  • files上传到 npm 上的文件包括哪些。没必要将你的所有文件和文件夹都推上去吧,里面的文件,能够让库正常使用且方便用户理解的前提下,越少越好
  • repository填写你的 github 项目仓库,这样别人在使用库的过程中出现问题了,或者就是想看看你的个人主页,至少能够找到入口
  • keywords该库类型的关键字,比如我的库主要是实现事件实时监听,我就用了这几个monitoreventemitter

第三步:工程配置

具体功能实现前的重要步骤,工程化领域不可或缺的部分,大致讲一下

  • husky在我们自己的仓库目录下,有一个叫.git的目录,里面放了一些脚本hook,为了方便在执行git的步骤过程中,前置或者后置执行一些额外的脚本,从而让我们可以干预它的流程,做一些有意思的事。比如pre-commit,也是最常用的脚本,主要用来在commit之前,做一些检查工作,比如你的提交信息是不是符合规范,别人是否能够根据你的提交信息窥见你本次提交的代码意图等。还有一个就是代码风格和质量校验,配合上eslintprettierstylelint简直不要太爽。你可以自己写一些脚本,比如我之前尝试自己用node实现了一个小功能,在sentry版本号同changelog版本号不匹配的情况下,拒绝本次提交的逻辑。但是更方便的是用一下现成的库husky
  • lint-staged一句话阐述就是,约束了husky脚本执行范围。只去校验我本次提交的内容,它的意义可能在你重构一个旧项目或者添加代码质量及风格校验时,能够得到更好的体现。毕竟,没有人想只提交一行代码,会把前人写的骨灰级代码的风格或者质量问题都暴露出来吧,虽然有自动修复的问题,但是仍然有的是编辑器不能自动帮我们修复的,尤其是有强迫症的老哥,估计心态瞬间爆炸
  • eslint主要用来管理代码质量问题。拜托你用let,用var我就给你报错!但是我也可以很细心的帮你纠正错误,修复不了的,还得劳烦你自己手动操作一下
  • prettier主要用来管理代码风格问题。约束大家开发风格统一,避免每个人的风格不统一而导致的合并冲突或报错问题,比如语句末尾要不要用分号,单个参数的函数需不需要有括号包裹、用双引号还是单引号。这个并没有好坏之分,自己团队商量着出一套大家都能接受的规范即可
  • stylelint主要用来管理样式代码的质量和风格问题。比如颜色应该用#000还是#000000亦或是black,还有就是样式属性的顺序问题等。虽然任意一种方式都不会影响页面的展示效果,但是从长远的维护角度来看,它是非常有意义的。而且就上面提到的顺序问题,也是解决性能优化的一个小点,因为它可以减少浏览器的重排或是重绘
  • commitlint约束提交信息规范,别整天只会来一句git commit -m 'update'了,你倒是告诉我,你update了什么呀?涉及到的范围有哪些呀?是重构还是删除?永远记住一句话,提交信息是给人看的,不是给神看的,没有哪个人能够通过你那微弱的update六个字母,窥见你的大脑思路。同时我也敢保证回过头的你自己再去看提交信息时,也是一脸懵逼

第四步:本库特点

到这里,我们已经可以正式着手实现我们的功能代码了。该库 核心文件 不算注释大概 400 行代码。实现了一个轻量级的事件监测触发器。个人认为,如果你熟悉ES6语法,还是很容易读懂的。具体的实现有兴趣的可以参考git commit提交记录,有更好的实现思路的可以给我提 issue 或者通过 pr 参与到项目中来。

每次当接收到一个事件执行命令且函数执行后,控制台就会实时的将日志以表格的形式打印出来,方便调试进行问题定位。实际效果请参考 demo 控制台。大致思路请参考该图:

TS实现控制台实时快照日志的EventBus npm库TS实现控制台实时快照日志的EventBus npm库

该库的主要特点有

  • 没有太多的约束。因为我的个人认知就是约束越少,使用起来越方便,就越愿意有人去用它和了解它。有一种普遍场景就是,虽然你写的东西很好用,但是约束太多了,实例化的时候,需要传递N个参数才能触及它的灵魂,那么我很大可能性会放弃使用它。记住一点,使用成本越高,弃用它的概率就越大。但是话说回来,很多库看起来使用方式非常自由,用起来没有太多的心智负担,那是因为它的很多逻辑被高内聚了。说直白点,就是开发者预判了你的一切使用习惯和场景,在库中实现的时候大部分都考虑到了
  • 设计之初考虑过用对象还是用map来维护我的事件中心,由于涉及到频繁的addremovecheck等逻辑。自认为选择用map更加合适,毕竟它自带的一些方法着实好用。这里我想表达的是,有很多种方式都能够实现功能,但是在设计之初,你就要有一定的大局观念。你应该考虑怎么样去更好,更方便,更直观的实现它,而不是实现一半了,发现自己输在了起跑线上,推翻从头再来简直头皮发麻
  • 支持实时监测能力。大致意思就是我们的业务代码中,可能有N处不起眼的地方,注册了N个事件监听器,也可能在N个角落中,默默的触发了它们。如果没有监测机制的话,很难弄情况它们执行的真实环境和情况,比如是什么类型的函数处理器?执行参数是什么?返回结果是啥?执行顺序是什么等。但是有了实时观测的能力后,你就可以很方便的在控制台中,实时观测到事件的触发,包括它们的入参、出参、类型。这样更加方便定位问题,做到有迹可循
  • 大部分能用表格或者图片呈现意图的事,就不要用苍白无力的文字去表达。因为这是个快节奏的社会,人们大多数没有耐心。所以我将复杂(这里的复杂是指map类型的数据,在控制台打印后看上去不太清晰)的map结构的事件执行快照,转换成数组模型,在控制台中以表格的形式呈现给大家,更加容易阅读和调试。同时支持mode参数,也可以让你自由的选择,你需要什么看到样的数据。目前支持defaultcool
  • 做了定制化的提示信息,根据你使用时传入的scope字段,实现在控制台中相关日志信息的分类展示。这样就可以做到方便地区分不同业务下出现的问题,从而快速定位及修改问题

然后就是不断的优化功能代码的实现,同时记得保持代码的易读性...

第五步:单元测试

当你认为你写的核心逻辑已经实现的时候,你就要去开展单元测试了。你要确保你的代码在别人使用之前,出现问题的概率降到最低。大部分的功能使用场景,你都需要通过单元自测的方式提前演练一遍。几乎所有优秀的库,都有单元自测模块。它的意义并不仅仅是发现错误并纠正,更有价值的是,它能测出一些你在实现时没有考虑到的地方,驱使你去重新完善业务逻辑。

  • jest单元测试框架。我之前也没用过,但是跟着文档尝试用了下,发现还是挺好理解和使用的。_这里有一些尴尬,不太会写异步的,虽然看了文档的用法,但是具体到结合我的一步场景时还是不太理解该怎么去写,有擅长的小伙伴可以帮忙完善下,提个 PR,磕头致谢_

第六步:写一份合格的README

当你觉得一切准备就绪准备发布npm时。且慢,最重要的一步来了。那就是写一个标准格式的README.md,什么叫标准,我提炼几点我的理解:

  • 大纲清晰,主要包含以下几部分
    • demo能用一个实际演示场景展示给别人你的库的特点,就不要用苍白无力的文字
    • why为什么用这个包。可以阐述下该包的用途,以及它与现存的一些同类型包的区别,重点解决了什么问题
    • install该如何才能安装你的包,支持哪些环境下使用
    • usage最基本的使用方式
    • api支持的 api 有哪些,举一些例子,让人知道该怎么用
    • config该包支持的参数有哪些,都有什么意义,类型是什么
    • todo接下来要实现的功能,以及记录下目前做的不好的点,后期待优化
  • 正式、重视起来。如果你认为你要做的事,是一件有意义的事。那么就去把它做好,且让它看起来像那么回事。
    • 一些小图标shields.io,比如你的库用了什么语言,单元测试覆盖率是多少,打包后的体积是多少。这些都是影响到别人是否愿意使用你的库的关键点,且看起来逼格满满。想要提示小伙伴的是,这里的图标,有的并不仅仅只是一个icon展示静态的数据。比如我的codecov图标中的单元自测覆盖率,是在提交代码时通过github action实时将测试覆盖率报告上报到第三方的,还是很有意思的。这里想安利大家去学习下github action,真的是太香了。我就是个前端小仔,你让我搞定一些太深的后台服务器相关的专业配置,比如 nginxjenkins配置,臣妾真的不一定能搞定呀。而学会了它,简直就是赛神仙,你想实现的一切都能通过简单的几行代码实现。比如部署网站,定时执行任务,拦截单元测试,有人提交issue的时候通知我等等,有利用github pages写博客的小伙伴,一定要去学着用它一下,难道当你只用执行一下push命令后,你的本地博客最新内容已经部署到线上为他人所知,它不香吗?

第七步:写博客推广

写博客,推广你的库。你要能够用干练通俗的语言,告诉大家你做了一件什么事,它有什么意义?给你带来了什么成长,同时又解决了什么问题。让大家能够从你的文章中,有所收获,同时也能吸引大家参与到你的项目中来

这里我想借用一个梗,那就是:

不写博客的程序猿不一定是不合格的程序猿,但是愿意去写博客的程序猿将来一定会成为一名合格的程序猿

落笔

原创不易,且赞且珍惜。看官至此,何不来一波mark三连。

monitor-event-emitter 源码

demo 效果演示

0 人点赞