Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions .cursor/skills/nutui-taro-weapp-wxss/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
name: nutui-taro-weapp-wxss
description: >-
NutUI React Taro 小程序 WXSS 编译超时修复:nutui-taro-demo 样式 bundle 合并、
删除无效 renderingMode、app-origin.wxss 体积治理。Use when 微信小程序报
[ WXSS 文件编译错误] something must be wrong、wcsc timeout、app-origin.wxss
过大、predev:taro 重写 app.config、或修改 generate-nutui-taro.js /
nutui.react.scss.taro.bundle.scss。
---

# NutUI Taro 小程序 WXSS 编译治理

## 1. 背景与根因

**现象**:`[ WXSS 文件编译错误] something must be wrong` + `Error: timeout`;偶发 `无效的 app.json ["renderingMode"]`。

**根因**:`app.ts` → `nutui.react.scss.taro.ts` 曾 **100+ 条**独立 `import` 组件 scss;Taro `sass.resource` 向**每个**文件注入 `variables.scss` + `theme-default.scss`(含 base64 `@font-face`)。

| 指标 | 修复前 | 修复后(bundle) |
| --- | --- | --- |
| `app-origin.wxss` | ~4MB | ~0.3–0.9MB |
| `@font-face` 重复 | ~216 | ~2–10 |

**不是**单个组件(如 `switch.scss`)的 bug,而是 **demo 全量样式打包方式** 导致。

**数据流(修复后)**:

```
app.ts → nutui.react.scss.taro.ts → nutui.react.scss.taro.bundle.scss
├─ variables + theme(各 1 次)
└─ 全部组件 scss → dist/weapp/app-origin.wxss
```
Comment on lines +28 to +32

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

给这个代码块补上语言标记。

这里是纯文本流程图,但未声明 fence 语言,和当前的 markdownlint 规则不一致,容易在文档校验里产生告警。建议直接标成 text(或等价的纯文本语言)。

🔧 建议修改
-```
+```text
 app.ts → nutui.react.scss.taro.ts → nutui.react.scss.taro.bundle.scss
   ├─ variables + theme(各 1 次)
   └─ 全部组件 scss → dist/weapp/app-origin.wxss
-```
+```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
app.ts → nutui.react.scss.taro.ts → nutui.react.scss.taro.bundle.scss
├─ variables + theme(各 1 次)
└─ 全部组件 scss → dist/weapp/app-origin.wxss
```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 28-28: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.cursor/skills/nutui-taro-weapp-wxss/SKILL.md around lines 28 - 32, The
fenced code block containing the flow "app.ts → nutui.react.scss.taro.ts →
nutui.react.scss.taro.bundle.scss" should declare a language to satisfy
markdownlint; change the opening fence from ``` to ```text so the block is
treated as plain text (i.e., update the fence surrounding the lines starting
with "app.ts → nutui.react.scss.taro.ts → nutui.react.scss.taro.bundle.scss"
accordingly).

Source: Linters/SAST tools


---

## 2. 最小改动清单

| 文件 | 改动 |
| --- | --- |
| `scripts/taro/generate-nutui-taro.js` | 新增 `bundleScssStr`;遍历组件拼 `@import`;`nutui.react.scss.taro.ts` 改为单 import bundle;新增写 `nutui.react.scss.taro.bundle.scss` |
| `src/packages/nutui.react.scss.taro.bundle.scss` | variables/theme + 全部组件 `@import`(**自动生成,勿手改**) |
| `scripts/build-taro.mjs` | `buildCSS` / `buildHarmonyCSS` 的 glob 排除 `nutui.react.scss.taro.bundle.scss`,避免打进 npm 按组件发包 |
| `scripts/harmony/update-taro-entry.js` | 删除 `renderingMode: 'mixed'` |
| `scripts/taro/generate-taro-route.js` | 同上 |

- `nutui.react.scss.ts`(H5)**不变**,`generate-nutui.js` 仍生成 100+ 条 JS import
- **勿只改** `app.config.ts`:`predev:taro` 会跑 `update-taro-entry.js` 覆盖
- **不在最小集**:`config/index.js` minimize、各组件 scss calc 优化、`package.json` dev:weapp

### 边界说明(H5 / 发包)

| 场景 | 是否走 bundle | 说明 |
| --- | --- | --- |
| H5 文档站 `sites/mobile` + `nutui.react.scss.ts` | 否 | Vite `additionalData` 只注入 variables,theme 在 `main.tsx` 单独 import 一次,无 wcsc 超时问题 |
| Taro demo `dev:taro`(weapp / h5) | 是 | `app.ts` → `nutui.react.scss.taro.ts` → bundle |
| Taro 发包 `build:taro` | 否 | bundle 被 glob exclude;构建结束会删除 `nutui.react.scss.js`;业务方仍 `import '@nutui/nutui-react-taro/dist/es/packages/xxx/style'` |

---

## 3. 解决 / 好处 / 影响

**解决**:WXSS 超时;无效 `renderingMode` 警告;demo 可预览(需登录开发者工具 + 清缓存)。

**好处**:样式单入口;不改 `build:taro` 发包;新增组件仍由 `generate-nutui-taro.js` 写入 bundle。

| 命令 | 影响 |
| --- | --- |
| `dev:taro weapp` | 有 |
| `build:taro` / `build:taro:demo` | 无(bundle 已在 `build-taro.mjs` glob 中排除) |
| `prepare` / `generate:file:taro` | 有(再生 bundle) |
| `VITE_APP_PROJECT_ID=jmapp` | bundle 写死 default 主题,需另行验证 |

**已知限制**:`build:weapp` 生产压缩时 postcss-calc 可能破坏嵌套 `var+calc`(dev 无此问题);游客模式 `webapi_getwxaasyncsecinfo:fail` 为环境问题。

---

## 4. 验证

```bash
pnpm run dev:taro weapp
wc -c packages/nutui-taro-demo/dist/weapp/app-origin.wxss
grep -c '@font-face' packages/nutui-taro-demo/dist/weapp/app-origin.wxss
```

期望:体积远小于 4MB;`@font-face` 为个位数。

---

## 5. 未采纳方案(备查)

| 方案 | 未采纳原因 |
| --- | --- |
| 各组件 scss 局部 CSS 变量 | 非主因,扩大 diff |
| `config/index.js` minimize(false) | dev 不需要 |
| `webpackImporter: false` | 引发 Module not found |
| sass.resource 置空 | 嵌套 @import(popup→overlay)缺变量 |
| 手改 app.config.ts | predev:taro 会覆盖 |

---

## 6. Agent 自检

- [ ] 只改生成脚本 + bundle + `build-taro.mjs` exclude,未扩大组件 scss diff?
- [ ] `build-taro.mjs` 已排除 `nutui.react.scss.taro.bundle.scss`?
- [ ] 两个生成脚本已去掉 `renderingMode`?
- [ ] 仍超时:查 `app-origin.wxss` 体积、游客模式、是否未重新 dev
11 changes: 9 additions & 2 deletions scripts/build-taro.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,11 @@ async function copyStyles() {
// 构建样式
async function buildCSS(themeName = '') {
const componentScssFiles = await glob(['src/packages/**/*.scss'], {
ignore: ['src/packages/**/demo.scss'],
ignore: [
'src/packages/**/demo.scss',
// demo 专用全量 bundle,不参与 npm 按组件发包
'src/packages/nutui.react.scss.taro.bundle.scss',
],
})

const variables = await readFile(
Expand Down Expand Up @@ -438,7 +442,10 @@ async function buildCSS(themeName = '') {
// 构建样式
async function buildHarmonyCSS(themeName = '') {
const componentScssFiles = await glob(['src/packages/**/*.scss'], {
ignore: ['src/packages/**/demo.scss'],
ignore: [
'src/packages/**/demo.scss',
'src/packages/nutui.react.scss.taro.bundle.scss',
],
})

const variables = await readFile(
Expand Down
6 changes: 5 additions & 1 deletion scripts/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,11 @@ async function copyStyles() {
// 构建样式
async function buildCSS(themeName = '') {
const componentScssFiles = await glob(['src/packages/**/*.scss'], {
ignore: ['src/packages/**/demo.scss'],
ignore: [
'src/packages/**/demo.scss',
// Taro demo 专用全量 bundle,不参与 H5 npm 按组件发包
'src/packages/nutui.react.scss.taro.bundle.scss',
],
})

const variables = await readFile(
Expand Down
1 change: 0 additions & 1 deletion scripts/harmony/update-taro-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export default defineAppConfig({
navigationBarTitleText: 'NutUI-React',
navigationBarTextStyle: 'black'
},
renderingMode: 'mixed',
components: ['pages/index/index', ...(subPackages.map(subPackage => {
return subPackage.pages.map(page => \`\${subPackage.root}/\${page}\`)
}).flat())]
Expand Down
14 changes: 12 additions & 2 deletions scripts/taro/generate-nutui-taro.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ let importStr = ``
let importRNStr = ``
let importMarkdownStr = ``
let importScssStr = `\n`
let bundleScssStr = `@import '../styles/variables.scss';\n@import '../styles/theme-default.scss';\n`
const packages = []
const mds = []
const raws = []
Expand All @@ -21,6 +22,7 @@ config.nav.map((item) => {
importRNStr += `import ${name} from '@/packages/${name.toLowerCase()}/index.${rn?'rn':'taro'}'\n`
importRNStr += `export * from '@/packages/${name.toLowerCase()}/index.${rn?'rn':'taro'}'\n`
importScssStr += `import '@/packages/${name.toLowerCase()}/${name.toLowerCase()}.scss'\n`
bundleScssStr += `@import './${name.toLowerCase()}/${name.toLowerCase()}.scss';\n`
packages.push(name)

glob
Expand Down Expand Up @@ -99,8 +101,7 @@ fs.outputFile(
// }
// )

let taroScssfileStr = `
${importScssStr}
let taroScssfileStr = `import './nutui.react.scss.taro.bundle.scss'
export default { "NutUI":"NutUI-Taro" };`
fs.outputFile(
path.resolve(__dirname, '../../src/packages/nutui.react.scss.taro.ts'),
Expand All @@ -111,6 +112,15 @@ fs.outputFile(
}
)

fs.outputFile(
path.resolve(__dirname, '../../src/packages/nutui.react.scss.taro.bundle.scss'),
bundleScssStr,
'utf8',
(error) => {
if (error) throw error
}
)

fs.outputFile(
path.resolve(__dirname, '../../src/packages/nutui.react.scss.ts'),
importScssStr,
Expand Down
1 change: 0 additions & 1 deletion scripts/taro/generate-taro-route.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export default defineAppConfig ({
navigationBarTitleText: 'NutUI-React',
navigationBarTextStyle: 'black'
},
renderingMode: 'mixed',
components: ['pages/index/index', ...(subPackages.map(subPackage => {
return subPackage.pages.map(page => \`\${subPackage.root}/\${page}\`)
}).flat())]
Expand Down
9 changes: 9 additions & 0 deletions src/packages/configprovider/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,13 @@ export type NutCSSVariables =
| 'nutuiIndicatorDotActiveSize'
| 'nutuiIndicatorBorderRadius'
| 'nutuiIndicatorDotMargin'
| 'nutuiIndicatorDotBorder'
| 'nutuiIndicatorDotInactiveColor'
| 'nutuiIndicatorTrackWidth'
| 'nutuiIndicatorSliderWidth'
| 'nutuiIndicatorDualScreenInactiveWidth'
| 'nutuiIndicatorPlacementGap'
| 'nutuiIndicatorPlacementSafeGap'
| 'nutuiMenuScrollFixedTop'
| 'nutuiMenuScrollFixedZIndex'
| 'nutuiMenuBarLineHeight'
Expand Down Expand Up @@ -941,6 +948,8 @@ export type NutCSSVariables =
| 'nutuiToastTitleFontWeight'
| 'nutuiToastIconColor'
| 'nutuiSafeAreaMultiple'
| 'nutuiIndicatorCurrent'
| 'nutuiIndicatorTotal'
| 'nutuiButtonDisabledBackgroundColor'
| 'nutuiBlack3'
| 'nutuiBlack1'
107 changes: 107 additions & 0 deletions src/packages/nutui.react.scss.taro.bundle.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
@import '../styles/variables.scss';
@import '../styles/theme-default.scss';
@import './button/button.scss';
@import './cell/cell.scss';
@import './cellgroup/cellgroup.scss';
@import './configprovider/configprovider.scss';
@import './image/image.scss';
@import './overlay/overlay.scss';
@import './divider/divider.scss';
@import './grid/grid.scss';
@import './griditem/griditem.scss';
@import './layout/layout.scss';
@import './col/col.scss';
@import './row/row.scss';
@import './safearea/safearea.scss';
@import './space/space.scss';
@import './sticky/sticky.scss';
@import './backtop/backtop.scss';
@import './elevator/elevator.scss';
@import './fixednav/fixednav.scss';
@import './hoverbutton/hoverbutton.scss';
@import './hoverbuttonitem/hoverbuttonitem.scss';
@import './navbar/navbar.scss';
@import './sidebar/sidebar.scss';
@import './sidebaritem/sidebaritem.scss';
@import './tabbar/tabbar.scss';
@import './tabbaritem/tabbaritem.scss';
@import './tabpane/tabpane.scss';
@import './tabs/tabs.scss';
@import './address/address.scss';
@import './calendar/calendar.scss';
@import './calendaritem/calendaritem.scss';
@import './calendarcard/calendarcard.scss';
@import './cascader/cascader.scss';
@import './checkbox/checkbox.scss';
@import './checkboxgroup/checkboxgroup.scss';
@import './datepicker/datepicker.scss';
@import './datepickerview/datepickerview.scss';
@import './form/form.scss';
@import './formitem/formitem.scss';
@import './input/input.scss';
@import './inputnumber/inputnumber.scss';
@import './menu/menu.scss';
@import './menuitem/menuitem.scss';
@import './numberkeyboard/numberkeyboard.scss';
@import './picker/picker.scss';
@import './pickerview/pickerview.scss';
@import './radio/radio.scss';
@import './radiogroup/radiogroup.scss';
@import './range/range.scss';
@import './rate/rate.scss';
@import './searchbar/searchbar.scss';
@import './shortpassword/shortpassword.scss';
@import './signature/signature.scss';
@import './switch/switch.scss';
@import './textarea/textarea.scss';
@import './uploader/uploader.scss';
@import './actionsheet/actionsheet.scss';
@import './badge/badge.scss';
@import './dialog/dialog.scss';
@import './drag/drag.scss';
@import './empty/empty.scss';
@import './infiniteloading/infiniteloading.scss';
@import './loading/loading.scss';
@import './noticebar/noticebar.scss';
@import './notify/notify.scss';
@import './popover/popover.scss';
@import './popup/popup.scss';
@import './pulltorefresh/pulltorefresh.scss';
@import './resultpage/resultpage.scss';
@import './skeleton/skeleton.scss';
@import './swipe/swipe.scss';
@import './toast/toast.scss';
@import './animate/animate.scss';
@import './animatingnumbers/animatingnumbers.scss';
@import './audio/audio.scss';
@import './avatar/avatar.scss';
@import './avatargroup/avatargroup.scss';
@import './circleprogress/circleprogress.scss';
@import './collapse/collapse.scss';
@import './collapseitem/collapseitem.scss';
@import './countdown/countdown.scss';
@import './ellipsis/ellipsis.scss';
@import './imagepreview/imagepreview.scss';
@import './indicator/indicator.scss';
@import './lottie/lottie.scss';
@import './pagination/pagination.scss';
@import './price/price.scss';
@import './progress/progress.scss';
@import './segmented/segmented.scss';
@import './step/step.scss';
@import './steps/steps.scss';
@import './swiper/swiper.scss';
@import './swiperitem/swiperitem.scss';
@import './table/table.scss';
@import './tag/tag.scss';
@import './tour/tour.scss';
@import './video/video.scss';
@import './virtuallist/virtuallist.scss';
@import './quickenter/quickenter.scss';
@import './avatarcropper/avatarcropper.scss';
@import './barrage/barrage.scss';
@import './card/card.scss';
@import './timedetail/timedetail.scss';
@import './timeselect/timeselect.scss';
@import './trendarrow/trendarrow.scss';
@import './watermark/watermark.scss';
28 changes: 28 additions & 0 deletions src/styles/variables-daojia.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,34 @@ $indicator-dot-active-size: var(--nutui-indicator-dot-active-size,
$indicator-border-radius: var(--nutui-indicator-border-radius,
$radius-xxs) !default;
$indicator-dot-margin: var(--nutui-indicator-dot-margin, $spacing-xxs) !default;
$indicator-dot-border: var(
--nutui-indicator-dot-border,
0.33px solid $color-border
) !default;
$indicator-dot-inactive-color: var(
--nutui-indicator-dot-inactive-color,
#f0f2f7
) !default;
$indicator-track-width: var(
--nutui-indicator-track-width,
24px
) !default;
$indicator-slider-width: var(
--nutui-indicator-slider-width,
8px
) !default;
$indicator-dual-screen-inactive-width: var(
--nutui-indicator-dual-screen-inactive-width,
16px
) !default;
$indicator-placement-gap: var(
--nutui-indicator-placement-gap,
8px
) !default;
$indicator-placement-safe-gap: var(
--nutui-indicator-placement-safe-gap,
12px
) !default;

// menu(✅)
$menu-scroll-fixed-top: var(--nutui-menu-scroll-fixed-top, 0) !default;
Expand Down
Loading
Loading