-
Notifications
You must be signed in to change notification settings - Fork 4.9k
fix(taro-platform-h5): 修复windows开发环境Taro对象上等方法不可用 #18153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthrough本次变更在 Vite 配置的 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Vite as Vite / Plugin
participant Transform as transform(id)
participant Norm as normalizePath
participant Check as conditionCheck
participant Babel as Babel.transform
Vite->>Transform: 调用 transform(id)
Transform->>Norm: 去除前导 \u0000、剥离 ?query、替换 "\" -> "/"
Transform->>Norm: 同步规范化 viteCompilerContext.sourceDir
Norm-->>Transform: 返回 cleanId, normalizedSourceDir
Transform->>Check: 使用 cleanId.startsWith(normalizedSourceDir) && ext check(原 id 的扩展名判断)
alt 条件成立
Transform->>Babel: 调用 Babel.transform(cleanId)
Babel-->>Transform: 返回变换结果
else 不满足
Transform-->>Vite: 跳过处理,返回 null
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 分钟 Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
packages/taro-platform-h5/src/program.ts (2)
233-236: 可选:同时将 Babel transform 的 filename 切换为 cleanId为避免 filename 携带查询参数或反斜杠导致的映射异常,建议将 transformAsync 的 filename 设置为 cleanId(非必需,但更一致):
// 下面代码在当前 if 分支内: // 建议将 // filename: id, // 改为 filename: cleanId,说明:这项改动不在本变更行内,实现时请在 238-246 行对应的 transformAsync 调用处调整。
233-235: 可选:兼容 Vite 的 /@fs/ 与 file:// 前缀在某些场景(特别是跨根目录或依赖解析)Vite 的模块 id 可能以 /@fs/ 或 file:// 开头。为进一步增强稳健性,可在清洗阶段顺便处理:
if (cleanId.startsWith('/@fs/')) { cleanId = cleanId.slice('/@fs/'.length) } // 如需支持 file:// URL,可配合 node:url: /* import { fileURLToPath } from 'node:url' if (cleanId.startsWith('file://')) { try { cleanId = fileURLToPath(cleanId) } catch {} } */注:这是增强项,当前修复不依赖此改动。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/taro-platform-h5/src/program.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ianzone
PR: NervJS/taro#17993
File: .github/advanced-issue-labeler.yml:20-63
Timestamp: 2025-07-11T14:04:05.557Z
Learning: 在 NervJS/taro 项目的 .github/advanced-issue-labeler.yml 中,平台标签被设计为可以多个共存。当用户选择"所有平台"时,系统会同时应用多个平台标签(如 T-h5, T-rn, T-weapp 等),这是期望的行为而非冲突。同样,"所有小程序"也会为小程序相关的标签应用多个标签。这种设计有助于跨平台问题的管理和维护者关注。
📚 Learning: 2025-08-08T02:32:58.207Z
Learnt from: ianzone
PR: NervJS/taro#18146
File: packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/package.json:12-14
Timestamp: 2025-08-08T02:32:58.207Z
Learning: 在 Taro 项目的 pnpm 工作区中,Vitest 相关依赖(vitest 和 vitest/coverage-istanbul)被管理在根目录的 package.json 中,而不是各个子包的 devDependencies 中。这是 monorepo 中依赖提升的标准做法。
Applied to files:
packages/taro-platform-h5/src/program.ts
📚 Learning: 2025-05-25T18:02:31.387Z
Learnt from: ianzone
PR: NervJS/taro#17746
File: packages/taro-runtime/tsdown.config.ts:10-16
Timestamp: 2025-05-25T18:02:31.387Z
Learning: 在 taro-runtime 包的 tsdown 配置中,必须禁用 treeshake 来保留 dom-external/index.js 文件。
Applied to files:
packages/taro-platform-h5/src/program.ts
🧬 Code Graph Analysis (1)
packages/taro-platform-h5/src/program.ts (1)
packages/taro-vite-runner/src/harmony/babel.ts (1)
viteCompilerContext(9-94)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build Rust Binding / stable - x86_64-apple-darwin
- GitHub Check: Build Rust Binding / stable - x86_64-pc-windows-msvc
🔇 Additional comments (1)
packages/taro-platform-h5/src/program.ts (1)
227-235: 路径规范化与清洗方向正确,能有效修复 Windows 上的识别问题
- 去除前导 NUL 字符、剥离查询参数、统一分隔符为正斜杠,以及对 sourceDir 做同样处理,都是必要步骤,思路到位。
| cleanId = cleanId.split('?')[0].replace(/\\/g, '/') // 👈 替换斜杠方向 | ||
|
|
||
| const normalizedSourceDir = viteCompilerContext.sourceDir.replace(/\\/g, '/') // 👈 替换斜杠方向 | ||
| if (cleanId.startsWith(normalizedSourceDir) && exts.some((ext) => id.includes(ext))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
用路径边界判断与基于 cleanId 的后缀匹配,避免误判与平台差异
当前仍然存在两处潜在问题:
- 目录前缀误判:cleanId.startsWith(normalizedSourceDir) 在 sourceDir 是另一路径前缀时会误命中(如 C:/src 与 C:/src2)。
- 扩展名匹配:仍用原始 id.includes(ext) 且为包含匹配,可能出现误判;亦未与上面的 cleanId 清洗保持一致。
建议在本段内改为“边界安全的目录判断 + 基于 cleanId 的结尾扩展匹配”,示例 diff 如下:
- cleanId = cleanId.split('?')[0].replace(/\\/g, '/') // 👈 替换斜杠方向
+ // 统一斜杠并去掉查询参数,便于跨平台匹配
+ cleanId = cleanId.split('?')[0].replace(/\\/g, '/')
- const normalizedSourceDir = viteCompilerContext.sourceDir.replace(/\\/g, '/') // 👈 替换斜杠方向
- if (cleanId.startsWith(normalizedSourceDir) && exts.some((ext) => id.includes(ext))) {
+ // 统一 sourceDir,并确保以路径边界比较,避免前缀相似导致的误命中
+ const normalizedSourceDir = viteCompilerContext.sourceDir.replace(/\\/g, '/').replace(/\/+$/, '')
+ const inSource = cleanId === normalizedSourceDir || cleanId.startsWith(normalizedSourceDir + '/')
+
+ // 更稳健的扩展名判断:基于 cleanId 且只匹配结尾
+ const extsPattern = new RegExp(`\\.(?:${exts.map((e: string) => e.replace(/^\\./, '')).join('|')})$`, 'i')
+
+ if (inSource && extsPattern.test(cleanId)) {这样可同时解决:
- Windows 路径前缀误匹配;
- 查询参数与分隔符已清洗,扩展名判断与之保持一致;
- 降低 includes 带来的误匹配风险。
📝 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.
| cleanId = cleanId.split('?')[0].replace(/\\/g, '/') // 👈 替换斜杠方向 | |
| const normalizedSourceDir = viteCompilerContext.sourceDir.replace(/\\/g, '/') // 👈 替换斜杠方向 | |
| if (cleanId.startsWith(normalizedSourceDir) && exts.some((ext) => id.includes(ext))) { | |
| // 统一斜杠并去掉查询参数,便于跨平台匹配 | |
| cleanId = cleanId.split('?')[0].replace(/\\/g, '/') | |
| // 统一 sourceDir,并确保以路径边界比较,避免前缀相似导致的误命中 | |
| const normalizedSourceDir = viteCompilerContext.sourceDir | |
| .replace(/\\/g, '/') | |
| .replace(/\/+$/, '') | |
| const inSource = | |
| cleanId === normalizedSourceDir || | |
| cleanId.startsWith(normalizedSourceDir + '/') | |
| // 更稳健的扩展名判断:基于 cleanId 且只匹配结尾 | |
| const extsPattern = new RegExp( | |
| `\\.(?:${exts | |
| .map((e: string) => e.replace(/^\./, '')) | |
| .join('|')})$`, | |
| 'i' | |
| ) | |
| if (inSource && extsPattern.test(cleanId)) { |
🤖 Prompt for AI Agents
In packages/taro-platform-h5/src/program.ts around lines 233 to 236, the current
check using cleanId.startsWith(normalizedSourceDir) can cause false positives
when sourceDir is a prefix of another path, and the extension check uses
id.includes(ext) which is an imprecise substring match. To fix this, replace the
startsWith check with a boundary-safe directory comparison (e.g., ensure the
character after normalizedSourceDir in cleanId is a path separator or the string
ends) and change the extension check to use cleanId.endsWith(ext) to accurately
match file extensions after cleaning the path. This ensures correct path prefix
matching and precise extension validation.
💡 Verification agent
🧩 Analysis chain
建议对全仓库同类判定做一致性巡检
为避免类似 Windows 路径问题在其它插件/分支重复出现,建议巡检是否还有基于 id.startsWith(sourceDir) 的直接字符串比较,并统一采用“清洗 + 路径边界 + 扩展名后缀”的写法。
可用以下脚本在仓库检索潜在位置,人工复核是否需要采用同样规范化处理:
🏁 Script executed:
#!/bin/bash
# 搜索基于 sourceDir 的 startsWith 判定
rg -n --no-heading "startsWith\\(.*sourceDir" -A 2 -B 2
# 搜索对 id 的扩展名 includes 判定
rg -n --no-heading "exts\\.some\\(.*id\\.includes\\(" -A 2 -B 2
# 搜索 Vite 插件 transform 中对 id 的处理(便于发现未清洗的地方)
rg -n --no-heading "async?\\s+transform\\s*\\(code,\\s*id\\)" -A 20 -B 2Length of output: 6180
统一路径前缀匹配时的清洗及后缀校验
为避免 Windows 下反斜杠和 query 参数导致匹配失效,全仓库所有基于 sourceDir 的 startsWith 判定都应按以下流程处理:
- 去除特殊前缀(如
\u0000)和?及后续参数 - 将所有
\统一替换为/ - 使用清洗后的路径做
startsWith(normalizedSourceDir),并尽量结合路径边界(如normalizedSourceDir + '/') - 再做扩展名后缀过滤(
exts.some(ext => cleanId.endsWith(ext)))
以下位置需同样引入该规范化处理:
- packages/taro-vite-runner/src/harmony/babel.ts(
transform钩子中对id.startsWith(viteCompilerContext.sourceDir)及后续exts.some(id.includes)) - packages/taro-vite-runner/src/h5/config.ts(
entryFileNames中对facadeModuleId.startsWith(sourceDir)的判断) - (packages/taro-platform-h5/src/program.ts 已按规范处理,无需改动)
可用脚本复核并定位所有潜在场景:
rg -n --no-heading "startsWith\\(.*sourceDir" -A2 -B2
rg -n --no-heading "facadeModuleId\\?\\.startsWith" -A2 -B2🤖 Prompt for AI Agents
In packages/taro-vite-runner/src/harmony/babel.ts and
packages/taro-vite-runner/src/h5/config.ts, locate all instances where sourceDir
is used with startsWith for path prefix matching and ensure the following
normalization steps are applied: first remove special prefixes like \u0000 and
query parameters starting with '?', then replace all backslashes '\' with
forward slashes '/', and use the cleaned path for startsWith checks combined
with a trailing '/' to ensure path boundary correctness. After that, perform
extension suffix filtering using endsWith on the cleaned path. This will align
these files with the normalization approach already implemented in
packages/taro-platform-h5/src/program.ts.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #18153 +/- ##
========================================
Coverage 55.06% 55.06%
========================================
Files 416 416
Lines 21563 21563
Branches 5285 5289 +4
========================================
Hits 11873 11873
- Misses 8038 8173 +135
+ Partials 1652 1517 -135
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
这个 PR 做了什么? (简要描述所做更改)
解决Windows开发环境中Taro.request、Taro.setStorageSync、Taro.getStorageSync、Taro.showToast等API方法不可用的问题。核心原因在于Windows系统路径使用反斜杠(\)而非正斜杠(/),同时路径中可能存在空格字符,导致相关模块无法被正确识别和导入。
这个 PR 是什么类型? (至少选择一个)
这个 PR 涉及以下平台:
Summary by CodeRabbit