以下主要简化复杂的打包流程,按照 delete -> wpspublish -> custom
的顺序运行
1. deleteFolder.js
- 用途:该脚本的主要功能是清理项目中的临时文件夹和文件,为后续的打包操作做准备。
- 具体操作:
- 尝试递归删除
wps-addon-build
和wps-addon-publish
这两个文件夹。如果文件夹不存在,脚本会正常提示无需删除;若删除过程中出现其他错误,则会输出相应的错误信息。 - 检查
wps-addon-build.zip
文件是否存在,若存在则将其删除;若文件不存在,也会给出相应提示。
- 尝试递归删除
删除:
const path = require('path');
const fs2 = require('fs').promises;
const fs = require('fs');
async function deleteFolder(folderPath) {
try {
await fs2.rmdir(folderPath, { recursive: true });
console.log(`Successfully deleted folder: ${folderPath}`);
} catch (err) {
if (err.code === 'ENOENT') {
// Folder does not exist, which is not an error in our context
console.log(`Folder does not exist: ${folderPath}, no need to delete.`);
} else {
// Some other error occurred
console.error(`Error deleting folder: ${folderPath}`, err);
}
}
}
async function main() {
const foldersToDelete = [
'wps-addon-build',
'wps-addon-publish'
];
for (const folder of foldersToDelete) {
const fullPath = path.join(__dirname, folder);
await deleteFolder(fullPath);
}
// Handling the ZIP file as before
const zipFilePath = path.join(__dirname, 'wps-addon-build.zip');
if (fs.existsSync(zipFilePath)) {
try {
fs.unlinkSync(zipFilePath);
console.log('File deleted successfully (sync)');
} catch (err) {
console.error('Error deleting file (sync):', err);
}
} else {
console.log('ZIP file does not exist, no need to delete.');
}
}
main().catch(err => {
console.error('Error in main function:', err);
});
2. wpspublish.js
- 用途:此脚本的主要任务是查找
wpsjs
可执行文件,并使用 Node.js 启动子进程来执行wpsjs publish
打包命令,同时处理该命令执行过程中的自动化交互。 - 具体操作:
- 从环境变量
PATH
中查找wpsjs
的路径。 - 若找到
wpsjs
可执行文件,使用spawn
函数启动一个子进程来执行wpsjs publish
命令。 - 在子进程执行过程中,监听其标准输出,当遇到需要输入服务器地址、选择发布类型或确认多用户使用等提示时,自动模拟输入相应信息,并使用防抖函数避免重复输出提示信息。
- 监听子进程的标准错误流和退出事件,输出相应的错误信息和退出码。
- 从环境变量
打包:
const { spawn } = require('child_process');
const path = require('path');
// 从环境变量中查找 wpsjs 路径
function findWpsjsInPath() {
const paths = process.env.PATH.split(path.delimiter); // 分割环境变量 PATH
for (let dir of paths) {
const wpsjsPath = path.join(dir, 'wpsjs');
if (pathExists(wpsjsPath)) {
return wpsjsPath; // 返回找到的 wpsjs 路径
}
}
return null;
}
// 检查路径是否存在
function pathExists(filePath) {
try {
return require('fs').existsSync(filePath);
} catch (e) {
return false;
}
}
// 执行 wpsjs 命令
const wpsjsPath = findWpsjsInPath(); // 查找 wpsjs 路径
if (wpsjsPath) {
// 如果找到了 wpsjs 可执行文件
console.log(`Found wpsjs at: ${wpsjsPath}`);
// 用node启动子进程执行 wpsjs 发布命令
const command = 'node';
const args = [wpsjsPath, 'publish'];
// const args = ['D:\\01tools\\npm\\node_modules\\wpsjs\\src\\index.js', 'publish'];
// 启动子进程
const child = spawn(command, args, { stdio: ['pipe', 'pipe', 'pipe'] });
// 定义防抖定时器
let debounceTimeoutServer = null; // 防抖定时器 - 服务器地址
let debounceTimeoutType = null; // 防抖定时器 - 发布类型
let debounceTimeoutMultiUser = null; // 防抖定时器 - 多用户
// 监听子进程的标准输出
child.stdout.on('data', (data) => {
let output = data.toString().replace(/^\?/, '').trim(); // 去除开头的问号,并去除多余的空格
// 处理自动化交互
if (output.includes('请输入发布 WPS 加载项的服务器地址')) {
child.stdin.write('a/\n'); // 模拟输入服务器地址
// 防抖:服务器地址输入
debounceTimeoutServer = setDebounceTimer(debounceTimeoutServer, () => {
console.log(output);
});
}
if (output.includes('选择 WPS 加载项发布类型')) {
child.stdin.write('\n'); // 输入回车选择发布类型
// 防抖:发布类型选择
debounceTimeoutType = setDebounceTimer(debounceTimeoutType, () => {
console.log(output);
});
}
if (output.includes('您的publish页面是否需要满足多用户同时使用')) {
child.stdin.write('\n'); // 确认操作,按回车
// 防抖:多用户选择
debounceTimeoutMultiUser = setDebounceTimer(debounceTimeoutMultiUser, () => {
console.log(output);
});
}
});
// 监听标准错误流
child.stderr.on('data', (data) => {
console.error('stderr:', data.toString()); // 打印所有的 stderr 输出
});
// 监听子进程退出
child.on('close', (code) => {
console.log(`子进程退出,退出码: ${code}`);
if (code !== 0) {
console.log('进程出现错误,退出代码不是 0');
}
});
}
// 防抖函数
function setDebounceTimer(timer, callback, delay = 500) {
// 清除之前的定时器
if (timer) {
clearTimeout(timer);
}
// 设置新的定时器
return setTimeout(callback, delay);
}
3. CustomZipPlugin.js
- 用途:该脚本主要负责识别
wps-addon-build
目录,将publish_html
目录的内容复制到wps-addon-build
目录,并在复制完成后将wps-addon-build
目录压缩成wps.tar.gz
文件。 - 具体操作:
- 检查
wps-addon-build
目录是否存在,若存在则调用复制目录的函数;若不存在或检查过程中出现错误,会输出相应的提示信息。 - 将
publish_html
目录的内容复制到wps-addon-build
目录。 - 复制完成后,将
wps-addon-build
目录压缩成wps.tar.gz
文件,并输出压缩结果信息。
- 检查
移动文件+压缩
const fs = require('fs-extra');
const path = require('path');
// const archiver = require('archiver');
checkFolderExists('wps-addon-build')
// 识别wps-addon-build目录
async function checkFolderExists(folderName) {
try {
const folderPath = path.join(__dirname, folderName);
const stats = await fs.stat(folderPath);
if (stats.isDirectory()) {//文件是否存在
console.log(`The folder "${folderName}" exists.1111111`);
// 调用复制目录的函数
copyDirectory();
return true;
} else {
console.log(`A file or something else named "${folderName}" exists, but it is not a folder.`);
return false;
}
} catch (err) {
if (err.code === 'ENOENT') {
console.log(`The folder "${folderName}" does not exist.`);
return false;
} else {
console.error(`An error occurred while checking for the folder: ${err.message}`);
throw err; // Re-throw the error after logging it
}
}
}
// 复制目录及其内容的异步函数
async function copyDirectory() {
// 源目录(publish_html)和目标目录(wps-addon-build)的路径
const sourceDir = path.resolve(__dirname, 'publish_html');
const targetDir = path.resolve(__dirname, 'wps-addon-build');
try {
await fs.copy(sourceDir, targetDir, { dereference: true });
console.log('Directory has been copied successfully.');
// 直接执行后续代码
// CustomTarGzPlugin();
} catch (err) {
console.error('Error copying directory:', err);
}
}
// 在目录复制完成后打压缩包
function CustomTarGzPlugin() {
const sourceFolder = path.join(__dirname, 'wps-addon-build');
const outputTarGzPath = path.join(__dirname, 'wps.tar.gz');
tarGzFolder(sourceFolder, outputTarGzPath)
.then(() => {
console.log('Folder has been successfully tar.gz\'ed!');
})
.catch(err => {
console.error('An error occurred while tar.gz\'ing the folder:', err);
});
}
// 压缩成 tar.gz 包
async function tarGzFolder(sourceFolder, outputTarGzPath) {
return new Promise((resolve, reject) => {
const output = fs.createWriteStream(outputTarGzPath);
const archive = archiver('tar', {
gzip: true, // 启用 gzip 压缩
gzipOptions: {
level: 9 // 设置压缩级别
}
});
output.on('close', function () {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
resolve();
});
archive.on('error', function (err) {
reject(err);
});
archive.pipe(output);
archive.directory(sourceFolder, false);
archive.finalize();
});
}
最后按顺序跑脚本即可,一行命令:
node delete.js && node wpspublish.js && node custom.js
也可以简化操作:package.json
最后npm run wps即可