niucloud/uni-app/scripts/swap-addon-pages.cjs
wangchen14709853322 5ed9a0ba81 v2.0-beta-20260626
v2框架公测版测试流程请看v2.0-beta.md
2026-07-01 12:25:30 +08:00

157 lines
4.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Core 构建前将插件真实页面替换为桥接页,构建后还原。
* uni-app 按 pages.json 的 subPackage root + path 扫描磁盘上的 .vue 文件。
*
* 备份目录放在系统 temp不在项目内避免 Vite 扫描 .build 时 EPERM。
*/
const fs = require('fs')
const path = require('path')
const os = require('os')
const crypto = require('crypto')
const { ROOT, parsePagesJson, BRIDGE_ADDON_ROOT } = require('./addon-utils.cjs')
const LEGACY_BACKUP_ROOT = path.join(ROOT, '.build', 'addon-pages-backup')
const SWAP_STATE_FILE = path.join(ROOT, '.build', 'addon-pages-swap.json')
const BRIDGE_ROOT = BRIDGE_ADDON_ROOT
function getBackupRoot() {
const hash = crypto.createHash('md5').update(ROOT).digest('hex').slice(0, 12)
return path.join(os.tmpdir(), 'uni-app-addon-pages-backup', hash)
}
function rmDir(dir) {
if (!fs.existsSync(dir)) return
fs.rmSync(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 })
}
function copyDir(src, dest) {
fs.mkdirSync(dest, { recursive: true })
for (const name of fs.readdirSync(src)) {
const s = path.join(src, name)
const d = path.join(dest, name)
if (fs.statSync(s).isDirectory()) copyDir(s, d)
else fs.copyFileSync(s, d)
}
}
function moveDir(src, dest) {
rmDir(dest)
fs.mkdirSync(path.dirname(dest), { recursive: true })
try {
fs.renameSync(src, dest)
} catch (e) {
if (e.code !== 'EPERM' && e.code !== 'EXDEV') throw e
copyDir(src, dest)
rmDir(src)
}
}
function readSwapState() {
if (!fs.existsSync(SWAP_STATE_FILE)) return null
try {
return JSON.parse(fs.readFileSync(SWAP_STATE_FILE, 'utf-8'))
} catch {
return null
}
}
function writeSwapState(state) {
fs.mkdirSync(path.dirname(SWAP_STATE_FILE), { recursive: true })
fs.writeFileSync(SWAP_STATE_FILE, JSON.stringify(state, null, 2) + '\n', 'utf-8')
}
function clearSwapState() {
if (fs.existsSync(SWAP_STATE_FILE)) fs.unlinkSync(SWAP_STATE_FILE)
}
function listAddonSubPackageRoots() {
const pagesJson = parsePagesJson()
const roots = new Set()
for (const sub of pagesJson.subPackages || []) {
if (sub.root?.startsWith('addon/')) roots.add(sub.root)
}
return [...roots].sort()
}
function toBackupPagesDir(backupRoot, root) {
return path.join(backupRoot, root.replace(/^addon\//, ''), 'pages')
}
function toBridgePagesDir(root) {
return path.join(BRIDGE_ROOT, root.replace(/^addon\//, ''), 'pages')
}
function toSrcPagesDir(root) {
return path.join(ROOT, 'src', root, 'pages')
}
function applySwap() {
const backupRoot = getBackupRoot()
rmDir(backupRoot)
let count = 0
for (const root of listAddonSubPackageRoots()) {
const pagesDir = toSrcPagesDir(root)
const bridgePages = toBridgePagesDir(root)
if (!fs.existsSync(pagesDir) || !fs.existsSync(bridgePages)) continue
const backupDir = toBackupPagesDir(backupRoot, root)
moveDir(pagesDir, backupDir)
copyDir(bridgePages, pagesDir)
count++
}
writeSwapState({ backupRoot, appliedAt: new Date().toISOString(), roots: listAddonSubPackageRoots() })
console.log(`[swap-addon-pages] applied ${count} addon subPackage page dirs -> bridge (${backupRoot})`)
}
function restoreSwap() {
const state = readSwapState()
const backupRoot = state?.backupRoot || getBackupRoot()
if (!fs.existsSync(backupRoot)) {
clearSwapState()
return 0
}
let count = 0
const roots = state?.roots?.length ? state.roots : listAddonSubPackageRoots()
for (const root of roots) {
const backupDir = toBackupPagesDir(backupRoot, root)
const pagesDir = toSrcPagesDir(root)
if (!fs.existsSync(backupDir)) continue
rmDir(pagesDir)
fs.mkdirSync(path.dirname(pagesDir), { recursive: true })
moveDir(backupDir, pagesDir)
count++
}
rmDir(backupRoot)
clearSwapState()
if (count) {
console.log(`[swap-addon-pages] restored ${count} addon subPackage page dirs`)
}
return count
}
const cmd = process.argv[2] || 'apply'
if (require.main === module) {
if (cmd === 'apply') applySwap()
else if (cmd === 'restore') restoreSwap()
else if (cmd === 'status') {
const state = readSwapState()
console.log('[swap-addon-pages] state:', state || 'idle')
console.log('[swap-addon-pages] legacy backup exists:', fs.existsSync(LEGACY_BACKUP_ROOT))
} else {
console.error('Usage: node swap-addon-pages.cjs apply|restore|status')
process.exit(1)
}
}
module.exports = {
applySwap,
restoreSwap,
listAddonSubPackageRoots,
getBackupRoot,
LEGACY_BACKUP_ROOT
}