TSone

快速开始

本指南将帮助您快速上手 TSone 框架。

安装

使用 Bun >=1.3.0 安装 TSone 框架与 CLI:

bun add @geektech/tsone @geektech/tsone-cli

创建第一个应用

1. 创建一个简单的组件

import { Component, VNode, createApp } from '@geektech/tsone';

interface AppState {
  count: number;
}

class App extends Component<object, AppState> {
  protected initState(): AppState {
    return { count: 0 };
  }

  protected initStyles(): void {
    this.styleManager.addStyle('.app', {
      selector: '.app',
      properties: {
        textAlign: 'center',
        padding: '20px',
      },
    });
  }

  protected render(): VNode {
    return {
      tag: 'div',
      props: { className: 'app' },
      children: [
        { tag: 'h1', children: ['计数: '] },
        {
          tag: 'button',
          props: { className: 'btn' },
          listeners: {
            click: () => this.state.count++,
          },
          children: ['增加计数'],
        },
      ],
    };
  }
}

2. 创建应用实例并挂载

export const app = createApp({
  root: App,
  state: {
    appName: 'TSone 示例',
  },
  document: { title: 'TSone 示例' },
});

app.mount();

不需要为默认挂载点传入 rootElement。createApp 默认使用 #app,应用创建后直接调用 app.mount();如果页面中暂时没有对应元素,本次挂载会安全跳过。

将入口保存为 src/main.ts。CLI 要求使用命名导出 export const app,并且导出值必须提供 renderHtmlDocument()。

3. 使用 TypeScript 生成文档壳

const app = createApp({
  root: App,
  document: {
    lang: 'zh-CN',
    title: 'TSone 示例',
    description: '一个 TSone 计数器应用',
    body: { tag: 'div', props: { id: 'app' } },
    scripts: [{ type: 'module', src: './index.ts' }],
  },
});

const html = app.renderHtmlDocument();
app.mount();

配置开发与构建

配置文件只支持普通对象默认导出;不支持函数式配置或函数值配置。默认值为入口 src/main.ts、无额外页面、主机 127.0.0.1、端口 52211、空的 server.proxy,以及 build.outDir dist。

import { defineConfig } from '@geektech/tsone-cli';

export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, ''),
      },
    },
  },
  build: { outDir: 'dist' },
});

代理也可以使用字符串简写 '/backend': 'http://localhost:4000'。开发服务器仅提供 HTTP。代理目标可以使用 HTTP 或 HTTPS。字面前缀按最长匹配优先;查询参数、请求体与端到端请求头会转发,changeOrigin 更新 Host,rewrite 修改路径,上游不可达时返回 502 Bad Gateway。

多页应用

通过 pages 选项把额外路由映射到各自的页面入口。每个页面入口与根入口一样,都必须通过 export const app 导出并提供 renderHtmlDocument();键必须以 / 开头并支持嵌套,末尾斜杠会被归一化,根路径 / 始终由 entry 提供。

import { defineConfig } from '@geektech/tsone-cli';

export default defineConfig({
  entry: 'src/main.ts',
  pages: {
    '/about': 'src/about.ts',
    '/docs/guide': 'src/guide.ts',
  },
});

开发时每个页面在其路由下提供服务,tsone build 会为每个页面输出一个 HTML 文档(index.html、about.html、docs/guide.html),资源 URL 相对各文档。站点 JavaScript 入口使用 main-<hash>.js 等带内容 hash 的文件名,HTML 自动引用实际生成的文件名。

运行应用

tsone create
tsone dev [--host <host>] [--port <port>] [--no-watch]
tsone build [--out-dir <path>]

create 会在当前目录脚手架一个基础 TSone 项目(package.json、tsone.config.ts、tsconfig.json、.gitignore,以及展示 TSone 名称与 GitHub 链接的 src/main.ts 首页),并拒绝覆盖已有文件。dev 接受 host/port 覆盖以及 --no-watch 标志,build 只接受 out-dir;支持 --port 3000 与 --port=3000 两种形式。build.outDir 必须是项目根目录内部的子目录。

tsone dev 默认监听项目文件:源码、样式或配置变更时重建当前页面并通知已连接的浏览器刷新。监听模式为每个入口只保留最新成功构建的产物代,在通知刷新前删除上一代,旧资源 URL 返回 404;构建失败时保留最后可用的产物,且不通知刷新。tsone.config.ts 变更会以新配置重启开发服务器,并在旧实例停止且待处理请求完成后删除该实例的会话产物;传入 --no-watch 则使用保留各代产物的普通按需构建服务器。

CLI 首版配置不提供 plugins、WebSocket、HMR、SSR、函数式配置、public/ 复制以及公开的 minify/sourcemap 配置。

下一步