網(wǎng)站主頁不收錄志鴻優(yōu)化設(shè)計(jì)電子版
以下主要簡(jiǎn)化復(fù)雜的打包流程,按照?delete -> wpspublish -> custom
?的順序運(yùn)行
1.?deleteFolder.js
- 用途:該腳本的主要功能是清理項(xiàng)目中的臨時(shí)文件夾和文件,為后續(xù)的打包操作做準(zhǔn)備。
- 具體操作:
- 嘗試遞歸刪除?
wps-addon-build
?和?wps-addon-publish
?這兩個(gè)文件夾。如果文件夾不存在,腳本會(huì)正常提示無需刪除;若刪除過程中出現(xiàn)其他錯(cuò)誤,則會(huì)輸出相應(yīng)的錯(cuò)誤信息。 - 檢查?
wps-addon-build.zip
?文件是否存在,若存在則將其刪除;若文件不存在,也會(huì)給出相應(yīng)提示。
- 嘗試遞歸刪除?
刪除:
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 contextconsole.log(`Folder does not exist: ${folderPath}, no need to delete.`);} else {// Some other error occurredconsole.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 beforeconst 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
- 用途:此腳本的主要任務(wù)是查找?
wpsjs
?可執(zhí)行文件,并使用 Node.js 啟動(dòng)子進(jìn)程來執(zhí)行?wpsjs publish
?打包命令,同時(shí)處理該命令執(zhí)行過程中的自動(dòng)化交互。 - 具體操作:
- 從環(huán)境變量?
PATH
?中查找?wpsjs
?的路徑。 - 若找到?
wpsjs
?可執(zhí)行文件,使用?spawn
?函數(shù)啟動(dòng)一個(gè)子進(jìn)程來執(zhí)行?wpsjs publish
?命令。 - 在子進(jìn)程執(zhí)行過程中,監(jiān)聽其標(biāo)準(zhǔn)輸出,當(dāng)遇到需要輸入服務(wù)器地址、選擇發(fā)布類型或確認(rèn)多用戶使用等提示時(shí),自動(dòng)模擬輸入相應(yīng)信息,并使用防抖函數(shù)避免重復(fù)輸出提示信息。
- 監(jiān)聽子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤流和退出事件,輸出相應(yīng)的錯(cuò)誤信息和退出碼。
- 從環(huán)境變量?
打包:
const { spawn } = require('child_process');
const path = require('path');
// 從環(huán)境變量中查找 wpsjs 路徑
function findWpsjsInPath() {const paths = process.env.PATH.split(path.delimiter); // 分割環(huán)境變量 PATHfor (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;}
}// 執(zhí)行 wpsjs 命令
const wpsjsPath = findWpsjsInPath(); // 查找 wpsjs 路徑if (wpsjsPath) {// 如果找到了 wpsjs 可執(zhí)行文件console.log(`Found wpsjs at: ${wpsjsPath}`);// 用node啟動(dòng)子進(jìn)程執(zhí)行 wpsjs 發(fā)布命令const command = 'node';const args = [wpsjsPath, 'publish'];// const args = ['D:\\01tools\\npm\\node_modules\\wpsjs\\src\\index.js', 'publish'];// 啟動(dòng)子進(jìn)程const child = spawn(command, args, { stdio: ['pipe', 'pipe', 'pipe'] });// 定義防抖定時(shí)器let debounceTimeoutServer = null; // 防抖定時(shí)器 - 服務(wù)器地址let debounceTimeoutType = null; // 防抖定時(shí)器 - 發(fā)布類型let debounceTimeoutMultiUser = null; // 防抖定時(shí)器 - 多用戶// 監(jiān)聽子進(jìn)程的標(biāo)準(zhǔn)輸出child.stdout.on('data', (data) => {let output = data.toString().replace(/^\?/, '').trim(); // 去除開頭的問號(hào),并去除多余的空格// 處理自動(dòng)化交互if (output.includes('請(qǐng)輸入發(fā)布 WPS 加載項(xiàng)的服務(wù)器地址')) {child.stdin.write('a/\n'); // 模擬輸入服務(wù)器地址// 防抖:服務(wù)器地址輸入debounceTimeoutServer = setDebounceTimer(debounceTimeoutServer, () => {console.log(output);});}if (output.includes('選擇 WPS 加載項(xiàng)發(fā)布類型')) {child.stdin.write('\n'); // 輸入回車選擇發(fā)布類型// 防抖:發(fā)布類型選擇debounceTimeoutType = setDebounceTimer(debounceTimeoutType, () => {console.log(output);});}if (output.includes('您的publish頁面是否需要滿足多用戶同時(shí)使用')) {child.stdin.write('\n'); // 確認(rèn)操作,按回車// 防抖:多用戶選擇debounceTimeoutMultiUser = setDebounceTimer(debounceTimeoutMultiUser, () => {console.log(output);});}});// 監(jiān)聽標(biāo)準(zhǔn)錯(cuò)誤流child.stderr.on('data', (data) => {console.error('stderr:', data.toString()); // 打印所有的 stderr 輸出});// 監(jiān)聽子進(jìn)程退出child.on('close', (code) => {console.log(`子進(jìn)程退出,退出碼: ${code}`);if (code !== 0) {console.log('進(jìn)程出現(xiàn)錯(cuò)誤,退出代碼不是 0');}});
}// 防抖函數(shù)
function setDebounceTimer(timer, callback, delay = 500) {// 清除之前的定時(shí)器if (timer) {clearTimeout(timer);}// 設(shè)置新的定時(shí)器return setTimeout(callback, delay);
}
3.?CustomZipPlugin.js
- 用途:該腳本主要負(fù)責(zé)識(shí)別?
wps-addon-build
?目錄,將?publish_html
?目錄的內(nèi)容復(fù)制到?wps-addon-build
?目錄,并在復(fù)制完成后將?wps-addon-build
?目錄壓縮成?wps.tar.gz
?文件。 - 具體操作:
- 檢查?
wps-addon-build
?目錄是否存在,若存在則調(diào)用復(fù)制目錄的函數(shù);若不存在或檢查過程中出現(xiàn)錯(cuò)誤,會(huì)輸出相應(yīng)的提示信息。 - 將?
publish_html
?目錄的內(nèi)容復(fù)制到?wps-addon-build
?目錄。 - 復(fù)制完成后,將?
wps-addon-build
?目錄壓縮成?wps.tar.gz
?文件,并輸出壓縮結(jié)果信息。
- 檢查?
移動(dòng)文件+壓縮
const fs = require('fs-extra');
const path = require('path');
// const archiver = require('archiver');checkFolderExists('wps-addon-build')
// 識(shí)別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`);// 調(diào)用復(fù)制目錄的函數(shù)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}}
}
// 復(fù)制目錄及其內(nèi)容的異步函數(shù)
async function copyDirectory() {// 源目錄(publish_html)和目標(biāo)目錄(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.');// 直接執(zhí)行后續(xù)代碼// CustomTarGzPlugin();} catch (err) {console.error('Error copying directory:', err);}
}
// 在目錄復(fù)制完成后打壓縮包
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 // 設(shè)置壓縮級(jí)別}});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
?
也可以簡(jiǎn)化操作:package.json
最后npm run wps即可