@honor-minigame/cli
Version:
honor minigame pack cli
121 lines (112 loc) • 4.42 kB
JavaScript
import fs from "fs"
import path from "path"
import { calcDataDigest } from "../common/utils.js"
import { createFullPackage, createSubPackages } from "./package.js"
/**
* 创建完整包和分包列表
* @param appPackageName
* @param subpackageOptions
* @param appIcon
* @returns {{fullPackage: Package, subPackages: *}}
*/
function createPackagesDefinition(appPackageName, subpackageOptions, appIcon) {
const fullPackage = createFullPackage(appPackageName)
let subPackages
if (subpackageOptions && subpackageOptions.length > 0) {
subPackages = createSubPackages(appPackageName, subpackageOptions, appIcon)
}
return {
fullPackage,
subPackages,
}
}
/**
* 检查并生成主入口文件main.js
* 当分包的入口为game.js时,增加main.js入口
* @param {string} projectPath - 项目路径
* @param {Array} subpackageOptions - 分包配置选项
*/
function checkAndGenerateMainJs(projectPath, subpackageOptions) {
if (!subpackageOptions || !subpackageOptions.length) {
return
}
subpackageOptions.forEach((subpkg) => {
const rootPath = path.join(projectPath, subpkg.root)
const gameJsPath = path.join(rootPath, 'game.js')
const mainJsPath = path.join(rootPath, 'main.js')
// 检查是否存在game.js入口
const subRoot = (subpkg.root || '').replace(/\/+$/, '')
if (fs.existsSync(gameJsPath) && !fs.existsSync(mainJsPath)) {
// 生成main.js,内容为require game.js的相对项目根目录路径
fs.writeFileSync(mainJsPath, `require('./${subRoot}/game.js')\n`, 'utf8')
} else if (fs.existsSync(mainJsPath)) {
// main.js已存在时,若内容为 require("./game.js")(单/双引号均可),则拼接上分包root,改为相对项目根目录的路径
const originalContent = fs.readFileSync(mainJsPath, 'utf8').trim()
// 兼容 require("./game.js")、require('./game.js') 以及末尾带分号的情况
if (/^require\(['"]\.\/game\.js['"]\);?$/.test(originalContent)) {
fs.writeFileSync(mainJsPath, `require('./${subRoot}/game.js')\n`, 'utf8')
}
}
})
}
/**
* 将各资源分派给各个要打出来的包
* @param {String[]} files 文件列表
* @param {String} base 文件相对的目录
* @param {Package} fullPackage 整包
* @param {Package[]} subPackages 分包列表
*/
function allocateResourceToPackages(files, base, fullPackage, subPackages) {
files.forEach((fileBuildPath) => {
const fileAbsPath = path.join(base, fileBuildPath)
const fileContentBuffer = fs.readFileSync(fileAbsPath)
const fileContentDigest = calcDataDigest(fileContentBuffer)
// 资源基本信息
const resourceInfo = [fileBuildPath, fileContentBuffer, fileContentDigest]
if (!fileBuildPath.match(/build\//)) {
fullPackage.addResource(...resourceInfo)
}
// 标志此资源是否属于主包,需要放入主包
let belongToBasePkg = true
if (subPackages) {
// 遍历除主包整包外的分包,判断此文件是否属于某个分包的
for (let i = 1; i < subPackages.length; i++) {
const pkg = subPackages[i]
if (
pkg.standalone &&
(fileBuildPath === "manifest.json" ||
(pkg.icon && pkg.icon.indexOf(fileBuildPath) > 0))
) {
pkg.addResource(...resourceInfo)
}
if (pkg.subMatch.test(fileBuildPath)) {
belongToBasePkg = false
// 保留第一级
if (pkg.isPlugin) {
resourceInfo[0] = fileBuildPath.substring(fileBuildPath.indexOf("/") + 1)
} else {
resourceInfo[0] = fileBuildPath
}
pkg.addResource(...resourceInfo)
break
}
}
if (belongToBasePkg) {
const basePkg = subPackages[0]
basePkg.addResource(...resourceInfo)
}
}
})
// 判断每个包的资源是否为空,如果为空抛出异常,停止打包
if (subPackages) {
subPackages.forEach((item) => {
const resource = item.resourceList
if (!resource.length) {
throw new Error(
`### HONOR PACK ### 分包失败:分包${item.fileName}内不包含任何资源`
)
}
})
}
}
export { createPackagesDefinition, allocateResourceToPackages, checkAndGenerateMainJs }