@honor-minigame/cli
Version:
honor minigame pack cli
116 lines (103 loc) • 4.82 kB
JavaScript
import path from 'path'
import fs from 'fs-extra'
import * as paths from '../lib/paths.js'
import { MAIN, RPK, RPK_SIGNED, LOG_TITLE } from '../lib/constanst.js'
import readdir, { noDotSymbolsFiles, noDotFiles } from '../lib/readdir.js'
import rpk from '../lib/rpk.js'
import { info } from '../../utils/logger.js'
class ZipWebpackPlugin {
constructor(options) {
this.options = options
}
apply(compiler) {
const pluginName = 'ZipWebpackPlugin'
/**
* 获取打原整包的配置
* @param {Boolean} isRelease 是否是release模式
* @param {String} packageName 包名
* @param {Boolean} singlePackage 是否是打原整包
* @param {Array} subpackages 分包配置
* @param {String} pluginPath 插件包路径
* @param {Object} manifest 小游戏配置文件
* @param {String} buildType 小游戏构建类型
*/
const { isRelease, packageName, singlePackage, subpackages, manifest, buildType, compileStartTime } = this.options
compiler.hooks.afterEmit.tapPromise(pluginName, compilation => {
// 签名文件
const signFiles = {
debug: {
privatekey: paths.DEBUG_PRIVATE_KEY,
certificate: paths.DEBUG_CERTIFICATE
},
release: {
privatekey: paths.RELEASE_PRIVATE_KEY,
certificate: paths.RELEASE_CERTIFICATE
}
}
// 编译完成开始打包,打包前先校验签名文件是否存在
const signFile = signFiles[isRelease ? 'release' : 'debug']
// debug包的后缀 .rpk release包的后缀 .signed.rpk
// buildType 默认值为release
let RPK_SIGNED_NEW = RPK_SIGNED
let RPK_NEW = RPK
if (buildType && !buildType.includes('release')) {
RPK_SIGNED_NEW = `.${buildType}${RPK_SIGNED}`
RPK_NEW = `.${buildType}${RPK}`
}
const ext = isRelease ? RPK_SIGNED_NEW : RPK_NEW
if (!fs.existsSync(signFile.privatekey)) {
throw (new Error(`${LOG_TITLE}缺少私钥文件, 打包失败: ${signFile.privatekey}`))
}
if (!fs.existsSync(signFile.certificate)) {
throw (new Error(`${LOG_TITLE}缺少证书文件, 打包失败: ${signFile.certificate}`))
}
return new Promise(resolve => {
info(`${LOG_TITLE}${singlePackage ? '原整包编译完成,开始生成原整包' : '分包编译完成,开始生成分包'} 耗时:${(new Date()).valueOf() - compileStartTime}ms`)
// 遍历出build目录所有文件
const files = readdir(paths.BUILD, isRelease ? noDotSymbolsFiles : noDotFiles)
// 如果是打原整包
if (singlePackage) {
// 打原整包到temp目录 有插件包的也走这个逻辑,因为需要打个兼容的包
rpk(`${packageName}${RPK}`, files, paths.BUILD, paths.TEMP, signFile, manifest).then(resolve)
} else {
// 如果存在分包,那么就打出各个分包,并和原整包一起再打一个rpk,到dist目录
const pkgRes = []
// 根据分包配置,找到各个包对应的资源。执行如下操作后,files中剩下的即为主包的资源
subpackages.forEach(({ name, root }) => {
const matchFiles = []
for (let index = files.length - 1; index >= 0; index--) {
const file = files[index]
const ext = path.extname(root)
if (isRelease && !noDotSymbolsFiles(file, 0, path.resolve(paths.BUILD, root))) {
continue
}
if (ext === '' && file.indexOf(root) === 0) {
// 如果是目录,校验路径
matchFiles.push(files.splice(index, 1)[0])
} else if (ext !== '' && (file === root || file === `${root}.map`)) {
// 如果是文件,校验是否为 xxx.js 和 xxx.js.map
matchFiles.push(files.splice(index, 1)[0])
}
}
pkgRes.push({
name,
matchFiles
})
})
// 打各个分包
const rpkPromise = pkgRes.map(({ name, matchFiles }) => {
return rpk(`${name}${RPK}`, matchFiles, paths.BUILD, paths.TEMP, signFile)
})
const promiseArr = [rpk(`${MAIN}${RPK}`, files, paths.BUILD, paths.TEMP, signFile, manifest)]
// 分包都打好后,连原整包一起打一个整包
Promise.all([...rpkPromise, ...promiseArr]).then(function () {
rpk(`${packageName}${ext}`, readdir(paths.TEMP), paths.TEMP, paths.DIST, signFile).then(() => {
resolve()
})
})
}
})
})
}
}
export default ZipWebpackPlugin