优化: 项目文件树/依赖图组件 + 灵感对抗校验 + 小程序脚本 + 模块管理
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
//! post-build 修复脚本:处理微信小程序构建产物的兼容性问题
|
||||
//!
|
||||
//! 背景:marked v18+ 含 lookbehind 检测 `new RegExp("(?<=1)(?<!1)")`,
|
||||
//! 微信开发者工具转译器静态检测到 `(?<=` 字符串 → 误判需 @swc/helpers/_wrap_reg_exp
|
||||
//! helper → 注入 require → 产物无此模块 → 小程序白屏。
|
||||
//!
|
||||
//! 微信基础库运行时不支持 lookbehind,marked 本就走降级路径(Te=false)。
|
||||
//! 本脚本把产物里的 lookbehind 检测替换为 Te=false,绕过微信工具静态误判,
|
||||
//! 同时保留 marked 完整功能(运行时本就降级)。
|
||||
//!
|
||||
//! 用法:build 后运行 `node scripts/fix-mp-build.cjs`
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const BUILD_DIR = path.join(__dirname, '..', 'dist', 'build', 'mp-weixin')
|
||||
const VENDOR = path.join(BUILD_DIR, 'common', 'vendor.js')
|
||||
|
||||
function fixLookbehind() {
|
||||
if (!fs.existsSync(VENDOR)) {
|
||||
console.warn('[fix-mp-build] vendor.js 不存在,跳过:', VENDOR)
|
||||
return
|
||||
}
|
||||
let src = fs.readFileSync(VENDOR, 'utf8')
|
||||
const before = src
|
||||
// marked v18 lookbehind 检测 `var Te=((l="")=>{try{return!!new RegExp("(?<=1)(?<!1)"+l)}catch{return!1}})()`
|
||||
// 替换为 `var Te=false`(强制降级,微信基础库不支持 lookbehind)
|
||||
src = src.replace(
|
||||
/var Te=\(\([^)]*\)=>\{try\{return!!new RegExp\("\(\?<=1\)\(\?<!1\)"[^}]*\}\}\)\)\(\),?/,
|
||||
'var Te=false,'
|
||||
)
|
||||
if (src === before) {
|
||||
// 未命中(压缩名可能不是 Te),退而按字符串替换 lookbehind 检测
|
||||
src = src.replace(/new RegExp\("\(\?<=1\)\(\?<!1\)"[^)]*\)/g, 'false')
|
||||
}
|
||||
// 关键:marked 条件分支里还有 `(?<!`)` lookbehind 字面量(Te 为 true 时的分支)。
|
||||
// 微信工具静态检测到任何 `(?<=` / `(?<!` 字符都会注入 swc helper 误判。
|
||||
// 把所有 lookbehind 字面量替换为非 lookbehind 等价形式。
|
||||
// (?:x) 合法不 throw;但该分支仅 Te=true 时用,运行时 Te=false 恒走降级分支,
|
||||
// 替换后行为不变,同时消除微信工具的静态触发器。
|
||||
src = src.replace(/\(\?<!`\)/g, '(?:x)')
|
||||
src = src.replace(/\(\?<=1\)\(\?<!1\)/g, '(?:1)')
|
||||
// 命名捕获组(ES2018)也触发 _wrap_reg_exp。marked v18 用 `(?<a>`+)[^`]+\k<a>` 匹配代码围栏。
|
||||
// 转为编号捕获组 `(`+)\1`(ES5 兼容,无命名捕获组,行为等价)。
|
||||
// 通用: (?<name>...) → (...), \k<name> → \N(按捕获组序编号,这里只有 a/b 两组)
|
||||
src = src.replace(/\(\?<a>\`\+\)\[^\`\]\+\\k<a>/g, '(`+)\\1')
|
||||
src = src.replace(/\(\?<b>\`\+\)\[^\`\]\+\\k<b>/g, '(`+)\\1')
|
||||
// 兜底:任何残留命名捕获组 (?<name> 或 \k<name> 转为无命名
|
||||
src = src.replace(/\(\?<[a-z][a-z0-9_]*>/g, '(')
|
||||
src = src.replace(/\\k<[a-z]>/g, '\\1')
|
||||
if (src !== before) {
|
||||
fs.writeFileSync(VENDOR, src)
|
||||
console.log('[fix-mp-build] vendor.js lookbehind 已全部替换(检测+条件分支)')
|
||||
} else {
|
||||
console.warn('[fix-mp-build] 未找到 lookbehind(可能已处理或格式不同)')
|
||||
}
|
||||
}
|
||||
|
||||
// 清理手动补的 @swc/helpers(不再需要,避免污染)
|
||||
function cleanupSwcHelpers() {
|
||||
const swcDir = path.join(BUILD_DIR, 'common', '@swc', 'helpers')
|
||||
if (fs.existsSync(swcDir)) {
|
||||
fs.rmSync(swcDir, { recursive: true, force: true })
|
||||
console.log('[fix-mp-build] 已清理手动补的 @swc/helpers')
|
||||
}
|
||||
}
|
||||
|
||||
fixLookbehind()
|
||||
cleanupSwcHelpers()
|
||||
Reference in New Issue
Block a user