123 lines
4.1 KiB
JavaScript
123 lines
4.1 KiB
JavaScript
import fs from 'fs';
|
||
import path from 'path';
|
||
import { JSDOM } from 'jsdom';
|
||
import archiver from 'archiver'; // 用于打包 ZIP 文件
|
||
|
||
/**
|
||
* 提取 HTML 中的内联 JavaScript 并保存为外部文件
|
||
* @param {string} htmlFilePath - HTML 文件路径
|
||
* @param {string} outputDir - 输出目录
|
||
* @param {string} jsPrefix - JavaScript 文件的前缀名称
|
||
*/
|
||
export function extractJsFromHtml(htmlFilePath, outputDir, jsPrefix = 'script') {
|
||
// 确保输出目录存在
|
||
if (!fs.existsSync(outputDir)) {
|
||
fs.mkdirSync(outputDir, { recursive: true });
|
||
}
|
||
|
||
// 读取 HTML 文件内容
|
||
const htmlContent = fs.readFileSync(htmlFilePath, 'utf-8');
|
||
|
||
// 使用 JSDOM 解析 HTML
|
||
const dom = new JSDOM(htmlContent);
|
||
const document = dom.window.document;
|
||
|
||
// 查找所有的 <script> 标签
|
||
const scriptTags = document.querySelectorAll('script');
|
||
|
||
scriptTags.forEach((script, index) => {
|
||
// 如果 script 标签有 src 属性,并且是 http 或 https 协议,则跳过
|
||
if (script.src && (script.src.startsWith('http://') || script.src.startsWith('https://'))) {
|
||
console.log(`跳过外部引用: ${script.src}`);
|
||
return;
|
||
}
|
||
|
||
// 如果 script 标签有 src 属性,但不是 http/https,则保留
|
||
if (script.src) {
|
||
return;
|
||
}
|
||
|
||
// 获取内联 JavaScript 代码
|
||
const jsCode = script.textContent;
|
||
if (!jsCode.trim()) {
|
||
return;
|
||
}
|
||
|
||
// 生成外部 JS 文件名
|
||
const jsFileName = `${jsPrefix}_${index + 1}.js`;
|
||
const jsFilePath = path.join(outputDir, jsFileName);
|
||
|
||
// 将 JavaScript 代码写入外部文件
|
||
fs.writeFileSync(jsFilePath, jsCode, 'utf-8');
|
||
|
||
// 更新 <script> 标签,改为引用外部文件
|
||
script.textContent = ''; // 清空内联代码
|
||
script.src = jsFileName; // 添加 src 属性
|
||
});
|
||
|
||
// 保存更新后的 HTML 文件为 index.html
|
||
const updatedHtmlContent = dom.serialize();
|
||
const updatedHtmlFilePath = path.join(outputDir, 'index.html');
|
||
fs.writeFileSync(updatedHtmlFilePath, updatedHtmlContent, 'utf-8');
|
||
|
||
console.log(`拆分完成!更新后的 HTML 文件已保存为: ${updatedHtmlFilePath}`);
|
||
}
|
||
|
||
/**
|
||
* 将目录打包为 ZIP 文件
|
||
* @param {string} sourceDir - 要打包的目录
|
||
* @param {string} outputZipFile - 输出的 ZIP 文件路径
|
||
*/
|
||
function zipDirectory(sourceDir, outputZipFile) {
|
||
const output = fs.createWriteStream(outputZipFile);
|
||
const archive = archiver('zip', { zlib: { level: 9 } }); // 设置压缩级别
|
||
|
||
// 监听打包完成事件
|
||
output.on('close', () => {
|
||
console.log(`打包完成!ZIP 文件已保存为: ${outputZipFile}`);
|
||
});
|
||
|
||
// 监听错误事件
|
||
archive.on('error', (err) => {
|
||
throw err;
|
||
});
|
||
|
||
// 将输出流与 archiver 关联
|
||
archive.pipe(output);
|
||
|
||
// 将目录内容添加到 ZIP 文件中
|
||
archive.directory(sourceDir, false);
|
||
|
||
// 完成打包
|
||
archive.finalize();
|
||
}
|
||
|
||
/**
|
||
* 处理 dist 目录下的所有 HTML 文件
|
||
* @param {string} distDir - dist 目录路径
|
||
* @param {string} jsPrefix - JavaScript 文件的前缀名称
|
||
*/
|
||
export function processHtmlFiles(distDir, jsPrefix = 'script') {
|
||
// 获取 dist 目录下的所有文件
|
||
const files = fs.readdirSync(distDir);
|
||
|
||
files.forEach((file) => {
|
||
const filePath = path.join(distDir, file);
|
||
|
||
// 只处理 HTML 文件
|
||
if (path.extname(file).toLowerCase() === '.html') {
|
||
const outputDir = path.join(distDir, path.basename(file, '.html')); // 输出目录
|
||
const zipFilePath = path.join(distDir, `${path.basename(file, '.html')}.zip`); // ZIP 文件路径
|
||
|
||
// 提取 JS 并生成 index.html
|
||
extractJsFromHtml(filePath, outputDir, jsPrefix);
|
||
|
||
// 将输出目录打包为 ZIP 文件
|
||
zipDirectory(outputDir, zipFilePath);
|
||
|
||
// 清理临时输出目录(可选)
|
||
fs.rmSync(outputDir, { recursive: true, force: true });
|
||
console.log(`清理临时目录: ${outputDir}`);
|
||
}
|
||
});
|
||
} |