hd-attribute-set
v0.1.6
Published
属性集组件库,基于 React + antd
Maintainers
Readme
hd-attribute-set
基于 TypeScript + React 的属性集 / 业务工具库,使用 Vite 库模式构建,通过 CNB 云原生构建 自动发布到 npm。
- 产物:ESM(
.js)+ CJS(.cjs)+.d.ts类型声明 - 入口:包根路径、
hd-attribute-set/utils、hd-attribute-set/hooks - 依赖:
react/react-dom/antd为 peer 依赖,不打包进产物
安装
npm i hd-attribute-set
# 或
yarn add hd-attribute-set引入方式
// 1. 包根路径:等价于同时引入 utils + hooks
import { isEmail, debounce, usePermission, version } from 'hd-attribute-set';
// 2. utils 子路径:只引工具方法
import { isPhone, listToTree, base64ToString } from 'hd-attribute-set/utils';
// 3. hooks 子路径:只引 hooks
import { usePermission, useBtnDeal, useSseConnect } from 'hd-attribute-set/hooks';CommonJS:
const { version } = require('hd-attribute-set');
const { isPhone } = require('hd-attribute-set/utils');
const { usePermission } = require('hd-attribute-set/hooks');目录结构
├── .cnb.yml # CNB 云原生构建流水线配置
├── .npmrc # npm 发布凭据(提交在仓库内,发布时使用)
├── index.html # 本地调试入口(playground)
├── src
│ ├── index.ts # 包主入口
│ ├── App.tsx / main.tsx # 调试页面
│ ├── utils # 公共工具方法
│ │ ├── index.ts # 统一出口(barrel)
│ │ ├── validate.ts # 校验类:isEmpty / isPhone / isIdCard / isEmail
│ │ ├── object.ts # 对象与树:deepClone / uniqueBy / listToTree
│ │ ├── fn.ts # 通用函数:debounce / throttle / sleep / isBase64 / base64ToString / isJson
│ │ └── universal.ts # 预留
│ └── hooks # 业务 Hook(均已与 redux / ahooks 解耦)
│ ├── index.ts
│ ├── use-memoized-fn.ts
│ ├── use-permission.ts
│ ├── use-btn-deal.ts
│ └── use-sse-connect.ts
├── vite.config.ts # Vite 配置(lib 模式,多入口)
└── tsconfig.jsonutils API
| 文件 | 方法 | 说明 |
|---|---|---|
| validate.ts | isEmpty(value) | 空值判断(undefined / null / '' / 空数组 / 空 Map·Set / 空对象) |
| | isPhone(value) | 手机号校验 |
| | isIdCard(value) | 身份证校验 |
| | isEmail(value) | 邮箱校验 |
| object.ts | deepClone(source) | 深拷贝 |
| | uniqueBy(list, key?) | 按字段(不传则按值)去重 |
| | listToTree(list, { idKey, parentKey, childrenKey }) | 列表转树,默认 id / parentId / children |
| fn.ts | debounce(fn, wait?) | 防抖,返回值带 cancel() |
| | throttle(fn, wait?) | 节流 |
| | sleep(ms) | 延时 |
| | isBase64(str) | 是否合法 Base64(空串视为合法) |
| | base64ToString(str) | Base64(UTF-8)转字符串,非 Base64 原样返回 |
| | isJson(str) | 是否合法 JSON 字符串 |
hooks API
usePermission
const { hasPermission, shouldShowButton, shouldShowMenu, isNoPermissionShow } = usePermission(source?)source 支持三种传法:
- 直接传权限配置对象(如 redux 里的
accessConfig); - 传 getter:
() => config,每次调用取最新值,适配 redux / context; - 不传:视为拥有全部权限(
DEFAULT_PERMISSION_CONFIG)。
PermissionConfig:{ noPermissionShow?: boolean; list?: (number | string)[]; selectAll?: boolean }。
useBtnDeal
const { controlShowStatus } = useBtnDeal(source?)
const [isShow, btn] = controlShowStatus({ type, detail, configBtns })- 按
type从configBtns中找按钮配置; - 用
btn-tag校验权限(内部复用usePermission); - 支持
show-match-key/show-match-value单个或数组条件匹配,invert-show-match反转; - 返回
[是否显示, 命中的按钮配置]。
useMemoizedFn
const memoized = useMemoizedFn(fn)返回引用稳定的函数(内部经 useRef 保存最新实现),可安全放入依赖数组,行为与 ahooks 的同名 hook 一致。
useSseConnect
const { fullUrl, sseUser, closeSSE, reInitSSE, getConnectStatus } = useSseConnect({
sseUrl, // { sse_test_url, sse_prod_url }
env: import.meta.env.VITE_BUILD_ENV, // test / dev 走测试地址
event, // 事件总线,收到带 datatype 的消息会 emit
onSseUserChange: user => dispatch(updateSseUser(user)),
onError: msg => message.error(msg?.msg),
autoConnect: false, // 默认 true;false 时由外部调用 reInitSSE
});其他参数:getToken / tokenStorageKey(默认读 sessionStorage 的 token)、handleDealMsg、onConnectSuccessCb、reconnectInterval(默认 3000ms)、maxReconnectTimes(默认 5)、debug。
token 取不到时不会建立连接。如果项目的 token 存在其他 key(例如
HD_TOKEN),必须传getToken:useSseConnect({ sseUrl, env, getToken: () => sessionStorage.getItem(TOKEN) });
接 redux 的完整示例
import { useBtnDeal, usePermission } from 'hd-attribute-set';
import { useAppSelector } from '@/store/hooks';
import { selectAccessConfig } from '@/store/slices/authSlice';
const accessConfig = useAppSelector(selectAccessConfig);
const { shouldShowButton, isNoPermissionShow } = usePermission(accessConfig);
const { controlShowStatus } = useBtnDeal(accessConfig);
const [editVisible, editBtn] = controlShowStatus({
type: 'edit',
detail: rowData,
configBtns: btnConfigs, // 来自后端 / 配置的按钮列表
});组件库不依赖 redux,所有业务数据(权限配置、SSE 地址、token、事件总线等)都由调用方传入。
本地开发
npm install
npm run dev # 启动 playground 调试(index.html)
npm run build # tsc --noEmit + vite build,产物输出到 dist/
npm pack --dry-run # 查看将要发布到 npm 的文件清单新增工具方法 / Hook
- 在
src/utils/或src/hooks/下新建文件并export; - 在对应的
index.ts(barrel)加一行export * from './xxx';; npm run build,新内容自动出现在包根路径与对应的子路径入口。
发布到 npm(CNB 云原生构建)
流水线规则见 .cnb.yml:
| 触发 | 执行内容 |
|---|---|
| push 到 main | 安装依赖 → 构建(仅校验,不发布) |
| push 到 main 且 package.json 有变更 | 安装依赖 → 构建 → npm whoami → npm publish |
也就是说:改完 version 合并到 main 即自动发版。
发布凭据来自仓库根目录的 .npmrc(内含 npm Automation Token),流水线里不再依赖 NPM_TOKEN 环境变量。
发版步骤:
git checkout main && git pull
npm version patch # 升版本号,如 0.1.5 -> 0.1.6
git push origin main --follow-tags发布前检查清单
- [ ]
package.json的version已升版(且该版本 npm 上不存在)。 - [ ]
npm run build通过,dist含hd-attribute-set.js/.cjs、utils.js/.cjs、hooks.js/.cjs及对应.d.ts。 - [ ]
npm pack --dry-run中仅包含dist与README.md,无源码泄露(.npmrc不会被发进包)。 - [ ] 使用方已安装
react/react-dom/antd(peer 依赖)。 - [ ] 新增的 hook / 方法已从
src/hooks/index.ts或src/utils/index.ts导出。
