@tbox.cn/app-template-h5 0.1.13 → 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AGENTS.md
2
2
 
3
- template-h5 是面向 AI 生成移动 H5 应用的单 workspace 模板:`apps/client`(React/Vite)+ `apps/server`(Express)。
3
+ template-h5 是面向 AI 生成 H5 应用的单 workspace 模板:`apps/client`(React/Vite)+ `apps/server`(Express)。
4
4
 
5
5
  ## 工程结构
6
6
 
@@ -59,4 +59,5 @@ apps/server/src/dev.ts # vite dev 入口(仅 tsx 运行;
59
59
 
60
60
  - 保持单 workspace 的 `apps/client` + `apps/server` 两成员;不新增 `apps/client/` 之外的 Vite 配置或嵌套 lockfile(`pnpm check:workspace` 校验)。
61
61
  - 无模块/Provider/主题装配面:缺双端 `apps/*/src/modules.ts`——`tbox-app module add`、`tbox-app new module`、`tbox-app new provider` 会被 CLI 直接拒绝;`tbox-app theme use` 因无主题接线点也不适用。
62
+ - 模板不预设端形态(移动/桌面/自适应)——适配策略由应用自定;全局样式挂点 = `apps/client/src/styles/base.css`(仅设备无关卫生规则)。
62
63
  - 结构、路由、命令、依赖或环境变量变化时同步 README 与本文件。
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # template-h5
2
2
 
3
- tbox 移动 H5 全栈模板(包名 `@tbox.cn/app-template-h5`),单 workspace:`apps/client`(React/Vite)+ `apps/server`(Express)。运行时与页面微调经 `@tbox.cn/app-sdk-client` / `@tbox.cn/app-sdk-server`。
3
+ tbox H5 全栈模板(包名 `@tbox.cn/app-template-h5`),单 workspace:`apps/client`(React/Vite)+ `apps/server`(Express)。运行时与页面微调经 `@tbox.cn/app-sdk-client` / `@tbox.cn/app-sdk-server`。
4
4
 
5
5
  ## 快速开始
6
6
 
@@ -2,28 +2,8 @@
2
2
  <html lang="zh-CN">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <!-- 移动端视口;缩放锁定,配合 postcss-pxtorem 的 750→rem 换算 -->
6
- <meta
7
- name="viewport"
8
- content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
9
- />
10
- <meta name="theme-color" content="#0f172a" />
11
- <!-- rem 弹性根字号(threshold 450 / designWidth 750):移动端随屏宽缩放、PC 固定 50px 居中。
12
- 在 CSS 前同步执行,避免首屏字号闪动。 -->
13
- <script>
14
- (function () {
15
- var THRESHOLD = 450,
16
- DESIGN = 750;
17
- function setRootFontSize() {
18
- var w = document.documentElement.clientWidth;
19
- document.documentElement.style.fontSize =
20
- (w > THRESHOLD ? 50 : (100 / DESIGN) * w) + 'px';
21
- }
22
- setRootFontSize();
23
- window.addEventListener('resize', setRootFontSize);
24
- window.addEventListener('orientationchange', setRootFontSize);
25
- })();
26
- </script>
5
+ <!-- 基础视口;全屏 safe-area(viewport-fit=cover + env() 补偿)由应用成对启用 -->
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
27
7
  <title>H5 应用</title>
28
8
  <!-- 平台微调(inspector) runtime:由 server 提供 GET /__vs_inspector__.js;dev 下经 Vite 代理到 server。 -->
29
9
  <script src="/__vs_inspector__.js" defer></script>
@@ -20,7 +20,6 @@
20
20
  "@types/react-dom": "catalog:",
21
21
  "@vitejs/plugin-react": "catalog:",
22
22
  "happy-dom": "catalog:",
23
- "postcss-pxtorem": "catalog:",
24
23
  "typescript": "catalog:",
25
24
  "vite": "catalog:",
26
25
  "vitest": "catalog:"
@@ -6,13 +6,13 @@ import { createElement } from 'react';
6
6
  import BusinessApp from './App';
7
7
 
8
8
  describe('BusinessApp', () => {
9
- it('渲染中性入口标题', () => {
9
+ it('渲染中性入口', () => {
10
10
  const container = document.createElement('div');
11
11
  document.body.appendChild(container);
12
12
  flushSync(() => {
13
13
  createRoot(container).render(createElement(BusinessApp));
14
14
  });
15
- expect(container.querySelector('h1')?.textContent).toBe('你的移动应用,从这里开始');
15
+ expect(container.querySelector('main')?.textContent).toBe('应用从这里开始');
16
16
  container.remove();
17
17
  });
18
18
  });
@@ -1,15 +1,3 @@
1
- /**
2
- * 业务应用唯一入口:中性单页起点,无占位标记。
3
- * 新应用替换本组件;后端调用走 @tbox.cn/app-sdk-client 的 httpGet/httpPost(同源 /api/*)。
4
- */
5
1
  export default function BusinessApp() {
6
- return (
7
- <main className="app-shell">
8
- <section className="app-hero" aria-labelledby="app-title">
9
- <p className="app-kicker">H5 应用</p>
10
- <h1 id="app-title">你的移动应用,从这里开始</h1>
11
- <p>品牌、页面与数据能力从这里构建——前后端同仓,SDK 提供运行时与页面微调基线。</p>
12
- </section>
13
- </main>
14
- );
2
+ return <main>应用从这里开始</main>;
15
3
  }
@@ -21,7 +21,7 @@ if (el) {
21
21
  <StrictMode>
22
22
  <ErrorBoundary
23
23
  fallback={
24
- <main className="app-error">
24
+ <main>
25
25
  <h1>页面暂时不可用</h1>
26
26
  <button type="button" onClick={() => window.location.reload()}>
27
27
  重新加载
@@ -1,61 +1,14 @@
1
- /* 基础样式三合一:tokens 变量 + 移动端基础 + motion。
2
- 变量值保持中性(slate 系),主题覆写由各应用自行扩展。 */
3
-
4
- /* ===== tokens(变量) ===== */
5
- :root {
6
- --font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
7
- --color-background: #f8fafc;
8
- --color-surface: #ffffff;
9
- --color-text: #0f172a;
10
- --color-muted: #64748b;
11
- --color-primary: #0f766e;
12
- --color-primary-strong: #115e59;
13
- --color-accent: #f59e0b;
14
- --color-border: #dbe4ea;
15
- --color-focus: #f59e0b;
16
- --content-width: 480px;
17
- --space-1: 0.25rem;
18
- --space-2: 0.5rem;
19
- --space-3: 0.75rem;
20
- --space-4: 1rem;
21
- --space-5: 1.25rem;
22
- --space-6: 1.5rem;
23
- --space-8: 2rem;
24
- --radius-sm: 0.5rem;
25
- --radius-md: 0.75rem;
26
- --shadow-soft: 0 20px 50px rgba(15, 23, 42, 0.08);
27
- }
28
-
29
- /* ===== 基础(reset + 移动端基线) ===== */
30
- :root { font-family: var(--font-family); color: var(--color-text); background: var(--color-background); font-synthesis: none; text-rendering: optimizeLegibility; }
1
+ /* 全局样式入口:仅设备无关的基础卫生规则;视觉/布局/端形态由应用自定。 */
31
2
  *, *::before, *::after { box-sizing: border-box; }
32
- html { min-width: 320px; min-height: 100%; background: var(--color-background); }
33
- body { margin: 0; min-width: 320px; min-height: 100%; overflow-x: hidden; background: var(--color-background); }
34
- body, button, input, textarea, select { font: inherit; }
35
- button, a, input, textarea, select { -webkit-tap-highlight-color: transparent; }
36
- button, a { touch-action: manipulation; }
37
- button { min-height: 44px; cursor: pointer; }
38
- button:disabled { cursor: wait; opacity: 0.65; }
39
- img, video, canvas { display: block; max-width: 100%; }
40
- img { height: auto; }
41
- #root { min-height: 100dvh; }
42
- @supports not (height: 100dvh) { #root { min-height: 100vh; } }
43
- @media (min-width: 700px) {
44
- body { display: flex; justify-content: center; background: #e2e8f0; }
45
- #root { width: min(100%, 480px); min-height: 100dvh; background: var(--color-background); box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.08); overflow-x: hidden; }
3
+ body { margin: 0; }
4
+ button, input, textarea, select { font: inherit; }
5
+ img, video, canvas { display: block; }
6
+ img, video { max-width: 100%; height: auto; }
7
+ @media (prefers-reduced-motion: reduce) {
8
+ *, *::before, *::after {
9
+ animation-duration: 0.01ms !important;
10
+ animation-iteration-count: 1 !important;
11
+ scroll-behavior: auto !important;
12
+ transition-duration: 0.01ms !important;
13
+ }
46
14
  }
47
- :focus-visible { outline: 3px solid var(--color-focus); outline-offset: 3px; }
48
-
49
- /* ===== 入口类(中性起点,随应用改写) ===== */
50
- .app-shell { min-height: 100dvh; padding: max(2rem, env(safe-area-inset-top)) var(--space-5) max(2rem, env(safe-area-inset-bottom)); }
51
- .app-hero { padding: clamp(2.5rem, 12vh, 6rem) 0 var(--space-8); }
52
- .app-kicker { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--color-primary); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
53
- .app-hero h1 { max-width: 12ch; margin: var(--space-4) 0; font-size: 2.75rem; line-height: 1.02; }
54
- .app-hero p { max-width: 34rem; margin: 0 0 var(--space-6); color: var(--color-muted); font-size: 1.05rem; line-height: 1.7; }
55
- .app-error { display: grid; min-height: 100dvh; place-content: center; gap: var(--space-4); padding: var(--space-6); text-align: center; }
56
- @media (max-width: 380px) { .app-hero h1 { font-size: 2.4rem; } }
57
-
58
- /* ===== motion ===== */
59
- .loading-dot { width: 0.65rem; height: 0.65rem; border-radius: 50%; background: currentColor; animation: pulse 1.2s ease-in-out infinite; }
60
- @keyframes pulse { 0%, 100% { opacity: 0.35; transform: scale(0.8); } 50% { opacity: 1; transform: scale(1); } }
61
- @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; transition-duration: 0.01ms !important; } }
@@ -1,3 +1 @@
1
1
  /// <reference types="vite/client" />
2
-
3
- declare module 'postcss-pxtorem';
@@ -1,23 +1,11 @@
1
1
  /// <reference types="vitest" />
2
2
  import { defineConfig } from 'vite';
3
3
  import react from '@vitejs/plugin-react';
4
- import pxToRem from 'postcss-pxtorem';
5
4
  import { resolve } from 'node:path';
6
5
  // 平台微调配套 babel plugin(随 @tbox.cn/app-sdk 分发):dev 期给每个 JSX 注入源码位置属性,
7
6
  // 供 inspector runtime(/__vs_inspector__.js) 点选元素→定位源码(check:inspector 断言点)。
8
7
  import codeInspectPlugin from '@tbox.cn/app-sdk-client/platform/code-inspect';
9
8
 
10
- const pxToRemPlugin = pxToRem({
11
- rootValue: 100,
12
- unitPrecision: 5,
13
- propList: ['*'],
14
- selectorBlackList: ['.no-rem'],
15
- minPixelValue: 1,
16
- mediaQuery: false,
17
- // 排除 node_modules 内三方样式,但放行 pnpm 布局下的 @tbox.cn 模块 CSS(agent 同参)
18
- exclude: /node_modules\/(?!\.pnpm|@tbox\.cn)/,
19
- });
20
-
21
9
  // dev 期页面由 apps/server dev.ts 的 vite middleware 托管(本文件被其加载);
22
10
  // build 恒走静态产物。无 .tbox-dev.local 探针段(h5 无 dev 装配面,native launch)。
23
11
  export default defineConfig(({ command }) => ({
@@ -27,9 +15,6 @@ export default defineConfig(({ command }) => ({
27
15
  '@': resolve(__dirname, 'src'),
28
16
  },
29
17
  },
30
- css: {
31
- postcss: { plugins: [pxToRemPlugin] },
32
- },
33
18
  build: {
34
19
  rollupOptions: { input: { index: resolve(__dirname, 'index.html') } },
35
20
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tbox.cn/app-template-h5",
3
- "version": "0.1.13",
4
- "description": "tbox 移动 H5 全栈模板(单 workspace:apps/client + apps/server),运行时与页面微调经 @tbox.cn/app-sdk。",
3
+ "version": "0.1.14",
4
+ "description": "tbox H5 全栈模板(单 workspace:apps/client + apps/server),运行时与页面微调经 @tbox.cn/app-sdk。",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=24.0.0 <25.0.0"
@@ -42,9 +42,6 @@ catalogs:
42
42
  happy-dom:
43
43
  specifier: 20.11.2
44
44
  version: 20.11.2
45
- postcss-pxtorem:
46
- specifier: 6.1.0
47
- version: 6.1.0
48
45
  react:
49
46
  specifier: 18.3.1
50
47
  version: 18.3.1
@@ -123,9 +120,6 @@ importers:
123
120
  happy-dom:
124
121
  specifier: 'catalog:'
125
122
  version: 20.11.2
126
- postcss-pxtorem:
127
- specifier: 'catalog:'
128
- version: 6.1.0(postcss@8.5.26)
129
123
  typescript:
130
124
  specifier: 'catalog:'
131
125
  version: 5.9.3
@@ -1901,11 +1895,6 @@ packages:
1901
1895
  yaml:
1902
1896
  optional: true
1903
1897
 
1904
- postcss-pxtorem@6.1.0:
1905
- resolution: {integrity: sha512-ROODSNci9ADal3zUcPHOF/K83TiCgNSPXQFSbwyPHNV8ioHIE4SaC+FPOufd8jsr5jV2uIz29v1Uqy1c4ov42g==}
1906
- peerDependencies:
1907
- postcss: ^8.0.0
1908
-
1909
1898
  postcss@8.5.26:
1910
1899
  resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==}
1911
1900
  engines: {node: ^10 || ^12 || >=14}
@@ -3886,10 +3875,6 @@ snapshots:
3886
3875
  postcss: 8.5.26
3887
3876
  tsx: 4.23.11
3888
3877
 
3889
- postcss-pxtorem@6.1.0(postcss@8.5.26):
3890
- dependencies:
3891
- postcss: 8.5.26
3892
-
3893
3878
  postcss@8.5.26:
3894
3879
  dependencies:
3895
3880
  nanoid: 3.3.18
@@ -46,7 +46,6 @@ catalog:
46
46
  tsup: 8.5.1
47
47
  "@vitejs/plugin-react": 4.7.0
48
48
  happy-dom: 20.11.2
49
- postcss-pxtorem: 6.1.0
50
49
  supertest: 7.2.2
51
50
  "@types/supertest": 7.2.1
52
51