之前参与的一个项目使用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了,兼容不好)
tsup,0天,放弃
(在git上没看到他介绍支持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
npx是跟npm一套的,安装node以后就有,npm大家都知道做包管理的,就相当于你在工厂工作,他来给你管理你要用的工具,你要的工具,他会去给你买.npx呢,他不光是能管理包,当有包的时候,他就会直接运行,没有的时候他会去下载然后再运行.
键盘↓选择到react 回车
使用webstorm打开项目(文件夹)
打开后项目如图:
运行项目,使你的每一步编译都自动生成可被引用的包文件
在webstorm下面的Terminal(终端),输入
yarn start
运行起来以后,他会自动检测你的文件修改.
如果只是想使用tsdx创建的项目做控件/组件/组件包.那就不要在example这里运行,单独创建一个ts项目进行开发,用到组件的时候引用这个ruilib(刚创建的)就可以了.
反正以后你的项目也不可能在一个组件库的子目录下开发.
如果你现在想直接测试一下包的运行,在webstorm中新开一个终端 然后
到example目录下.这个目录是使用你生成的组件(组件库)的一个测试项目.
然后再 yarn start 就运行起来了测试项目(调用组件库的项目)
然而,并不那么顺利,会出现如下错误:
是因为tsdx虽然给你的组件库项目安装了包依赖,并没有给example项目安装.所以你应该会像我一样执行 yarn 或者 yarn i 或者 yarn install 这三个命令都是一样的都是安装包依赖
好,完成了,看起来没什么问题.yarn build或者yarn start试一下
出现了Invalid Version: undefined 错误
改一下example项目下的package.json
在package.json中加入
"resolutions": {
"@babel/preset-env": "7.13.8"
}
在package.json中的scripts中加入
"preinstall": "npx npm-force-resolutions"
改完以后应该是这样:
删掉example目录下的 node_modules
重新执行包安装 这一次不要使用yarn了,使用
npm i
然后你还会发现错误.再执行一次
npm run preinstall
然后再执行一次
yarn
成功,再执行
yarn start
过关,点击这个蓝色的连接在浏览器中查看组件的效果吧
好了.这时候你就编辑你项目根目录下src的默认Thing组件试试效果吧.
我们分别创建了两个项目:
use-ruilib-js
use-ruilib-ts
都是使用create-react-app来创建的.
webstorm创建ts项目的时候直接在参数中勾选使用ts即可.
在TS项目中使用组件库.
点击上面的create之后,ts新项目正在创建中
利用这个时间我们回到刚才的ruilib项目中,再开一个终端.运行
yarn link
已经连接好了.
切换到新创建的use-ruilib-ts项目中,也已经创建完毕了.
关掉这个run执行完了的脚本.在右侧的Terminal中连接刚才我们创建好的组件库项目
yarn link ruilib
然后在src目录下的 app.tsx中引用默认的那个Thing的组件
import Thing from 'ruilib'
然后再加入这个标签.可是会出现错误如下:
改正 引入方式为:
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项目叫use-ruilib-js
因为在之前我们已经在ruilib项目下执行了yarn link
所以在这个js项目中直接就引用
yarn link ruilib
然后在app中像ts项目那样引入ruilib的thing组件.
启动项目:
yarn start
TS和JS项目都运行成功,
类似如下这两种引用方式:
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的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和styled component是我比较习惯的两种写css的方式.
但是styled component总感觉不伦不类 文件不分离.做项目移植或者借鉴的时候应该会很麻烦.
直接在ruilib的src目录下新建 index.module.css
你会发现如下错误
自动编译也会捕获到错误:
这个不要紧,直接在 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 就看到又编译成功了.代码错误提示也没有了.
看一下正在运行并监听的项目use-ruilib-ts和 use-ruilib-js.可以看到样式都有了.
这里贴出我测试可以使用的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目录下做修改.
改成这样:
index.tsx作为一个路由,里面内容类似这样:
发布包到npm的话,跟js写npm包没有区别.到我写的另一篇文章查看:
从零开始创建自己的npm组件/包(使用react)并发布到npm_Afterwards_的博客-CSDN博客_npm react包