存了
This commit is contained in:
@@ -17,6 +17,59 @@ Kbone 是腾讯提供的 Web 与小程序同构解决方案,允许使用 React
|
||||
|
||||
---
|
||||
|
||||
## Next 项目 → 小程序 最优转化方式
|
||||
|
||||
适用于:**现有 Next.js 前端 + newpp(Kbone 模板)**,以**适配**方式转化,保持功能与视觉一致。
|
||||
|
||||
### 架构约定
|
||||
|
||||
| 角色 | 说明 |
|
||||
|------|------|
|
||||
| **newpp** | Kbone 构建源:多入口 React 应用,`npm run mp` 输出到 `dist/mp/common/` |
|
||||
| **miniprogram** | 小程序壳:`app.js`/`app.json`/`custom-tab-bar` 等,构建后**合并** newpp 的页面与 common |
|
||||
| **Next 项目根目录** | Web 端:`app/`、`components/`、Tailwind;与 newpp 共享业务逻辑时可被 alias 或复制 |
|
||||
|
||||
### 转化步骤概要
|
||||
|
||||
1. **以 newpp 为唯一 Kbone 构建源**
|
||||
- 在 `newpp/build/miniprogram.config.js` 中按 Next 路由配置 `router`(每页单独配置,不用 `other`)。
|
||||
- 在 `newpp/build/webpack.mp.config.js` 中为每个页面配置 `entry`,且 `isOptimize = process.env.NODE_ENV === 'production'`。
|
||||
|
||||
2. **适配层(必须)**
|
||||
- `adapters/env.js`:`isMiniProgram()`(`typeof wx !== 'undefined' && wx.getSystemInfoSync`)。
|
||||
- `adapters/request.js`:Web 用 `fetch`,小程序用 `wx.request`,统一返回 Promise。
|
||||
- `adapters/storage.js`:Web 用 `localStorage`,小程序用 `wx.getStorageSync`/`setStorageSync`。
|
||||
- `adapters/router.js`:Web 用 `window.location` 或 Next `router`,小程序用 `wx.navigateTo`/`wx.reLaunch`;路径转小程序页面路径 `toMpPath(path)`。
|
||||
- **功能控制一致**:与 Next 端相同,用同一套 API(如 `/api/db/config`)和条件渲染(如 `features.matchEnabled` 控制「找伙伴」入口),不写死开关。
|
||||
|
||||
3. **UI 与页面来源**
|
||||
- **方案 A(推荐起步)**:在 newpp 内维护页面与组件,从 Next 的 `app/**/page.tsx`、`components/**` 复制并改为 JSX + 适配器调用(去掉 Next 专属的 `Link`/`useRouter`/`usePathname`,改用适配层)。
|
||||
- **方案 B**:在 newpp 的 webpack 中配置 `resolve.alias`,直接引用项目根目录的共享组件目录(需保证组件仅用 React + 适配层,无 `window`/`document`/Next 专属 API)。
|
||||
|
||||
4. **miniprogram.config.js 要点**
|
||||
- `router`:每个页面单独 key,例如 `index`、`chapters`、`read`、`my`、`match`,对应 `entry` 与小程序页面路径。
|
||||
- 动态底部导航:不配置原生 `tabBar`,在 `appExtraConfig` 中不写 `tabBar`;底部栏用 React 组件 + `wx.reLaunch` 跳转。
|
||||
|
||||
5. **样式兼容(与 Next 视觉一致)**
|
||||
- Grid → Flex(含 `boxSizing: 'border-box'`、必要时 `lineHeight`)。
|
||||
- `backdrop-filter` / `position: sticky` 等不支持则用占位或纯色/渐变替代,保证布局不错乱。
|
||||
- 单位:小程序侧可用 rpx,与 Web 的 rem/px 按设计稿做一次换算或共用同一套换算规则。
|
||||
|
||||
6. **构建与合并**
|
||||
- 在 newpp 执行 `NODE_ENV=production npm run build:mp`,将 `dist/mp/common/` 及 mp-plugin 生成的页面目录合并到 `miniprogram/`。
|
||||
- 合并时保留 miniprogram 壳的 `app.js` 全局数据与生命周期,只覆盖/新增 Kbone 生成的页面与 common 资源。
|
||||
|
||||
### 与 Kbone 规则的关系
|
||||
|
||||
- **router**:遵循本技能「核心配置规范」——每页单独配置、不用 `other`。
|
||||
- **底部导航**:遵循「问题 4:底部导航动态显示」——不配置原生 tabBar,用自定义组件 + `wx.reLaunch`。
|
||||
- **API/兼容**:遵循「跨平台适配层」与「问题 3:URLSearchParams」——全部走适配层,避免 Web 独有 API。
|
||||
- **样式**:遵循「问题 1:样式错位」与 troubleshooting 中的 Grid/Flex、box-sizing、lineHeight 等。
|
||||
|
||||
详细排查与示例见本目录下 `troubleshooting.md` 以及项目 `开发文档/8、部署/`。
|
||||
|
||||
---
|
||||
|
||||
## 核心配置规范
|
||||
|
||||
### 1. miniprogram.config.js 配置
|
||||
|
||||
110
.cursor/skills/kbone-miniprogram/reference.md
Normal file
110
.cursor/skills/kbone-miniprogram/reference.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Next → 小程序 转化参考(详细步骤)
|
||||
|
||||
与 `SKILL.md` 中「Next 项目 → 小程序 最优转化方式」对应,用于按步骤执行转化。
|
||||
|
||||
---
|
||||
|
||||
## 1. 架构与目录约定
|
||||
|
||||
| 目录/产物 | 作用 |
|
||||
|-----------|------|
|
||||
| `newpp/` | Kbone 源码:多入口 React,构建输出到 `newpp/dist/mp/` |
|
||||
| `miniprogram/` | 小程序壳:`app.js`、`app.json`、`custom-tab-bar`、空白页面占位等 |
|
||||
| Next 根目录 `app/`、`components/` | Web 端页面与组件;可被 newpp 复制或通过 alias 引用 |
|
||||
|
||||
构建后:将 `newpp/dist/mp/` 下的页面与 `common/` 合并进 `miniprogram/`,保留壳的 `app.js` 全局逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 2. newpp 配置
|
||||
|
||||
### 2.1 miniprogram.config.js
|
||||
|
||||
- `router`:每个页面单独 key,对应 Next 路由,**不要使用 `other` 数组**。
|
||||
- 动态底部导航:`appExtraConfig` 中**不配置** `tabBar`,用自定义 React 组件 + `wx.reLaunch`。
|
||||
- `global`:建议 `rem: true`、`pageStyle: true`。
|
||||
- `pages`:为每个页面配置 `extra.navigationBarTitleText`。
|
||||
|
||||
示例(按实际路由调整):
|
||||
|
||||
```javascript
|
||||
router: {
|
||||
index: ['/', '/(index)?', '/index.html'],
|
||||
chapters: ['/chapters', '/chapters.html'],
|
||||
read: ['/read/:id', '/read.html'],
|
||||
my: ['/my', '/my.html'],
|
||||
match: ['/match', '/match.html'],
|
||||
},
|
||||
appExtraConfig: {
|
||||
sitemapLocation: 'sitemap.json',
|
||||
// 不配置 tabBar
|
||||
},
|
||||
```
|
||||
|
||||
### 2.2 webpack.mp.config.js
|
||||
|
||||
- `entry`:每个页面一个入口,例如 `index`、`chapters`、`read`、`my`、`match`,指向 newpp 内对应入口 JSX。
|
||||
- `isOptimize`:`const isOptimize = process.env.NODE_ENV === 'production'`,生产构建时再压缩。
|
||||
- `optimization.splitChunks`:中小型项目建议 `splitChunks: false`,避免 chunk 缺失;大型项目再考虑固定命名 cacheGroups。
|
||||
|
||||
---
|
||||
|
||||
## 3. 适配层(必须)
|
||||
|
||||
在 newpp 内(或共享到根目录再被引用)实现:
|
||||
|
||||
| 文件 | 职责 |
|
||||
|------|------|
|
||||
| `adapters/env.js` | `isMiniProgram()`:`typeof wx !== 'undefined' && wx.getSystemInfoSync` |
|
||||
| `adapters/request.js` | Web:`fetch`;小程序:`wx.request`,统一返回 Promise |
|
||||
| `adapters/storage.js` | Web:`localStorage`;小程序:`wx.getStorageSync`/`setStorageSync` |
|
||||
| `adapters/router.js` | Web:`window.location` 或 Next Router;小程序:`wx.navigateTo`/`wx.reLaunch`,路径用 `toMpPath(path)` 转成小程序页面路径 |
|
||||
|
||||
业务代码**只**通过适配层访问请求、存储、路由,不直接使用 `window`、`document`、`localStorage`、`URLSearchParams` 等。
|
||||
|
||||
---
|
||||
|
||||
## 4. 功能控制一致
|
||||
|
||||
与 Next 端保持一致:
|
||||
|
||||
- 功能开关来自同一 API,例如 `/api/db/config` 的 `features.matchEnabled`。
|
||||
- 底部导航「找伙伴」等入口根据该配置条件渲染,不在小程序端写死。
|
||||
- 支付方式、营销二维码等同样由 API 配置驱动,两端逻辑一致。
|
||||
|
||||
---
|
||||
|
||||
## 5. UI 来源策略
|
||||
|
||||
- **复制适配**:从 Next 的 `app/**/page.tsx`、`components/**` 复制到 newpp,改为 JSX,用适配层替代 `Link`/`useRouter`/`usePathname`/`fetch`。
|
||||
- **Alias 引用**:在 newpp 的 webpack `resolve.alias` 中指向项目根目录的共享组件目录,保证该目录内仅用 React + 适配层,无 Next 专属 API。
|
||||
|
||||
---
|
||||
|
||||
## 6. 样式兼容(与 Next 视觉一致)
|
||||
|
||||
- **Grid → Flex**:所有 Grid 布局改为 Flex,并加 `boxSizing: 'border-box'`、必要时 `lineHeight`。
|
||||
- **backdrop-filter / sticky**:不支持则用纯色、渐变或占位,保证布局不错位。
|
||||
- **单位**:小程序侧可用 rpx,与 Web 的 rem/px 按设计稿统一换算。
|
||||
|
||||
详见 `troubleshooting.md` 中的「样式问题」小节。
|
||||
|
||||
---
|
||||
|
||||
## 7. 构建与合并流程
|
||||
|
||||
1. 在 newpp 执行:`NODE_ENV=production npm run build:mp`。
|
||||
2. 将 `newpp/dist/mp/` 下生成的页面目录及 `common/` 复制/合并到 `miniprogram/`。
|
||||
3. 保留 miniprogram 壳的 `app.js`(全局 data、onLaunch、onShow 等),仅覆盖或新增 Kbone 生成的页面与 common。
|
||||
4. 用微信开发者工具打开 `miniprogram/` 根目录,编译并测试。
|
||||
|
||||
---
|
||||
|
||||
## 8. 检查清单
|
||||
|
||||
- [ ] miniprogram.config.js:每页单独 router,无 `other`;未配置原生 tabBar。
|
||||
- [ ] webpack.mp.config.js:每页有 entry;isOptimize 按 NODE_ENV;中小型项目 splitChunks 为 false。
|
||||
- [ ] 适配层:env、request、storage、router 已实现并在业务中统一使用。
|
||||
- [ ] 功能开关与 Next 一致,来自同一 API。
|
||||
- [ ] 样式:无 Grid,Flex 已加 boxSizing/lineHeight;不支持特性已替代。
|
||||
- [ ] 合并后 app.js 未被错误覆盖,页面路径与 app.json 一致。
|
||||
@@ -1,5 +1,20 @@
|
||||
# Kbone 常见问题排查指南
|
||||
|
||||
## 从 Next 项目迁移到小程序
|
||||
|
||||
**先读**:本技能 `SKILL.md` 中的「Next 项目 → 小程序 最优转化方式」章节。
|
||||
|
||||
**要点**:
|
||||
- 以 **newpp** 为 Kbone 构建源,**miniprogram** 为壳,构建后合并产物。
|
||||
- 必须做 **适配层**:`env`、`request`、`storage`、`router`;功能开关与 Next 一致,用同一 API(如 `/api/db/config` 的 `features.matchEnabled`)。
|
||||
- **UI**:在 newpp 内复制并适配 Next 的页面/组件,或通过 webpack alias 引用根目录共享组件(无 Next 专属 API)。
|
||||
- **配置**:`miniprogram.config.js` 每页单独 router、不配原生 tabBar;`webpack.mp.config.js` 中 `isOptimize = process.env.NODE_ENV === 'production'`,中小型项目建议 `splitChunks: false`。
|
||||
- **样式**:Grid 改 Flex,补 `boxSizing`/`lineHeight`;不支持特性用兼容写法或替代。
|
||||
|
||||
遇到具体报错时,在下方「编译问题」「运行时问题」「样式问题」中按类型排查。
|
||||
|
||||
---
|
||||
|
||||
## 编译问题
|
||||
|
||||
### 1. chunk 文件缺失错误
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
---
|
||||
name: web-to-miniprogram-conversion
|
||||
description: Ensures complete 1:1 style migration and visual parity when converting Next.js to WeChat Mini Program (Kbone). Covers style compatibility mapping,补齐兼容 for Grid/backdrop/sticky/shadow/selectors, and visual parity checklist. Use when migrating Web to miniprogram, doing style conversion, or when the user asks for 100% style migration or visual consistency.
|
||||
---
|
||||
|
||||
# Web 转小程序转化过程技能
|
||||
|
||||
本技能提供「Web 前端转微信小程序」时的注意事项与清单,与 Kbone 配置互补使用。
|
||||
|
||||
**前置**:Kbone 搭建与配置见 [.cursor/skills/kbone-miniprogram/SKILL.md](../kbone-miniprogram/SKILL.md)。本文聚焦**转化过程**中的样式、动态 UI、请求、存储、路由等细节。
|
||||
|
||||
---
|
||||
|
||||
## 样式迁移目标与原则
|
||||
|
||||
**目标**:Next 转小程序过程中,实现 **完整、1:1、100% 样式迁移**,小程序端与 Web 端**视觉一致**。
|
||||
|
||||
**原则**:
|
||||
- 两端框架 CSS 能力有差异时,**不做删减**,而是做**补齐兼容**:用小程序支持的写法实现**等价的视觉效果**(颜色、字号、间距、圆角、对齐、安全区等一致)。
|
||||
- 凡无法用原生 CSS 完全复刻的(如 backdrop-filter、多阴影、部分选择器),用**视觉等价替代**(如毛玻璃→同色半透明、多阴影→单阴影或边框)并记录在 [reference.md - 样式兼容映射表](reference.md#web小程序-样式兼容映射表)。
|
||||
- 验收标准:同一页面在 Web 与小程序上并排对比,**字体、颜色、间距、圆角、对齐、安全区**等肉眼无差异。
|
||||
|
||||
---
|
||||
|
||||
## 一、样式转化与补齐兼容
|
||||
|
||||
### 1.1 布局:Grid → Flex(视觉等价)
|
||||
|
||||
- 小程序对 CSS Grid 支持不完整,易错位。
|
||||
- **补齐兼容**:所有 `grid` / `grid-cols-*` 改为 Flex,**保持视觉一致**:
|
||||
- 父:`display: flex`,`flexDirection: 'row'`(多列)或 `'column'`(多行);`flexWrap: 'wrap'` 若需换行。
|
||||
- 子:`flex: 1` 平分,或 `flex: '0 0 25%'` 等固定比例;**宽度/比例与 Web 上列数一致**(如 4 列即每项约 25%)。
|
||||
- **gap**:小程序支持则用 `gap`;不支持则用子项 `margin`(如 `marginRight`/`marginBottom`)或父 `padding`,**数值与 Web 一致**(如 gap-3 → 12px 或 24rpx)。
|
||||
- 涉及:底部导航、统计卡片、菜单列表、弹窗内多列、Dialog 居中(用 `flex` + `alignItems: 'center'` + `justifyContent: 'center'`)等。
|
||||
|
||||
### 1.2 必加属性(保证视觉一致)
|
||||
|
||||
- **box-sizing**:有 padding/border 的容器**必须**加 `boxSizing: 'border-box'`(或 Tailwind `box-border`),避免撑破布局导致错位、溢出。
|
||||
- **line-height**:图标+文字、多行文案处**显式**设 `lineHeight`(如 1、1.2、1.5),与 Web 一致,避免垂直错位。
|
||||
- **width**:需要占满的块加 `width: '100%'` 或 `flex: 1`,避免窄屏下宽度不一致。
|
||||
|
||||
### 1.3 需替换或降级的样式(视觉等价补齐)
|
||||
|
||||
| 类型 | Web 常见用法 | 小程序补齐兼容(视觉一致) |
|
||||
|------|--------------|----------------------------|
|
||||
| 毛玻璃 | `backdrop-filter` / `backdrop-blur-*` | 取 Web 背景主色 + 透明度:如 `backgroundColor: 'rgba(0,0,0,0.95)'` 或 `'rgba(28,28,30,0.95)'`,**与 Web 视觉效果接近**,不删该区域。 |
|
||||
| 吸顶 | `position: sticky` | `position: 'fixed'`,`top: 0`,`left/right: 0`,**同高同背景**;页面内容区加 `paddingTop` 与顶栏高度一致,避免被遮挡。 |
|
||||
| 安全区 | `env(safe-area-inset-*)` | 小程序支持则保留;构建后确认 WXSS 未丢失;`.safe-top`/`.safe-bottom` 在小程序端用相同 `padding` 或类实现,**数值一致**。 |
|
||||
| 多阴影 | `box-shadow: a, b, c` | Skyline 仅支持单阴影:保留主阴影或用 `border` + 单 `boxShadow` 近似,**颜色与扩散与 Web 主阴影一致**。 |
|
||||
| 伪类间距 | `:last-child { margin }` | 改为给最后一项加 class 或内联 `marginBottom: 0`,其余项统一 `marginBottom`,**间距数值与 Web 一致**。 |
|
||||
|
||||
### 1.4 Tailwind / CSS 变量
|
||||
|
||||
- Tailwind v4 的 `@theme inline`、`@layer` 等需确认 Kbone 构建链支持;`:root` 的 CSS 变量(如 oklch)一般可用,若有问题再在构建侧替换为固定值。
|
||||
- 单位:若 Kbone 配置 `global.rem: true`,Tailwind 的 rem 会按小程序规范转换。
|
||||
|
||||
### 1.5 样式补充(选择器、单位、Skyline、动画)
|
||||
|
||||
- **WXSS 选择器**:仅支持 `.class`、`#id`、`element`、`element, element`、`::before`/`::after`;**不支持**通配 `*`、属性选择器 `[attr]`、伪类 `:hover`/`:not()`/`:first-child` 等(Skyline 高版本起部分伪类支持,需看基础库)。
|
||||
- **单位**:竖屏以 **rpx** 为主(规定屏幕宽 750rpx);字体建议 rpx 或页面设 `page` 初始字号,避免 px 随系统字体变化;横屏可用 **vmin**(100rpx ≈ 100vmin/7.5)。
|
||||
- **Skyline 渲染**:若启用 Skyline,默认 `display: flex`、`box-sizing: border-box`、`flex-direction: column`,与 Web 不同;可配置 `defaultDisplayBlock: true`、`defaultContentBox: true` 对齐 Web。`overflow: scroll` 不支持,需用 `scroll-view`;`position: sticky` 用组件 `sticky-header`/`sticky-section` 替代;`backdrop-filter` 有多项限制(多函数、与 opacity 混用、blur 表现不一致);`box-shadow` 不支持多阴影叠加。
|
||||
- **动画与性能**:CSS 动画(transform、keyframes)会影响性能,宜少用;静态样式写 class,动态写 style,避免全部塞进 style。
|
||||
- 更多见 [reference.md - 样式补充(联网核查)](reference.md#样式补充联网核查)。
|
||||
|
||||
### 1.6 视觉一致验收
|
||||
|
||||
- **单位统一**:Web 用 rem/px 的数值,小程序侧用 rpx 或 rem(Kbone 开启 rem 时)时,**换算后与 Web 视觉一致**(如 16px → 32rpx 或 1rem 按基准换算)。
|
||||
- **颜色**:CSS 变量、hex、rgba 等在小程序侧**原样保留或替换为同值**(oklch 若不支持则转为 rgb/hex)。
|
||||
- **字体与行高**:`fontSize`、`fontWeight`、`lineHeight` 与 Web 一致;图标+文字对齐用 `lineHeight` 与 `alignItems: 'center'` 保证。
|
||||
- **间距与圆角**:padding、margin、borderRadius 数值与 Web 一致(px→rpx 按 750 基准换算)。
|
||||
- **对齐**:flex 的 `alignItems`、`justifyContent` 与 Web 一致;多列时子项 `flex: 1` 或比例与 Web 列数一致。
|
||||
- 完整检查项见 [reference.md - 视觉一致检查清单](reference.md#视觉一致检查清单);兼容映射见 [reference.md - Web→小程序 样式兼容映射表](reference.md#web小程序-样式兼容映射表)。
|
||||
|
||||
---
|
||||
|
||||
## 二、不能「配置化」的 UI(API 控制)
|
||||
|
||||
以下均需**自定义组件/页面 + 请求同一套 API**,不能依赖 app.json 的静态配置。
|
||||
|
||||
### 2.1 底部导航
|
||||
|
||||
- **Tab 项动态显隐**(如按 `features.matchEnabled` 显示「找伙伴」):必须用**自定义底部栏**,在组件内请求配置接口,根据返回渲染项;跳转用 `wx.reLaunch` 等,不配置原生 tabBar。
|
||||
- **按页面隐藏底部栏**:无 `usePathname()`,需按「当前页面路径」判断(各页是否渲染 BottomNav,或在公共组件内维护不展示的页面列表)。
|
||||
|
||||
### 2.2 功能开关
|
||||
|
||||
- 找伙伴/推广/搜索/关于等若由后端 `feature_config` 控制:各页面/组件请求配置后按 `features.*` 条件渲染;小程序端与 Web 同一套逻辑,仅请求方式走适配层。
|
||||
|
||||
### 2.3 配置驱动的内容
|
||||
|
||||
- 匹配类型·次数·价格、书籍章节·价格、支付方式展示:凡从后端配置来的,均在**页面内请求接口再渲染**,不能写死在小程序配置里。
|
||||
|
||||
---
|
||||
|
||||
## 三、请求与域名
|
||||
|
||||
- **CORS**:小程序请求 API **不涉及 CORS**(CORS 是浏览器策略);服务端无需为小程序加 CORS 头。
|
||||
- **合法域名**:小程序必须在微信公众平台配置「请求合法域名」,否则 `wx.request` 报 `url not in domain list`;本地调试可设 `urlCheck: false`。
|
||||
- **baseURL**:小程序内需使用完整 API 地址(如 `https://soul.quwanzhi.com`),相对路径 `fetch('/api/xxx')` 会失败;适配层用 `getApp().globalData.baseUrl + path` 或等价方式。
|
||||
|
||||
---
|
||||
|
||||
## 四、路由与导航
|
||||
|
||||
- 所有跳转走**适配层**:小程序用 `wx.navigateTo` / `wx.reLaunch` / `wx.redirectTo` / `wx.navigateBack`,Web 用 location/history;不用 Next.js `Link` / `useRouter`。
|
||||
- 动态参数:`/read/[id]` 在小程序为 `/pages/read/read?id=xxx`,参数从 `getCurrentPages()[].options` 或适配层 `getPageQuery()` 获取。
|
||||
- 底部 Tab 因使用自定义导航,用 `wx.reLaunch`,不用 `wx.switchTab`。
|
||||
|
||||
---
|
||||
|
||||
## 五、存储与持久化
|
||||
|
||||
- **localStorage**:全部走适配层,小程序端用 `wx.getStorageSync` / `wx.setStorageSync`(如 match 页联系方式、匹配次数、自动提现配置等)。
|
||||
- **Zustand persist**:需为 persist 提供自定义 storage(小程序环境用 wx 的 storage),否则登录态、设置等无法持久化。
|
||||
|
||||
---
|
||||
|
||||
## 六、登录与支付
|
||||
|
||||
- **微信登录**:若小程序用微信登录,走 `wx.login` 取 code 再调后端换 session;与 Web 手机号/密码逻辑不同,需分支或适配。
|
||||
- **支付**:小程序内用 `wx.requestPayment`;「展示哪些支付方式」仍可由现有 `settings.paymentMethods` 等 API 配置控制。
|
||||
|
||||
---
|
||||
|
||||
## 七、环境与 API 兼容
|
||||
|
||||
- **window / document**:使用前加 `if (!isMiniProgram())` 或 `window?.xxx`,避免报错。
|
||||
- **URLSearchParams**:小程序不支持,需自实现 `buildQueryString` 或 polyfill。
|
||||
- **标题**:用 `wx.setNavigationBarTitle`,不用 `document.title`。
|
||||
|
||||
---
|
||||
|
||||
## 八、第三方库
|
||||
|
||||
- **framer-motion**:Kbone 不支持,改用 CSS 动画或 `wx.createAnimation`,或移除动画。
|
||||
- **Radix UI**:部分依赖 DOM/Portal,小程序可能不可用;用内联样式 + 自写组件替代(Dialog、Tabs、Select 等)。
|
||||
|
||||
---
|
||||
|
||||
## 九、构建与包体
|
||||
|
||||
- 主包 ≤ 2MB,总分包 ≤ 20MB;必要时分包或减依赖。
|
||||
- 中小项目建议 `splitChunks: false`,避免动态 chunk 缺失。
|
||||
- Kbone 产出需与现有 miniprogram 壳合并(custom-tab-bar、globalData、project.config 等)。
|
||||
|
||||
---
|
||||
|
||||
## 十、测试与发布
|
||||
|
||||
- 开发阶段可勾选「不校验合法域名」;体验版/真机须配置合法域名,且关闭 `urlCheck: false`。
|
||||
- 真机重点测:请求、支付、登录、存储、底部栏显隐、各功能开关。
|
||||
|
||||
---
|
||||
|
||||
## 参考
|
||||
|
||||
- **样式 1:1 迁移**:[reference.md - Web→小程序 样式兼容映射表](reference.md#web小程序-样式兼容映射表)、[视觉一致检查清单](reference.md#视觉一致检查清单)、[补齐兼容实施步骤](reference.md#补齐兼容实施步骤1-1-样式迁移)。
|
||||
- 完整转化清单与更多细节见 [reference.md](reference.md)。
|
||||
- Kbone 配置与故障排查见 [../kbone-miniprogram/](../kbone-miniprogram/)。
|
||||
@@ -1,223 +0,0 @@
|
||||
# Web 转小程序转化过程 - 详细清单
|
||||
|
||||
与 SKILL.md 配套使用,提供完整检查项与说明。**目标**:样式 1:1、100% 迁移,视觉与 Web 一致;有差异处做补齐兼容。
|
||||
|
||||
---
|
||||
|
||||
## Web→小程序 样式兼容映射表
|
||||
|
||||
| Web(Next/CSS) | 小程序能力 | 补齐兼容(视觉一致) |
|
||||
|-----------------|------------|----------------------|
|
||||
| `display: grid` / `grid-cols-N` | Grid 支持不完整 | 改为 `display: flex`,子项 `flex: 1` 或 `flex: 0 0 (100/N)%`,**列数、间距与 Web 一致** |
|
||||
| `gap: 12px` | 部分支持 gap | 用子项 `marginRight`/`marginBottom` 或父 padding,**数值与 Web 一致**(12px→24rpx 等) |
|
||||
| `backdrop-filter` / `backdrop-blur-*` | 支持差/限制多 | 取 Web 背景主色 + 透明度:`backgroundColor: 'rgba(r,g,b,0.95)'`,**视觉接近毛玻璃** |
|
||||
| `position: sticky` | 不支持或仅组件 | `position: fixed` + 内容区 `paddingTop: 顶栏高度`,**顶栏高度、背景与 Web 一致** |
|
||||
| `box-shadow: 多值` | 仅单阴影 | 保留主阴影或 `border` + 单 `boxShadow`,**颜色、模糊、偏移与 Web 主阴影一致** |
|
||||
| `:hover` / `:last-child` 等伪类 | 不支持或部分 | 用 class/内联样式:如最后一项加 `marginBottom: 0`,其余统一 margin,**间距数值一致** |
|
||||
| `env(safe-area-inset-*)` | 支持 | 保留;确认构建后 WXSS 未丢失;`.safe-top`/`.safe-bottom` 等价实现,**数值一致** |
|
||||
| `box-sizing: content-box`(默认) | Skyline 默认 border-box | 需与 Web 一致时配置 `defaultContentBox: true` 或显式设 `boxSizing: 'content-box'` |
|
||||
| `rem` / `px` | rpx / rem | 统一基准:750 宽→1px=2rpx;rem 由 Kbone 转换;**换算后视觉一致** |
|
||||
| oklch / 复杂颜色 | 部分支持 | 不支持的用 rgb/hex 替换,**色值一致** |
|
||||
| 多 `background-image` | 仅单图 | 保留主图或合并为单图,**视觉近似** |
|
||||
|
||||
---
|
||||
|
||||
## 视觉一致检查清单
|
||||
|
||||
每页迁移后按下列项与 Web 并排对比,确保**肉眼无差异**。
|
||||
|
||||
### 全局
|
||||
|
||||
- [ ] 页面背景色与 Web 一致
|
||||
- [ ] 安全区(顶部/底部/左右)与 Web 一致(有无留白、留白多少)
|
||||
- [ ] 全局字体大小、行高、字重与 Web 一致
|
||||
|
||||
### 布局
|
||||
|
||||
- [ ] 多列数量与 Web 一致(如 4 列、3 列)
|
||||
- [ ] 列间距、行间距与 Web 一致(gap 或 margin 换算正确)
|
||||
- [ ] 顶栏/底栏高度、内边距与 Web 一致
|
||||
- [ ] 吸顶区域(若有)与 Web 视觉一致(fixed + 占位)
|
||||
|
||||
### 组件与模块
|
||||
|
||||
- [ ] 卡片/列表项:圆角、内边距、边框、背景与 Web 一致
|
||||
- [ ] 按钮:高度、圆角、字号、背景/边框与 Web 一致
|
||||
- [ ] 图标+文字:垂直对齐、间距与 Web 一致(lineHeight、alignItems)
|
||||
- [ ] 弹窗/遮罩:背景透明度、圆角与 Web 一致(毛玻璃→同色半透明)
|
||||
|
||||
### 文字与颜色
|
||||
|
||||
- [ ] 标题/正文字号、颜色、字重与 Web 一致
|
||||
- [ ] 链接/强调色与 Web 一致
|
||||
- [ ] 占位符、禁用态颜色与 Web 一致
|
||||
|
||||
### 阴影与装饰
|
||||
|
||||
- [ ] 主阴影(单阴影或近似)与 Web 主阴影颜色、模糊、偏移一致
|
||||
- [ ] 装饰性 blur 可保留或简化,**不改变布局与主色**
|
||||
|
||||
### 验收通过标准
|
||||
|
||||
- 同一页面在 Web 与小程序并排对比,**字体、颜色、间距、圆角、对齐、安全区**无肉眼差异;有差异的已记录为「视觉等价替代」并符合上表。
|
||||
|
||||
---
|
||||
|
||||
## 补齐兼容实施步骤(1:1 样式迁移)
|
||||
|
||||
1. **扫一遍 Web 样式**:列出所有 Grid、backdrop、sticky、多阴影、伪类间距、单位(rem/px)。
|
||||
2. **按映射表替换**:用 [Web→小程序 样式兼容映射表](#web小程序-样式兼容映射表) 逐项改为小程序等价写法,**数值与 Web 一致**(单位换算:750 宽下 1px≈2rpx)。
|
||||
3. **必加属性**:有 padding/border 的容器加 `boxSizing: 'border-box'`;图标+文字处加 `lineHeight`;需占满的加 `width: '100%'` 或 `flex: 1`。
|
||||
4. **Skyline 若启用**:与 Web 不一致时配置 `defaultDisplayBlock`、`defaultContentBox`;overflow 用 `scroll-view`;sticky 用组件或 fixed+占位。
|
||||
5. **验收**:按 [视觉一致检查清单](#视觉一致检查清单) 与 Web 并排对比,逐项打勾。
|
||||
|
||||
---
|
||||
|
||||
## 一、样式转化清单
|
||||
|
||||
### Grid 需改为 Flex 的典型位置(视觉等价)
|
||||
|
||||
- 首页「我的阅读」统计区(grid-cols-4)→ flex,子项 flex: 1,**4 列间距与 Web 一致**
|
||||
- 我的页统计卡片、菜单区(grid-cols-3)→ flex,子项 flex: 1,**3 列间距一致**
|
||||
- 找伙伴页统计/列表(grid-cols-4)→ 同上
|
||||
- 弹窗内多列(grid-cols-2 / grid-cols-3)→ flex,**列数、gap 一致**
|
||||
- 目录/章节列表多列、书籍介绍多列 → flex,**比例与间距一致**
|
||||
- Dialog 居中:用 `display: flex; align-items: center; justify-content: center` 替代 `display: grid`,**居中效果一致**
|
||||
|
||||
### 需替换或降级的样式(视觉等价补齐)
|
||||
|
||||
- `backdrop-blur-*`:底部导航、顶栏、弹窗遮罩、glass-card → **取 Web 背景主色 + 透明度**(如 rgba(28,28,30,0.95)),视觉接近毛玻璃
|
||||
- `position: sticky`:各页顶栏 → fixed + 内容区 paddingTop 占位,**顶栏高度、背景与 Web 一致**
|
||||
- 装饰性 `blur-3xl` 等:可保留(对布局无影响);性能差再考虑简化,**不改变主色与布局**
|
||||
- 多阴影:保留主阴影或单阴影+边框,**颜色、模糊与 Web 主阴影一致**
|
||||
|
||||
### 安全区
|
||||
|
||||
- `env(safe-area-inset-*)` 小程序支持;确认构建后 WXSS 中未丢失
|
||||
- `.safe-top` / `.safe-bottom` 类需在小程序端有等价实现,**padding 数值与 Web 一致**
|
||||
|
||||
---
|
||||
|
||||
## 样式补充(联网核查)
|
||||
|
||||
以下基于微信官方 WXSS / Skyline 文档与社区实践整理,转化时可按需核对。
|
||||
|
||||
### WXSS 选择器
|
||||
|
||||
| 支持 | 不支持或部分支持 |
|
||||
|------|-------------------|
|
||||
| `.class`、`#id`、`element`、`element, element`、`::before`、`::after` | 通配 `*`、属性选择器 `[attr]` |
|
||||
| (Skyline 8.0.49+)`:first-child`、`:last-child`;(8.0.50+)`:nth-child`、`:not`、`:only-child`、`:empty` | 传统 WXSS 下伪类如 `:hover`、`:not()`、`:first-child` 等可能不支持,需以 JS 控制状态替代 |
|
||||
|
||||
- 依赖 `:last-child`、`:not()` 等做间距/边框时,改为给子项加 class 或内联样式(如 `marginRight`、`borderBottom`)。
|
||||
|
||||
### 单位与适配
|
||||
|
||||
- **rpx**:规定屏幕宽 750rpx;设计稿 750px 可直接 1:1 转 rpx。竖屏布局、字体建议用 rpx,避免 px 随系统字体缩放。
|
||||
- **横屏**:rpx 以宽度为基准,横屏会变;若支持横屏,可用 **vmin**(如 `100rpx ≈ 100vmin/7.5`)或动态计算。
|
||||
- **rem**:Kbone 可开 `global.rem: true`,Tailwind 的 rem 会按小程序规范转换;与 rpx 二选一或统一策略。
|
||||
|
||||
### Skyline 渲染引擎差异(若启用)
|
||||
|
||||
- **默认值**:`display: flex`、`box-sizing: border-box`、`flex-direction: column`、`position: relative`,与 Web 不同;布局错乱时可配置:
|
||||
- `rendererOptions.skyline.defaultDisplayBlock: true` → 默认 block
|
||||
- `rendererOptions.skyline.defaultContentBox: true` → 默认 content-box
|
||||
- **不支持**:通配 `*`、属性选择器;`overflow: scroll`(用 `scroll-view`);单独 `overflow-x`/`overflow-y`;`position: sticky`(用 `sticky-header`/`sticky-section`);inline / inline-block 布局(或仅 text 内部分支持)。
|
||||
- **限制**:`fixed` 的 top/left/bottom/right 不支持 `auto`;z-index 无 Web 层叠上下文,只对兄弟节点生效;`box-shadow` 不支持多阴影叠加;`backdrop-filter` 不支持多函数、drop-shadow、url,与 opacity 混用有问题,blur 部分场景不一致;SVG 不支持 rgba,可用 fill-opacity。
|
||||
- **Font-face**:仅支持 ttf。
|
||||
|
||||
### 内联样式与性能
|
||||
|
||||
- 官方建议:**静态样式写 class**,**style 只放动态样式**,避免全部塞进 style 影响解析与渲染。
|
||||
- Kbone 若大量使用内联 style,需权衡;可把不变部分抽成 class,动态部分再合并进 style。
|
||||
|
||||
### 动画
|
||||
|
||||
- CSS 动画(transform、keyframes)会拉高渲染开销,宜少用、简化。
|
||||
- Skyline 可用 Worklet 动画;传统 view 动画可用 `wx.createAnimation`。
|
||||
|
||||
### Kbone 样式相关
|
||||
|
||||
- 尽量用 **HTML 标签**(如 `<input>`、`<img>`)而非小程序内置组件,减少包裹层对样式的影响。
|
||||
- 用 webpack `DefinePlugin` 注入 `process.env.isMiniprogram`,便于样式与逻辑按端分支。
|
||||
|
||||
---
|
||||
|
||||
## 二、API 控制 UI 清单(不能配置化)
|
||||
|
||||
| 场景 | 当前实现 | 小程序做法 |
|
||||
|------|----------|------------|
|
||||
| 底部 Tab 数量与「找伙伴」显隐 | `/api/db/config` → `features.matchEnabled` | 自定义底部栏 + 同一配置接口 + `wx.reLaunch` |
|
||||
| 按页面隐藏底部栏 | `usePathname()` 判断 | 按当前页面路径或各页是否挂载 BottomNav |
|
||||
| 找伙伴/推广/搜索/关于开关 | `feature_config.*`(若接上) | 各页请求配置后条件渲染 |
|
||||
| 匹配类型·次数·价格 | 可改为请求 `match_config` | 页面内请求并渲染 |
|
||||
| 书籍章节·价格 | 可改为请求 `book_config`/`price_config` | 页面内请求并渲染 |
|
||||
| 支付方式展示 | `settings.paymentMethods` | 同一配置,支付调起用 `wx.requestPayment` |
|
||||
|
||||
---
|
||||
|
||||
## 三、构建与配置清单
|
||||
|
||||
- [ ] miniprogram.config.js:router 每页单独配置,无 other 数组
|
||||
- [ ] webpack entry 与 router 键名一致
|
||||
- [ ] global.rem / pageStyle 按需开启
|
||||
- [ ] 主包 ≤ 2MB;必要时分包
|
||||
- [ ] splitChunks:中小项目建议 false
|
||||
- [ ] 合并脚本:dist/mp 与 miniprogram 壳合并(custom-tab-bar、globalData、project.config)
|
||||
|
||||
---
|
||||
|
||||
## 四、路由与导航清单
|
||||
|
||||
- [ ] 所有跳转走适配层(navigateTo / reLaunch / redirectTo / navigateBack)
|
||||
- [ ] 底部 Tab 用 reLaunch(因自定义导航)
|
||||
- [ ] 动态参数用 query:/read/[id] → ?id=xxx,从 getCurrentPages()[].options 或 getPageQuery() 取
|
||||
- [ ] 无 usePathname;按页面路径或各页挂载逻辑控制底部栏显隐
|
||||
|
||||
---
|
||||
|
||||
## 五、请求与域名清单
|
||||
|
||||
- [ ] 小程序不涉及 CORS;服务端无需为小程序加 CORS 头
|
||||
- [ ] 公众平台配置「请求合法域名」(如 https://soul.quwanzhi.com)
|
||||
- [ ] 请求 baseURL 为完整域名;适配层拼接 baseUrl + path
|
||||
- [ ] 本地调试可 urlCheck: false;发布前恢复并确认域名
|
||||
|
||||
---
|
||||
|
||||
## 六、存储与持久化清单
|
||||
|
||||
- [ ] 所有 localStorage 走适配层(wx.getStorageSync / wx.setStorageSync)
|
||||
- [ ] Zustand persist 提供自定义 storage(小程序用 wx storage)
|
||||
- [ ] match 页:联系方式、当日匹配次数等 key 在适配层统一实现
|
||||
|
||||
---
|
||||
|
||||
## 七、登录与支付清单
|
||||
|
||||
- [ ] 微信登录:wx.login + code 换 session,与 Web 逻辑分支或适配
|
||||
- [ ] 支付:小程序内用 wx.requestPayment;展示哪些方式仍由 API 配置控制
|
||||
|
||||
---
|
||||
|
||||
## 八、环境与 API 兼容清单
|
||||
|
||||
- [ ] window/document 使用前判断或可选链
|
||||
- [ ] URLSearchParams 用自实现或 polyfill
|
||||
- [ ] 页面标题用 wx.setNavigationBarTitle
|
||||
|
||||
---
|
||||
|
||||
## 九、第三方库清单
|
||||
|
||||
- [ ] framer-motion:移除或改为 CSS / wx.createAnimation
|
||||
- [ ] Radix UI:用内联样式 + 自写组件替代(Dialog、Tabs、Select 等)
|
||||
- [ ] 其他依赖 DOM/BOM 的库:条件加载或替换
|
||||
|
||||
---
|
||||
|
||||
## 十、测试与发布清单
|
||||
|
||||
- [ ] 开发阶段:不校验合法域名可开启
|
||||
- [ ] 体验版/真机:合法域名已配置,urlCheck 已关闭
|
||||
- [ ] 真机验证:请求、支付、登录、存储、底部栏显隐、功能开关
|
||||
Reference in New Issue
Block a user