ttrpg-tools/docs/development.md

5.6 KiB
Raw Permalink Blame History

开发和项目说明

快速开始

# 安装依赖
npm install

# 开发模式Web
npm run dev

# 构建Web
npm run build

# 预览构建结果
npm run preview

# CLI 开发模式
npm run cli:dev

# CLI 构建
npm run cli:build

# 运行测试
npm test

项目结构

ttrpg-tools/
├── src/
│   ├── cli/                    # CLI 工具源码
│   │   ├── commands/           # 命令实现 (serve, compile)
│   │   ├── index.ts            # CLI 入口
│   │   └── types.ts            # 类型定义
│   ├── components/             # TTRPG 组件
│   │   ├── md-dice.tsx         # 骰子组件
│   │   ├── md-table.tsx        # 表格组件
│   │   ├── md-deck/            # 卡牌组件
│   │   ├── md-pins.tsx         # 标记组件
│   │   ├── md-commander/       # 命令追踪器
│   │   ├── md-yarn-spinner.tsx # 叙事线组件
│   │   ├── md-token.tsx        # 代币组件
│   │   ├── Article.tsx         # 文章组件
│   │   ├── Sidebar.tsx         # 侧边栏
│   │   ├── FileTree.tsx        # 文件树
│   │   └── utils/              # 工具函数
│   ├── markdown/               # Markdown 解析器
│   │   ├── index.ts            # marked 配置
│   │   └── mermaid.ts          # mermaid 支持
│   ├── data-loader/            # 数据加载器
│   ├── plotcutter/             # 剧情切割工具
│   ├── yarn-spinner/           # 叙事线解析
│   ├── App.tsx                 # 主应用
│   ├── main.tsx                # 入口文件
│   ├── styles.css              # 样式
│   ├── index.html              # HTML 模板
│   └── global.d.ts             # 类型声明
├── bin/
│   └── cli/                    # CLI 二进制文件
├── content/                    # 示例内容
├── docs/                       # 文档
├── package.json
├── tsconfig.json
├── tsconfig.cli.json
├── rsbuild.config.ts
└── jest.config.js

技术栈

类别 技术
前端框架 Solid.js 1.9+
构建工具 Rsbuild
样式 Tailwind CSS 4 + @tailwindcss/typography
Markdown marked + marked-directive + marked-alert + marked-gfm-heading-id
图表 mermaid
3D three.js
测试 Jest
CLI commander + chokidar

开发规范

Solid.js 最佳实践

  • 优先使用 createEffectcreateMemo 实现响应式
  • 在 JSX 中直接引用 props 保持响应式
  • 避免滥用 onMount + createSignal
// ✅ 推荐
const doubled = createMemo(() => count() * 2);
createEffect(() => console.log(count()));

// ❌ 避免
onMount(() => {
  const [value, setValue] = createSignal(0);
});

组件开发

  • 不使用 Shadow DOM:使用 noShadowDOM()
  • 继承 Tailwind CSS 样式系统
  • 使用 customElement 注册自定义元素
import { customElement, noShadowDOM } from "solid-element";

customElement("md-dice", { key: "" }, (props, { element }) => {
  noShadowDOM();
  // 组件逻辑
});

类型检查

开发完成后检查类型错误:

npx tsc --noEmit

代码风格

  • 使用 TypeScript 严格模式
  • 遵循 ESLint 配置(如有)
  • 使用 2 空格缩进

添加新组件

1. 创建组件文件

// src/components/md-new-component.tsx
import { customElement, noShadowDOM } from "solid-element";
import { createSignal } from "solid-js";

export interface NewComponentProps {
  prop1?: string;
}

customElement("md-new-component", { prop1: "" }, (props, { element }) => {
  noShadowDOM();
  
  const [state, setState] = createSignal("");
  
  return (
    <div class="new-component">
      {/* 组件内容 */}
    </div>
  );
});

2. 注册组件

// src/components/index.ts
import './md-new-component';

3. 导出类型(可选)

// src/components/index.ts
export type { NewComponentProps } from './md-new-component';

构建配置

Rsbuild 配置

// rsbuild.config.ts
import { defineConfig } from '@rsbuild/core';
import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginSolid } from '@rsbuild/plugin-solid';
import tailwindcss from '@tailwindcss/postcss';

export default defineConfig({
  plugins: [pluginBabel(), pluginSolid()],
  tools: {
    postcss: {
      postcssOptions: {
        plugins: [tailwindcss()],
      },
    },
  },
  html: {
    template: './src/index.html',
  },
});

TypeScript 配置

  • tsconfig.json - 主项目配置Web
  • tsconfig.cli.json - CLI 工具配置Node.js

测试

# 运行所有测试
npm test

# 运行特定测试文件
npm test -- src/components/md-dice.test.ts

# 监听模式
npm test -- --watch

调试

Web 开发

npm run dev
# 访问 http://localhost:3000

CLI 调试

# 使用 ts-node 直接运行
npm run ttrpg serve ./content

# 或构建后运行
npm run cli:build
node dist/cli/index.js serve ./content

发布流程

  1. 更新版本号
  2. 运行测试和类型检查
  3. 构建 Web 和 CLI
  4. 发布到 npm
npm run build
npm run cli:build
npm test
npx tsc --noEmit
npm publish

常见问题

Windows 换行符

开发环境主要在 Windows 上,注意使用 CRLF 换行符。

依赖安装失败

# 清理缓存
npm cache clean --force
rm -rf node_modules package-lock.json
npm install

构建错误

# 检查类型
npx tsc --noEmit

# 重新构建
npm run build