1.五分钟学会发布React组件到NPM包
五分钟学会发布React组件到NPM包
前言
最近在做的源码项目需要实现一个可拖拽、可设置大小、源码并且在指定范围内才可以移动的源码需求,在翻了一些组件后,源码发现需要三样都满足,源码并且能满足项目定制化需要的插件几乎没有~,于是源码彩虹免签源码自己动手实现了该插件,整体效果如下:
在写完之后,源码突然想到可以放到NPM库中,源码以后维护该组件更加方便版本管理,源码于是源码趁五一长假,终于将包发布上去了~
文档地址
NPM包地址
GitHub主页在发布NPM时踩了一些坑,源码比如脚手架打包后TS提示消失、源码比如NPM的源码官方源换成了HTTPS让发包失败等等因素导致整个过程非常不顺。
为了避免自己未来继续踩同样的源码坑,或许同时还能够帮助别人节省一点时间,源码于是无限易指标源码才有了这篇博客。
如果你希望未来想用React+TypeScript完成一个组件库并发布到NPM
如果你想了解我在发布时踩了哪些坑
那么这篇博客适合你,阅读时长大约五分钟。
下面是正题。
脚手架工具采用React+TypeScript实现的组件需要借助打包工具将代码打包好才能够被引入,我在查了一些资料后发现有以下三款工具:
TSDX
create-react-library
dumi
这三款工具都预设好了打包工具,比如dumi用的webpack、tsdx用的parcel,而且也基本实现了0配置,我们只需要根据官方文档就可以很快地完成组件编写、用例测试、打包等环节。
其中create-react-library已经很少维护了,所以我没试过它。
tsdx和dumi带给我的体验差不太多,而且发布最重要的其实是写文档,两款工具都有对应的追书大师源码文档工具,tsdx内置的是storybook,我写的第一个组件库就是用的它,但是实在太难配插件了~
tsdx的问题一开始我用的tsdx,但是发现几个问题:
问题一:
我的组件在测试用例时,无法触发ts的提示,然后我发现它打包后的声明文件中需要将:
import?react?from?'react'修改成:
import?*?as?react?from?'react我的组件才能够有类型提示。
问题二:
tsdx中修改组件源代码后,需要手动再次打包,然后删掉example文件夹内的node_modules文件以及.parcel_cache文件夹生成新的dist目录,才会有效果。换言之它的watch模式貌似有问题?
dumi的问题于是我试了一下dumi,dumi写文档的方式对我而言要比tsdx的storybook方便,不过它也有一点缺陷:
即使用了官方推荐的ts-in-markdown插件,在写组件demo时,也是没有api智能提示的,只能提示有没有语法错误之类的。
这个缺陷就使得写demo时没有办法知道当别人用你的溯源系统下载源码组件时,有没有代码自动提示。(自动提示props真的很重要啊!!)
不过最终我找到了解决这个问题的方法,方法在本地测试组件。
我最终选择dumi从结果来说使用dumi打包完的组件还是有类型提示的,不需要我手动改dist目录。
我的组件文档首页目前是这样的:
基本满足了我的需求,所以下面讲讲如何使用dumi的发布过程。
一些微不足道的经验如何使用dumi这里就不多说,看官方文档就好,我在这里讲一下我遇到的问题以及解决方法:
当组件的props类型与外部引入的组件的props类型合并后,写API时会默认将所有props的api都展示出来。
这一点我们需要在.umirc.ts中配置apiParser:
apiParser:?{ ?propFilter:?{ ?//?是否忽略从?node_modules?继承的属性,默认值为?影视源码哪种好false?skipNodeModules:?true,?//?需要忽略的属性名列表,默认为空数组?skipPropsWithName:?[],?//?是否忽略没有文档说明的属性,默认值为?false?skipPropsWithoutDoc:?false,?},},当配置publicPath或base后,如果logo和favicon用的本地,一定要在前面加上publicPath或base的路径。
favicon:?'/react-drag-resizable/lightbulb.png',logo:?'/react-drag-resizable/lightbulb.png',base:?'/react-drag-resizable/',publicPath:?'/react-drag-resizable/',否则部署后logo和favicon的会引入失败。(这点在开发环境下发现不了)
dumi官方给的github-pages-action自动部署的yml文件有问题官方给的yml文件是这样写的:
name:?github?pageson:push:branches:
master#defaultbranch这里有问题,需要改成main
main#这才是正确的
jobs:deploy:runs-on:ubuntu-.steps:
uses:actions/checkout@v2
run:npminstall
run:npmrundocs:build
name:Deployuses:peaceiris/actions-gh-pages@v3with:github_token:${ { secrets.GITHUB_TOKEN}}publish_dir:./docs-dist
官方给的自定义导航、分组和标题写法有问题
官方写法如下:
---title:?自定义页面名称nav:path:?/自定义导航路由title:?自定义导航名称order:?控制导航顺序,数字越小越靠前,默认以路径长度和字典序排序group:path:?/自定义分组路由,注意,分组路由?=?导航路由?+?自己title:?自定义分组名称order:?控制分组顺序,数字越小越靠前,默认以路径长度和字典序排序---有效的写法:
---title:?自定义页面名称nav:path:?/自定义导航路由title:?自定义导航名称order:?控制导航顺序,数字越小越靠前,默认以路径长度和字典序排序group:path:?/自定义分组路由,注意,分组路由?=?导航路由?+?自己title:?自定义分组名称order:?控制分组顺序,数字越小越靠前,默认以路径长度和字典序排序---看出差别了吗??
已经将必要的模块导出,但写docs时引入该模块依然报错比如我已经在src/index.ts中导出组件内的类型声明和导出组件了:
export?type?{ ?RectProps,?DragResizableBoxProps?}?from?'./react-drag-resizable';export{ defaultasDragResizableBox}from'./react-drag-resizable';
但是在写?doc?时,正常引入`RectProps`,还是报错了。![image.png](-i-k3u1fbpfcp/7dad4e3efa5ccb9fd~tplv-k3u1fbpfcp-watermark.image?)执行`npm?run?build`打包出一个?dist?文件夹,然后重启?vscode?解决。#?使用github-actions自动化部署我们可以使用?github-actions?自动化将?dumi?的组件文档部署到?github-pages?中,实现步骤如下:1.?在?github?建一个代码仓库2.?到github?的个人主页申请一个?token![image.png](-i-k3u1fbpfcp/3ccdb4d9bfbff0cbecb4de~tplv-k3u1fbpfcp-watermark.image?)3.?选择token?的?note和过期时间![image.png](-i-k3u1fbpfcp/c5a3afeaebcbc3c3~tplv-k3u1fbpfcp-watermark.image?)![image.png](-i-k3u1fbpfcp/1ba1dae0f4ebfdcccdd~tplv-k3u1fbpfcp-watermark.image?)4.?权限选择![image.png](-i-k3u1fbpfcp/e0cecc1cba5aecc8f7a1~tplv-k3u1fbpfcp-watermark.image?)5.?最后生成?token,将token?复制到你的个人仓库的?`setting/secrets`?中![image.png](-i-k3u1fbpfcp/a7eee9ddeda8~tplv-k3u1fbpfcp-watermark.image?)我在这里使用的是?`ACCESS_TOKEN`,也可以自己写,不过这里的名字需要跟后面的?yml?文件保持一致。6.?在你的项目根目录中创建目录和?yml?文件.github└──workflows└──gh-pages.yml
yml文件中这样写```ymlname:?github?pageson:push:branches:-?main?#?default?branchjobs:deploy:runs-on:?ubuntu-.steps:-?uses:?actions/checkout@v2-?run:?npm?install-?run:?npm?run?docs:build-?name:?Deployuses:?peaceiris/actions-gh-pages@v3with:github_token:?${ { ?secrets.ACCESS_TOKEN?}}publish_dir:?./docs-dist注意最后的secrets.ACCESS_TOKEN里面的ACCESS_TOKEN就是你在github仓库中设置的token名字。
在项目的package.json中配置homepage字段
import?*?as?react?from?'react1将代码推送到远程仓库,actions会自动下载依赖并打包
最后打开你配置的homepage就可以看到部署好的文档,我的文档地址是这样的
/中注册一个账号
package.json中配置一些内容
import?*?as?react?from?'react4上面的配置是我收集到的,如果不是非常特殊的情况,我们只需要将name、description、author、version、keywords、homepage、repository修改成自己的就可以了,其他可以不动。
修改README一个NPM包,好的README能够快速让用户知道这个包能够干什么,如何使用等。
这里有一个github高star的项目,教人怎么写README,并提供了模板。
地址在这:standard-readme中文
同时我们可能还需要徽章,这里有一个徽章生成的工具网站,可以根据NPM或者github来生成徽章,我们只需要拷贝到README就可以生成徽章
徽章生成:https://shields.io/
在README中的徽章生成示例代码:
import?*?as?react?from?'react5会变成这样:
我们只需要拷贝代码,并将生成的链接覆盖掉这串代码上的链接就行
在项目中输入命令行发布登陆npm,并根据提示输入注册时的username、password,email
import?*?as?react?from?'react6npm镜像源,记得还原为官方,官方的源已经换成了https协议了
import?*?as?react?from?'react7设置完了也可以再看一眼
import?*?as?react?from?'react8执行npm打包,此时会出来dist文件
import?*?as?react?from?'react9一般来说我们只需要将dist传到npm就行了,不需要传源码,这时候你可能需要再看一眼package.json中的files字段是不是设置正确了
apiParser:?{ ?propFilter:?{ ?//?是否忽略从?node_modules?继承的属性,默认值为?false?skipNodeModules:?true,?//?需要忽略的属性名列表,默认为空数组?skipPropsWithName:?[],?//?是否忽略没有文档说明的属性,默认值为?false?skipPropsWithoutDoc:?false,?},},0发包
apiParser:?{ ?propFilter:?{ ?//?是否忽略从?node_modules?继承的属性,默认值为?false?skipNodeModules:?true,?//?需要忽略的属性名列表,默认为空数组?skipPropsWithName:?[],?//?是否忽略没有文档说明的属性,默认值为?false?skipPropsWithoutDoc:?false,?},},1后面更新包的代码时,需要同步更新包的版本,这个字段在package.json中
apiParser:?{ ?propFilter:?{ ?//?是否忽略从?node_modules?继承的属性,默认值为?false?skipNodeModules:?true,?//?需要忽略的属性名列表,默认为空数组?skipPropsWithName:?[],?//?是否忽略没有文档说明的属性,默认值为?false?skipPropsWithoutDoc:?false,?},},2每次都需要跟上一次不一样,否则会发包失败。
同时发包时,也可以修改其他package.json的内容,但不要改name噢。
最后推广一下本人长期维护的github博客
1.从学习到总结,记录前端重要知识点,涉及Javascript深入、HTTP协议、数据结构和算法、浏览器原理、ES6、前端技巧等内容。
2.在README中有目录可对应查找相关知识点。
如果对您有帮助,欢迎star、follow。
完结,撒花?ヽ(°▽°)ノ?
参考#是时候搭建你们团队的UI组件库了
#GitHubActions入门教程-阮一峰
#使用TypeScript+React发布组件到Npm