mirror of
https://gitee.com/niucloud-team/niucloud.git
synced 2026-08-01 20:15:49 +00:00
171 lines
5.5 KiB
JavaScript
171 lines
5.5 KiB
JavaScript
/**
|
|
* 双产物组装:框架包 A + 全量 common B + 插件分包 B → dist/build/mp-weixin/
|
|
*/
|
|
const fs = require('fs')
|
|
const path = require('path')
|
|
const {
|
|
ROOT,
|
|
MP_OUT_BUILD,
|
|
MP_CORE_DIR,
|
|
MP_FRAMEWORK_DIR,
|
|
MP_FULL_DIR,
|
|
MP_ADDONS_DIR,
|
|
MP_LOCK_PATH,
|
|
rmDir,
|
|
copyDir,
|
|
readJson,
|
|
writeJson,
|
|
readAppJson,
|
|
getAppSubPackages,
|
|
setAppSubPackages,
|
|
stripOrphanAddonSubpackages
|
|
} = require('./mp-utils.cjs')
|
|
const { validateRequires } = require('./scan-mp-requires.cjs')
|
|
const { applyMpWeixinPost } = require('./mp-weixin-post.cjs')
|
|
|
|
function loadMeta(dir) {
|
|
const p = path.join(dir, 'mp-build-meta.json')
|
|
return fs.existsSync(p) ? readJson(p) : null
|
|
}
|
|
|
|
function loadAddonManifest(key) {
|
|
const p = path.join(MP_CORE_DIR, 'mp-addons', key, 'manifest.json')
|
|
const legacy = path.join(MP_ADDONS_DIR, key, 'manifest.json')
|
|
const manifestPath = fs.existsSync(p) ? p : legacy
|
|
if (!fs.existsSync(manifestPath)) {
|
|
console.error(`[assemble-mp-dual] missing mp-addons/${key}/manifest.json — run build-mp-addon ${key}`)
|
|
process.exit(1)
|
|
}
|
|
return readJson(manifestPath)
|
|
}
|
|
|
|
function copyAddonPayload(outDir, key) {
|
|
const manifest = loadAddonManifest(key)
|
|
const pkgDir = fs.existsSync(path.join(MP_CORE_DIR, 'mp-addons', key))
|
|
? path.join(MP_CORE_DIR, 'mp-addons', key)
|
|
: path.join(MP_ADDONS_DIR, key)
|
|
for (const root of manifest.roots) {
|
|
const src = path.join(pkgDir, root)
|
|
const dest = path.join(outDir, root)
|
|
if (!fs.existsSync(src)) {
|
|
console.error(`[assemble-mp-dual] missing extracted ${key}/${root}`)
|
|
process.exit(1)
|
|
}
|
|
rmDir(dest)
|
|
copyDir(src, dest)
|
|
}
|
|
return manifest
|
|
}
|
|
|
|
function mergeAppJson(frameworkApp, fullApp, selectedRoots) {
|
|
const rootSet = new Set(selectedRoots)
|
|
const merged = { ...frameworkApp }
|
|
const fullSubs = getAppSubPackages(fullApp)
|
|
const mergedSubs = fullSubs.filter((s) => rootSet.has(s.root))
|
|
setAppSubPackages(merged, mergedSubs)
|
|
|
|
return merged
|
|
}
|
|
|
|
function validateLock(frameworkMeta, addonManifests) {
|
|
if (!fs.existsSync(MP_LOCK_PATH)) return
|
|
const lock = readJson(MP_LOCK_PATH)
|
|
if (lock.framework?.buildId && frameworkMeta?.buildId && lock.framework.buildId !== frameworkMeta.buildId) {
|
|
console.warn('[assemble-mp-dual] warn: framework buildId differs from lock')
|
|
}
|
|
for (const m of addonManifests) {
|
|
if (lock.full?.buildId && m.buildId && lock.full.buildId !== m.buildId) {
|
|
console.warn(`[assemble-mp-dual] warn: addon ${m.key} buildId differs from lock.full`)
|
|
}
|
|
}
|
|
}
|
|
|
|
function main() {
|
|
const keys = process.argv.slice(2)
|
|
if (!keys.length) {
|
|
console.error('Usage: node assemble-mp-dual.cjs <addon-key> [addon-key...]')
|
|
process.exit(1)
|
|
}
|
|
|
|
if (!fs.existsSync(MP_CORE_DIR)) {
|
|
console.error('[assemble-mp-dual] missing dist/build/mp-core — run build-mp-framework')
|
|
process.exit(1)
|
|
}
|
|
if (!fs.existsSync(MP_FULL_DIR)) {
|
|
console.error('[assemble-mp-dual] missing dist/.mp-full — run build-mp-full')
|
|
process.exit(1)
|
|
}
|
|
|
|
const frameworkMeta = loadMeta(MP_CORE_DIR)
|
|
const fullMeta = loadMeta(MP_FULL_DIR)
|
|
const frameworkApp = readAppJson(MP_CORE_DIR)
|
|
const fullApp = readAppJson(MP_FULL_DIR)
|
|
|
|
console.log('[assemble-mp-dual] copy framework -> output')
|
|
rmDir(MP_OUT_BUILD)
|
|
copyDir(MP_CORE_DIR, MP_OUT_BUILD)
|
|
stripOrphanAddonSubpackages(MP_OUT_BUILD)
|
|
|
|
const fullCommon = path.join(MP_FULL_DIR, 'common')
|
|
const outCommon = path.join(MP_OUT_BUILD, 'common')
|
|
if (fs.existsSync(fullCommon)) {
|
|
rmDir(outCommon)
|
|
copyDir(fullCommon, outCommon)
|
|
console.log('[assemble-mp-dual] common/ <- full build')
|
|
} else {
|
|
console.warn('[assemble-mp-dual] warn: full build has no common/')
|
|
}
|
|
|
|
const manifests = []
|
|
const allRoots = []
|
|
|
|
for (const key of keys) {
|
|
const manifest = copyAddonPayload(MP_OUT_BUILD, key)
|
|
manifests.push(manifest)
|
|
allRoots.push(...manifest.roots)
|
|
}
|
|
|
|
validateLock(frameworkMeta, manifests)
|
|
|
|
const mergedApp = mergeAppJson(frameworkApp, fullApp, allRoots)
|
|
writeJson(path.join(MP_OUT_BUILD, 'app.json'), mergedApp)
|
|
console.log(`[assemble-mp-dual] app.json subPackages: ${getAppSubPackages(mergedApp).length}`)
|
|
|
|
const allRequirePaths = new Set()
|
|
const allForbidden = new Set()
|
|
for (const m of manifests) {
|
|
for (const p of m.deps?.requirePaths || []) allRequirePaths.add(p)
|
|
for (const p of m.deps?.forbiddenPaths || []) allForbidden.add(p)
|
|
}
|
|
|
|
const validation = validateRequires(
|
|
MP_OUT_BUILD,
|
|
[...allRequirePaths],
|
|
[...allForbidden]
|
|
)
|
|
if (!validation.ok) {
|
|
if (validation.missing.length) {
|
|
console.error('[assemble-mp-dual] missing require targets:', validation.missing.slice(0, 20))
|
|
}
|
|
if (validation.forbiddenPaths.length) {
|
|
console.error('[assemble-mp-dual] cross-addon requires:', validation.forbiddenPaths)
|
|
}
|
|
process.exit(1)
|
|
}
|
|
console.log('[assemble-mp-dual] require validation OK')
|
|
|
|
applyMpWeixinPost(MP_OUT_BUILD)
|
|
|
|
writeJson(path.join(MP_OUT_BUILD, 'mp-assemble-meta.json'), {
|
|
time: new Date().toISOString(),
|
|
frameworkBuildId: frameworkMeta?.buildId,
|
|
fullBuildId: fullMeta?.buildId,
|
|
addonKeys: keys,
|
|
roots: allRoots
|
|
})
|
|
|
|
console.log(`[assemble-mp-dual] OK -> ${path.relative(ROOT, MP_OUT_BUILD)}/`)
|
|
}
|
|
|
|
main()
|