从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM

之前参与的一个项目使用ts,从此就感觉无法回到js.决定用ts开发一套自己的组件.中间遇到各种问题,在此记录一下.

react,ts都是自己自学的,所以在搞这些东西的时候属实不易,用了大概一周.

draggable-time-selector - npm


期间测试过

自己使用ts+webpack/rollup/+react搭建,3天,放弃

(封装js的组件包弄弄也就算了,ts+react+webpack/rollup 之类的太麻烦了,这让写惯了c#,习惯开箱即用的人来说,ts简直就是千刀万剐.认识好多人都说,ts或者react之类的,写写就好了,不要深琢磨,很少有人愿意研究轮子,坑太多了,而这中间的坑有大部分都是版本问题)

  • 开始原因:想要纯粹,想要干净,轻量级
  • 结束原因:倦了,真的倦了,我想要纯粹没错,但是也没有必要再浪费时间了.

create-react-library,2天,放弃

(项目比较老了,现在react都18.1了,兼容不好)

  • 开始原因:想要快速,能用就行
  • 结束原因:各种不兼容react18,资料少

tsup,0天,放弃

(在git上没看到他介绍支持react,不敢尝试)

  • 开始原因:它说他是最简单最快速的方法创建ts库
  • 结束原因:在自述文件没看到支持react,怕了怕了

microbundle,1天,放弃

(哇哦,7k star)

开始原因:他说他产出的包是tiny级别的,他竟然用了tiny

结束原因:使用和导出css的问题.

tsdx,0.1天(目前我选用的方案)

(期间也出了问题,但是很快的解决了)

开始原因:我学尖了,先搜中文站有没有什么教程或者是有多少吐槽的.感觉好像还行,毕竟到此也没有太多的方案可用了.


我的环境:

macos 10.13.6

webstorm2022.1.3

node 16.14


创建:

打开终端,切换到要放组件库的文件夹,输入

npx tsdx create ruilib

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第1张图片

npx是跟npm一套的,安装node以后就有,npm大家都知道做包管理的,就相当于你在工厂工作,他来给你管理你要用的工具,你要的工具,他会去给你买.npx呢,他不光是能管理包,当有包的时候,他就会直接运行,没有的时候他会去下载然后再运行.

键盘↓选择到react 回车

使用webstorm打开项目(文件夹)

打开后项目如图:

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第2张图片


运行项目,使你的每一步编译都自动生成可被引用的包文件

在webstorm下面的Terminal(终端),输入

yarn start

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第3张图片

运行起来以后,他会自动检测你的文件修改.


使用自带的测试项目进行测试(这里有坑)

如果只是想使用tsdx创建的项目做控件/组件/组件包.那就不要在example这里运行,单独创建一个ts项目进行开发,用到组件的时候引用这个ruilib(刚创建的)就可以了.

反正以后你的项目也不可能在一个组件库的子目录下开发.

如果你现在想直接测试一下包的运行,在webstorm中新开一个终端 然后

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第4张图片

到example目录下.这个目录是使用你生成的组件(组件库)的一个测试项目.

然后再 yarn start 就运行起来了测试项目(调用组件库的项目)

然而,并不那么顺利,会出现如下错误:

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第5张图片

是因为tsdx虽然给你的组件库项目安装了包依赖,并没有给example项目安装.所以你应该会像我一样执行 yarn 或者 yarn i 或者 yarn install 这三个命令都是一样的都是安装包依赖

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第6张图片

好,完成了,看起来没什么问题.yarn build或者yarn start试一下

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第7张图片

 出现了Invalid Version: undefined 错误

改一下example项目下的package.json

在package.json中加入


  "resolutions": {
    "@babel/preset-env": "7.13.8"
  }

在package.json中的scripts中加入

"preinstall": "npx npm-force-resolutions"

改完以后应该是这样:

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第8张图片

删掉example目录下的 node_modules

重新执行包安装 这一次不要使用yarn了,使用

npm i

 然后你还会发现错误.再执行一次

npm run preinstall

然后再执行一次

yarn

 从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第9张图片

成功,再执行

yarn start

过关,点击这个蓝色的连接在浏览器中查看组件的效果吧

好了.这时候你就编辑你项目根目录下src的默认Thing组件试试效果吧.


在新项目或者已有项目中使用刚创建的组件库中的组件.

  • TS

我们分别创建了两个项目:

use-ruilib-js

use-ruilib-ts

都是使用create-react-app来创建的.

webstorm创建ts项目的时候直接在参数中勾选使用ts即可.

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第10张图片


在TS项目中使用组件库.

点击上面的create之后,ts新项目正在创建中

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第11张图片

利用这个时间我们回到刚才的ruilib项目中,再开一个终端.运行

yarn link

 从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第12张图片

 已经连接好了.

切换到新创建的use-ruilib-ts项目中,也已经创建完毕了.

 从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第13张图片

 关掉这个run执行完了的脚本.在右侧的Terminal中连接刚才我们创建好的组件库项目

yarn link ruilib

然后在src目录下的 app.tsx中引用默认的那个Thing的组件

import Thing from 'ruilib'

然后再加入这个标签.可是会出现错误如下:

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第14张图片

改正 引入方式为:

import {Thing} from 'ruilib';

 这样就正常了.因为组件的导出方式不是 export default xxx 而是 export const xxx的方式.

这时候如果我们编辑ruilib项目,会自动在dist下生成新的组件库导出文件.

由于ruilib下的package.json都是tsdx配置好的,use-ruilib-ts项目下使用ruilib的时候会自动通过package.json的typings字段和main字段来判断引用的库的入口.而且ruilib已经yarn start起来了.

所以你只管正常编写你的组件库代码即可.

再由于use-ruilib-ts项目也运行起来了,所以你改组件项目的代码或者是改使用组件的项目的代码,都会自动更新.


  • JS

以前开发的JS项目也能使用这个组件库.

我们又创建了一个js项目叫use-ruilib-js

因为在之前我们已经在ruilib项目下执行了yarn link

所以在这个js项目中直接就引用

yarn link ruilib

然后在app中像ts项目那样引入ruilib的thing组件.

启动项目:

yarn start

 

TS和JS项目都运行成功,


我们让tsdx支持css

类似如下这两种引用方式:

import 'aaa.css'
import styles from 'bbb.module.css'

这里提前说一下,上面那种写法我没测试通,如果硬刚的兄弟你可以试试怎么才可以.我屈服了使用了第二种写法.

直接在ruilib项目下添加css,把thing组件加一下样式

 在ruilib的src目录下新建了index.css

.main
{
    width: 300px;
    border: 1px solid red;
    border-radius: 10px;
    min-height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
}

在index.tsx中引用(不可用的方式):

import './index.css'

可用的方式:

import styles from './main.css'

你可能会奇怪,为啥要这么写,写过微信小程序的或者之前的react js项目的都知道

import xxx 和  import s from xxx在使用样式的时候是不一样的.

没错,现在就是让你用对象的形式使用样式了,而且不需要在样式的css文件上加入module.css了

以前index.js中要使用全局的css(可被污染的)要这样写:

import 'index.css'

使用css的时候这样写:

aaaaaa

后来当你接触了 css module的写法以后,把css当做对象 

import index.module.css

使用css的时候这样写:

aaaaaa

而且,使用 css module的方式的话,这个css文件名还必须为  js同名的开头+.module.css的形式.

现在不同了.不管css文件名叫什么,都可以以module也就是当做一个对象来引用.而且不污染其他css

好了,当你引用的时候,会出现如下错误:

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第15张图片

查阅官方文档,tsdx的rollup配置中默认没有加入css的支持.

这是可以理解的,因为有的人就是不用css,使用styled component之类的.

创建一个tsdx.config.js放在ruilib项目的根目录(tsdx默认会读取这个文件,不要创建别的名字,别浪)

内容是:

const postcss = require('rollup-plugin-postcss');

module.exports = {
    rollup(config, options) {
        config.plugins.push(
            postcss({
                inject: true,
                extract: !!options.writeMeta,
                modules: true,
                camelCase: true,
            }),
        );
        return config;
    },
};

 安装两个包到项目的开发依赖:

yarn add postcss rollup-plugin-postcss -D

Ctrl+c终止(不是复制) ruilib项目之前运行过的yarn start

然后再重新运行 yarn start 打包和监听文件修改都会成功的.

但是,我们发现并没有出现想要的样式.原因是因为css文件已经被刚刚定义为了模块形式导入,所以他不再是双引号引用的那种样式了.如果之前你项目已经在用'类名'的方式.那抱歉我目前也帮不了你了.我的时间紧任务重也是为了要解决使用css而已,虽然换个方式,但是还可以接受


  • 使用xxx.module.css
     

xxx.module.css和styled component是我比较习惯的两种写css的方式.

但是styled component总感觉不伦不类 文件不分离.做项目移植或者借鉴的时候应该会很麻烦.

直接在ruilib的src目录下新建 index.module.css

你会发现如下错误

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第16张图片

自动编译也会捕获到错误:

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第17张图片

 这个不要紧,直接在 ruilib的src目录下新建一个任意名字的.ts文件,比如我起名字为:index.module.ts

内容是:

declare module '*.css' {
    const content: any;
    export default content;
}

如果要同时支持less的话,这个文件里面可以这样写:

declare module '*.less' {
    const content: any;
    export default content;
}
declare module '*.css' {
    const content: any;
    export default content;
}

如果你写完了这些还没有自动编译的话,保存这个ts文件并且yarn start的那个终端进程终止(ctrl+c)再重新执行一次 yarn start 就看到又编译成功了.代码错误提示也没有了.

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第18张图片

 看一下正在运行并监听的项目use-ruilib-ts和 use-ruilib-js.可以看到样式都有了.

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第19张图片

这里贴出我测试可以使用的css引入方式:

import * as React from 'react';
import './main.css'
import styles0 from './main.css'
import styles from './index.less'
import styles2 from './index.module.css';
// Delete me
export const Thing = () => {
  return 
❌import './main.css' 这样使用不支持了.
✅import styles0 from './main.css'
✅import styles from './index.less'
✅import styles2 from './index.module.css'
the red border bound Thing element
; };

 至此我们就可以编译自己的组件了.


为了让一个组件库中能有多个组件,就像antd那样的.我们可以在ruilib的src目录下做修改.

改成这样:

从零开始使用tsdx封装自己的ts+react的组件库并发布到NPM_第20张图片

index.tsx作为一个路由,里面内容类似这样:


 发布包到npm的话,跟js写npm包没有区别.到我写的另一篇文章查看:

从零开始创建自己的npm组件/包(使用react)并发布到npm_Afterwards_的博客-CSDN博客_npm react包

你可能感兴趣的:(React,react.js,npm,javascript,typescript,tsdx)