UNPKG

wpsjs

Version:

用于开发wps加载项的工具包

209 lines (186 loc) 7.55 kB
const inquirer = require('inquirer') const fs = require('fs') const fsEx = require('fs-extra') const path = require('path') const _7z = require('node-7z'); const _7zBin = require('7zip-bin') const jsUtil = require('./util.js') let projectCfg = jsUtil.projectCfg() const chalk = require('chalk'); const { serialize } = require('v8'); const buildDirectory = jsUtil.GetBuildDir() async function build(cmd) { if (cmd.parent.rawArgs[cmd.parent.rawArgs.length - 1].includes("exe")) { if (false == new RegExp("^[!-~]+$").test(projectCfg.name)){ console.log(`${chalk.red("项目名只能是字母、数字和下划线")}...`) return } buildwithSelfArchive() return } inquirer.prompt({ name: 'pluginType', type: 'list', message: `选择 WPS 加载项发布类型:`, choices: [{ name: '在线插件', value: 'online' }, { name: '离线插件', value: 'offline' } ] }).then(answers => { return buildWithArgs(answers) }).then(buildDir=>{ console.log(chalk.cyan(`\n==>> 编译成功。请将目录${buildDir}下的文件署到服务器...`)) }) } async function buildWithArgs(answers) { return new Promise((r,j)=>{ let debugTemp = jsUtil.GetDebugTempPath(true); fsEx.removeSync(debugTemp) let curDir = process.cwd() let buildDir = curDir if (projectCfg.scripts && typeof projectCfg.scripts.build == 'string') { let buildCmd = projectCfg.scripts.build.trim(); if (buildCmd.includes("vite")) { buildDir = require('./buildvue')(answers) } else if (buildCmd.includes("react-scripts")) { buildDir = require('./buildreact')(answers) } } let publishRoot = path.resolve(curDir, jsUtil.GetPublishDir()); fsEx.removeSync(publishRoot); let buildRoot = path.resolve(curDir, buildDirectory); let distPath = buildRoot if (answers.pluginType == "offline") distPath = path.resolve(buildRoot, `${projectCfg.name}_${projectCfg.version}`) fsEx.removeSync(buildRoot) fs.readdir(buildDir, (_, files) => { files.forEach(file => { if (file != buildDirectory && file != "node_modules" && file != ".vscode" && file != ".git" && file != "package.json" && file != "package-lock.json") { const srcPath = path.resolve(buildDir, file) fsEx.copySync(srcPath, path.resolve(distPath, file)) } }) if (answers.pluginType == "offline") { let path7z = path.resolve(buildRoot, `${projectCfg.name}.7z`) let inputPaths = [distPath] const stream7z = _7z.add(path7z, inputPaths, { recursive: false, $bin: _7zBin.path7za }); stream7z.on('end', ()=>{ fsEx.removeSync(distPath) }) } const buildResultDir = path.resolve(process.cwd(), buildDirectory) r(buildResultDir) }) }) } async function buildwithSelfArchive(){ buildWithArgs('online').then(buildDir=>{ let curDir = process.cwd() let buildRoot = path.resolve(curDir, 'dist') if (!projectCfg.scripts){ fsEx.removeSync(buildRoot) fsEx.copySync(buildDir, buildRoot) } let exePath = path.resolve(buildDir, `${projectCfg.name}.exe`) createSelfExtractingExe(buildDir, buildRoot, exePath) }) } async function createSelfExtractingExe(buildDir, inputFolder, outputFile) { const sfxPath = path.join(__dirname, 'res/7zsd.sfx'); if (!fs.existsSync(sfxPath)) { console.error('7zsd.sfx not found. Please make sure it exists in the same folder as this script'); return; } const configFileBuffer = createSfxConfig(outputFile); const zipBuffer = await create7ZipBuffer(buildDir, inputFolder); // 创建自解压 exe 文件 const ws = fs.createWriteStream(outputFile); ws.write(fs.readFileSync(sfxPath)); ws.write(configFileBuffer); let path7z = path.resolve(buildDir, `${projectCfg.name}.7z`) ws.write(fs.readFileSync(path7z)); ws.end(()=>{fsEx.removeSync(path7z)}); console.log('Self-extracting EXE created:', outputFile); } function createSfxConfig(outputFile) { return Buffer.from(` ;!@Install@!UTF-8! Title="install wps jsaddons" BeginPrompt="确定要安装${projectCfg.name}?" RunProgram="copy.bat" ;!@InstallEnd@! `, 'utf-8'); } function CreateCopyBat() { return Buffer.from(` @echo off set source_folder=${projectCfg.name}_${projectCfg.version} set destination_folder=%appdata%/kingsoft/wps/jsaddons if not exist "%destination_folder%" ( mkdir "%destination_folder%" ) if not exist "%destination_folder%/%source_folder%" ( mkdir "%destination_folder%/%source_folder%" ) xcopy /E /I /Y "%source_folder%" "%destination_folder%/%source_folder%" xcopy /E /I /Y "publish.xml" "%destination_folder%" `, 'utf-8'); } function CreatePublishXml(nameStr, typeStr, versionStr){ return Buffer.from(` <jsplugins> <jsplugin name="${nameStr}" type="${typeStr}" url="${nameStr}_${versionStr}" version="${versionStr}" enable="enable_dev" install="null" customDomain=""/> </jsplugins> `); } async function create7ZipBuffer(buildDir, inputFolder) { return new Promise((resolve, reject) => { let distDir = path.resolve(process.cwd(), 'dist') let tmp7zDir = path.resolve(buildDir, '7ztmpDir') let projDir = path.resolve(tmp7zDir, projectCfg.name + '_' + projectCfg.version) fsEx.ensureDirSync(tmp7zDir) fsEx.copy(distDir, projDir).then(()=>{ new Promise(r=>{ let batPath = path.resolve(tmp7zDir, "copy.bat") const ws = fs.createWriteStream(batPath) ws.write(CreateCopyBat()) ws.end(()=>{r()}) }).then(()=>{ new Promise(r=>{ let publishXmlPath = path.resolve(tmp7zDir, "publish.xml") const ws = fs.createWriteStream(publishXmlPath) ws.write(CreatePublishXml(projectCfg.name, projectCfg.addonType, projectCfg.version)) ws.end(()=>{r()}) }) }).then(()=>{ let path7z = path.resolve(buildDir, `${projectCfg.name}.7z`) let inputPaths = [path.resolve(tmp7zDir, "copy.bat"), path.resolve(tmp7zDir, "publish.xml"), projDir] const stream7z = _7z.add(path7z, inputPaths, { recursive: false, $bin: _7zBin.path7za }); stream7z.on('end', info=>{ fsEx.removeSync(tmp7zDir) resolve() }).on('error', err=>{ reject(err) }) }) }) }) } module.exports = { build, buildWithArgs }