- 知识管理
- 知识库
【免费下载链接】dendron
The personal knowledge management (PKM) tool that grows as you do!
Dendron 是面向个人知识管理(PKM)的开源工具,其前端生态由多个 npm 包构成。dendron-design-system是其中负责统一视觉规范与共享 UI 组件的基础包:它基于 TSDX 脚手架搭建,内置 Chakra UI 主题(字体、品牌色)与 Logo 组件,并通过 Storybook、Example Playground 与 size-limit 建立了一套"开发—预览—体积管控—发布"的完整工作流。阅读本文后,你将掌握该设计系统的目录结构、字体与主题集成方式、TSDX 开发命令、组件测试与体积分析,以及在 Lerna 单仓中运行 Example 与发布到 Netlify 的完整实操方案。
设计系统概览:包结构与工程定位
dendron-design-system位于 packages/dendron-design-system,是一个以 React 为基础、通过 TSDX 可以确认它的工程定位:
- 包名与产物:
name为dendron-design-system,main指向dist/index.js(CJS 产物),module指向dist/dendron-design-system.esm.js(ESM 产物),typings指向dist/index.d.ts,发布时仅打包dist与src两个目录; - 运行时依赖:
@chakra-ui/react(组件与主题体系)、@emotion/react/@emotion/styled(样式引擎)、@fontsource/montserrat与@fontsource/roboto(自托管字体)、framer-motion(动画); - 对宿主的要求:
peerDependencies声明react >= 16,即宿主项目只需保证 React 版本不低于 16 即可引入本设计系统。
目录结构分为五大部分:src/(组件与主题源码)、example/(Parcel 驱动的示例 Playground)、stories/(Storybook 故事)、test/(单元测试)与public/(静态资源,如 dendron-vector.svg Logo 矢量图)。
字体策略:Montserrat + Roboto 双字体方案
设计系统在字体上采用了明确的"标题/正文"双字体搭配:Montserrat作为标题字体(header font),Roboto作为正文字体(body font)。之所以选择 Montserrat,是因为它已在当时的 dendron.so 官网上投入使用,属于延续既有品牌视觉;Roboto 则来自 Google Fonts 的推荐搭配,用于保证正文的长文可读性。
通过 Fontsource 自托管,而非 CDN 加载
按 README 的说明,字体引入方式采用了 Chakra UI 官方指南中推荐的Fontsource 方案(自托管字体包)。与依赖 Google Fonts CDN 不同,Fontsource 将字体文件打包进 npm 依赖,随设计系统一起分发,宿主项目无需联网请求外部字体服务,加载更稳定、隐私更友好。
在 package.json 中可以看到两个字体依赖:
"@fontsource/montserrat": "^4.2.2", "@fontsource/roboto": "^4.2.2"宿主项目只需两行 import
字体将随设计系统一起被打包分发,宿主项目唯一需要做的,是在应用最底层引入字体样式:
import '@fontsource/montserrat'; import '@fontsource/roboto';对于 Next.js 项目,这个位置就是_app.tsx(应用入口组件)。README 注明该导入方式已在本仓库的preview.tsx中完成过。需要注意:这只是一种"接入约定"——字体样式导入必须发生在任何组件渲染之前,因此 README 特别强调"at the lowest app level"。
主题层:字体与品牌色如何注入 Chakra UI
字体导入解决的是"字体文件可用"的问题,而"哪些场景用哪种字体"则由主题配置决定。看 src/theme/fonts.ts:
export const fonts = { heading: "montserrat", body: "roboto", };heading对应标题类组件(如Heading),body对应正文类组件(如Text),两者恰好与 README 中的设计决策一一对应。
与之配套的是品牌色板 src/theme/colors.ts:
export const colors = { brand: { lightGreen: "#43B02A", darkGreen: "#154734", neutralBlack: "#232222", }, };lightGreen(亮绿)与darkGreen(深绿)构成品牌主色系,neutralBlack作为中性色基准。最终在 src/theme/index.ts 中通过 Chakra UI 的extendTheme合并为完整的主题对象并导出:
import { extendTheme } from "@chakra-ui/react"; import { colors } from "./colors"; import { fonts } from "./fonts"; export const theme = extendTheme({ colors, fonts, });extendTheme是 Chakra UI 提供的主题扩展入口,它会在保留 Chakra 默认设计令牌的基础上,用本设计系统自定义的colors与fonts覆盖同名令牌。宿主项目引入该主题后,所有 Chakra 组件的字体与配色即自动对齐品牌规范。
开发工作流:TSDX 构建 + Storybook + Example Playground
本设计系统基于 TSDX 搭建,TSDX 会在/src下初始化库代码,并在/example下创建基于 Parcel 的 Playground 演示应用。从 package.json 的scripts可以看到完整命令映射:
"start": "tsdx watch", "build": "tsdx build", "test": "tsdx test --passWithNoTests", "lint": "tsdx lint", "storybook": "start-storybook -s ./public -p 6006", "build-storybook": "build-storybook -s ./public", "size": "size-limit", "analyze": "size-limit --why"推荐的开发三终端工作流
README 给出的推荐流程是同时开三个终端:
终端一:启动 TSDX 监听构建
npm start # 或 yarn start对应tsdx watch:编译输出到/dist并以监听模式运行——每次保存src下的改动,都会自动重建到/dist。这是整个工作流的核心,因为下游的 Storybook 与 Example 都消费/dist产物。
终端二:运行 Storybook
yarn storybook加载./stories目录下的故事文件,启动时通过-s ./public指定静态资源目录(Logo 组件依赖其中的 dendron-vector.svg)。
注意:README 特别强调,Stories 中引用组件时应像使用库一样从项目根目录导入(例如
import { Logo } from "../src/components"),这个根目录别名已在 tsconfig 与 Storybook 的 webpack 配置中预先配置。
终端三:启动 Example Playground
cd example npm i # 或 yarn 安装依赖 npm start # 或 yarn startExample 是 example/package.json 定义的 Parcel 应用(parcel index.html)。它默认导入并热重载/dist中的产物,因此如果看到组件没有更新,请先确认终端一中的 TSDX 是否在监听模式运行。全程无需 symlink——组件复用依赖 Parcel 的模块别名(alias)机制,而非软链接。
Example 的入口 example/index.tsx 展示了最小用法:
import "react-app-polyfill/ie11"; import * as React from "react"; import * as ReactDOM from "react-dom"; import { Logo } from "../src/components/Logo"; const App = () => ( <div> <Logo /> </div> ); ReactDOM.render(<App />, document.getElementById("root"));一次性构建与测试
- 一次性构建:
npm run build(或yarn build),对应tsdx build; - 运行测试:
npm test(或yarn test),对应tsdx test --passWithNoTests,即无测试时也不会因退出码失败而中断。
组件示例:Logo 与 Storybook 交互式调试
以仓库中唯一的核心组件Logo为例,它的实现位于 src/components/Logo/index.tsx:
import { ImgProps } from "@chakra-ui/image"; import { chakra } from "@chakra-ui/system"; import * as React from "react"; export const Logo: React.FC<ImgProps> = ({ boxSize, ...rest }) => ( <chakra.img src={"/dendron-vector.svg"} boxSize={boxSize} {...rest} /> );Logo是一个泛型组件,直接透传 Chakra UI 图片组件的全部属性(ImgProps),并暴露boxSize控制尺寸,默认渲染public/dendron-vector.svg。它从 src/components/index.ts 统一导出:
export { Logo } from "./Logo";对应地在 stories/Logo.stories.tsx 中,Storybook 为它配置了交互式控制项,方便在设计阶段直观调节尺寸:
argTypes: { boxSize: { control: { type: "range", min: 8, max: 80, step: 8 }, }, },而 test/logo.test.tsx 提供了一个"渲染不崩溃"的最小冒烟测试,验证组件可被挂载与卸载:
it("renders without crashing", () => { const div = document.createElement("div"); ReactDOM.render(<Logo />, div); ReactDOM.unmountComponentAtNode(div); });工程配置解析:代码质量、体积与类型
README 的 Configuration 一节覆盖了工程质量相关的四项配置,均可对照仓库实际文件逐一验证。
代码质量:Prettier + Husky + lint-staged
代码质量由prettier、husky、lint-staged兜底。本仓库中 Husky 钩子配置为提交前执行tsdx lint(见 package.json 的husky.hooks.pre-commit),Prettier 则采用printWidth: 80、semi: true、singleQuote: true、trailingComma: "es5"的规范。各宿主项目可按需调整package.json中对应字段。
Jest 测试
Jest 已预先配置好,执行npm test或yarn test即可运行 test 目录下的测试。
体积分析:size-limit
size-limit用于计算库的真实体积成本:
npm run size # 输出各产物实际体积与预算对比 npm run analyze # size-limit --why,可视化各依赖的体积构成体积预算在 package.json 的size-limit字段中声明,两个产物分别限定在10 KB以内:
"size-limit": [ { "path": "dist/dendron-design-system.cjs.production.min.js", "limit": "10 KB" }, { "path": "dist/dendron-design-system.esm.js", "limit": "10 KB" } ]这对于组件库至关重要——体积直接决定宿主应用的首屏加载成本,超限会直接让 CI 失败。
目录骨架(Setup Files)
TSDX 初始化时生成的标准结构如下,其中标注EDIT THIS的文件是需要开发者修改的:
/example index.html index.tsx # test your component here in a demo app package.json tsconfig.json /src index.tsx # EDIT THIS /test blah.test.tsx # EDIT THIS /stories Thing.stories.tsx # EDIT THIS /.storybook main.js preview.js .gitignore package.json README.md # EDIT THIS tsconfig.json打包器:Rollup
TSDX 底层使用 Rollup 作为打包器,为不同模块格式与构建场景生成多份 Rollup 配置。本仓库还通过 tsdx.config.js 向 Rollup 管线注入了图片插件:
import image from "@rollup/plugin-image"; module.exports = { rollup(config) { config.plugins.push(image()); return config; }, };该插件允许在源码中直接import图片资源并内联为 base64 或独立文件,是组件库处理 SVG/PNG 等静态资源的标配能力。
TypeScript 严格模式
tsconfig.json 配置了dom、esnext类型环境与react的 JSX 转换,并开启strict、noImplicitReturns、noUnusedLocals、noUnusedParameters等严格检查;declaration: true与sourceMap: true保证消费者获得.d.ts声明与源码映射,moduleResolution: "node"+esModuleInterop则保证 ESM/CJS 互操作与 Node 式模块解析。宿主项目可按自身需求调整。
部署 Example Playground 到 Netlify
Example 只是一个简单的 Parcel 应用,可以像部署任何静态站点一样部署到任意平台。README 给出了使用 Netlify CLI 的手动部署流程:
npm i -g netlify-cli # 先安装 Netlify CLI cd example # 若尚未进入 example 目录 npm run build # 构建到 dist netlify deploy # 部署 dist 目录若已将 git 仓库接入 Netlify,也可以配置持续部署(CD):
netlify init # build command: yarn build && cd example && yarn && yarn build # directory to deploy: example/dist # pick yes for netlify.toml即先构建设计系统本身(yarn build),再进入example安装依赖并构建 Playground,最终部署example/dist目录。
Lerna 单仓中的依赖解析问题与修复
当在 Lerna 管理的 monorepo 中新建 TSDX 包时,运行example项目可能会遇到Cannot resolve dependency错误。README 指出了根因:Lerna 项目依赖安装方式特殊,example 项目package.json中的alias 可能指向错误位置——这些依赖实际安装在了 Lerna 项目的根node_modules,而非 example 本地。
修复方法是调整 example 内部package.json的alias指向实际安装位置(实际路径取决于 Lerna 目录结构):
"alias": { - "react": "../node_modules/react", - "react-dom": "../node_modules/react-dom" + "react": "../../../node_modules/react", + "react-dom": "../../../node_modules/react-dom" },对照本仓库 example/package.json,其 alias 正是这个模式:
"alias": { "react": "../node_modules/react", "react-dom": "../node_modules/react-dom/profiling", "scheduler/tracing": "../node_modules/scheduler/tracing-profiling" }另一种替代方案是彻底移除 alias,把被 alias 的依赖改为 devDependencies 直接声明——但这种方式可能引入其他问题(README 对此给出了警示)。实际采用哪种方式,取决于组件库对 React 版本的复用要求与 monorepo 的目录深度。
小结
dendron-design-system是一份结构清晰、工程化完备的组件库样例:字体通过 Fontsource 自托管并由 Chakra UI 主题统一注入,开发期借助 TSDX 监听构建串联 Storybook 与 Parcel Playground,发布前用 size-limit 把两个产物控制在 10 KB 预算内,并给出了 Netlify 部署与 Lerna 单仓踩坑的完整解法。无论是要为 Dendron 生态贡献组件,还是在自己的项目中搭建类似的 React 组件库,上述配置与工作流都可以直接复用。后续需要扩展组件时,只需在 src/components 新增组件、在 stories 补充 Story、并在 test 添加测试,即可无缝接入整套既有流程。
- 知识管理
- 知识库
【免费下载链接】dendron
The personal knowledge management (PKM) tool that grows as you do!
相关推荐
Carbon Design System 开发者手册:Monorepo 架构、Sass 包体系与发布维护实战指南
Carbon Design System 开发者手册:Monorepo 架构、Sass 包体系与发布维护实战指南 导读 :本文完整解读 IBM Carbon D
前端UI组件设计系统OpenCore Legacy Patcher终极指南:5步让旧Mac焕然一新安装最新macOS系统
OpenCore Legacy Patcher终极指南:5步让旧Mac焕然一新安装最新macOS系统 你是否有一台性能依然强劲的旧Mac,却被苹果官方限制无法升
操作系统固件驱动开发WordPress Design System MCP Server 实战与演进全解析:基于 Gutenberg 的设计系统智能体接口
WordPress Design System MCP Server 实战与演进全解析:基于 Gutenberg 的设计系统智能体接口 WordPress De
后端前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考