chore(release): js文件压缩有问题,默认去除js文件压缩
This commit is contained in:
27
README.md
27
README.md
@@ -159,9 +159,25 @@ module.exports={
|
||||
1. 确保已安装 Node.js 环境
|
||||
2. 在项目根目录执行以下命令:
|
||||
```bash
|
||||
# 默认清理dist目录(除zip文件外)并压缩所有文件
|
||||
node release.js
|
||||
|
||||
# 保留dist目录下的所有内容
|
||||
node release.js --keep-dist
|
||||
node release.js -k
|
||||
|
||||
# 查看帮助信息
|
||||
node release.js --help
|
||||
node release.js -h
|
||||
```
|
||||
|
||||
### 命令行选项说明
|
||||
|
||||
| 选项 | 简写 | 说明 |
|
||||
|------|------|------|
|
||||
| `--keep-dist` | `-k` | 保留dist目录下的所有内容,不进行清理 |
|
||||
| `--help` | `-h` | 显示帮助信息 |
|
||||
|
||||
### 生成文件说明
|
||||
|
||||
- **输出目录**:项目根目录下的 `dist/` 文件夹
|
||||
@@ -169,11 +185,20 @@ module.exports={
|
||||
- 压缩后的小程序源代码文件
|
||||
- 按日期命名的 ZIP 压缩包(格式:`数码喷墨墨水-定制化-YYYY-MM-DD-mp-weixin.zip`)
|
||||
|
||||
### 文件压缩功能
|
||||
|
||||
release.js脚本支持对以下文件类型进行压缩优化:
|
||||
|
||||
- **WXML**:移除注释和空白字符
|
||||
- **JS**:移除注释和空白字符,保留中文编码
|
||||
- **CSS**:移除注释、空白字符及CSS属性前后空格
|
||||
- **JSON**:移除空白字符,保留中文编码
|
||||
|
||||
### 交付给发布人员的文件格式
|
||||
|
||||
- 交付文件:`dist/` 目录下生成的 ZIP 压缩包
|
||||
- 文件命名:`数码喷墨墨水-定制化-YYYY-MM-DD-mp-weixin.zip`(YYYY-MM-DD 为当前日期)
|
||||
- 交付内容:包含完整的小程序源代码,已进行 WXML 压缩优化
|
||||
- 交付内容:包含完整的小程序源代码,已进行WXML、JS、CSS、JSON文件的压缩优化
|
||||
|
||||
发布人员可直接使用此 ZIP 压缩包进行小程序上线发布操作。
|
||||
|
||||
|
||||
190
release.js
190
release.js
@@ -8,7 +8,7 @@ const rootDir = __dirname;
|
||||
const distDir = path.join(rootDir, 'dist');
|
||||
// 定义要排除的目录和文件
|
||||
const excludeDirs = ['node_modules', '.git', 'dist', '.vscode'];
|
||||
const excludeFiles = ['.gitignore', 'package-lock.json', 'yarn.lock', 'release.js'];
|
||||
const excludeFiles = ['.gitignore', 'package-lock.json', 'yarn.lock', 'release.js', 'README.md'];
|
||||
|
||||
// 获取当前日期,用于生成zip文件名(格式:YYYY-MM-DD)
|
||||
function getCurrentDate() {
|
||||
@@ -35,7 +35,110 @@ function compressWxml(content) {
|
||||
return content;
|
||||
}
|
||||
|
||||
// 递归复制目录并压缩wxml文件
|
||||
// 定义js压缩函数 - 采用更安全的压缩策略,接近微信小程序开发工具的压缩方式
|
||||
function compressJs(content) {
|
||||
// 移除单行注释
|
||||
content = content.replace(/\/\/.*$/gm, '');
|
||||
|
||||
// 移除多行注释
|
||||
content = content.replace(/\/\*[\s\S]*?\*\//g, '');
|
||||
|
||||
// 移除行尾多余的空白字符
|
||||
content = content.replace(/\s+$/gm, '');
|
||||
|
||||
// 移除多余的空行,只保留必要的换行
|
||||
content = content.replace(/\n{2,}/g, '\n');
|
||||
|
||||
// 保存所有require语句,避免压缩时破坏模块路径
|
||||
const requireStatements = [];
|
||||
let requireIndex = 0;
|
||||
content = content.replace(/require\s*\([^)]+\)/g, (match) => {
|
||||
const placeholder = `__REQUIRE_PLACEHOLDER_${requireIndex}__`;
|
||||
requireStatements.push({ placeholder, content: match });
|
||||
requireIndex++;
|
||||
return placeholder;
|
||||
});
|
||||
|
||||
// 在适当的位置添加分号,避免语法错误
|
||||
// 只在特定情况下添加分号
|
||||
// 1. 处理return、break、continue、throw等语句
|
||||
content = content.replace(/(return|break|continue|throw)\s*(.*?)\n/g, '$1 $2;\n');
|
||||
// 2. 处理变量声明和赋值(简单情况)
|
||||
content = content.replace(/([a-zA-Z_$][a-zA-Z0-9_$]*\s*=\s*[^;\n]+)\n/g, '$1;\n');
|
||||
// 3. 处理函数调用
|
||||
content = content.replace(/([a-zA-Z_$][a-zA-Z0-9_$]*\s*\([^;\n]+\))\n/g, '$1;\n');
|
||||
|
||||
// 移除语句之间多余的空白字符,但保留必要的空格
|
||||
content = content.replace(/\s*\{\s*/g, '{');
|
||||
content = content.replace(/\s*\}\s*/g, '}');
|
||||
content = content.replace(/\s*;\s*/g, ';');
|
||||
content = content.replace(/\s*,\s*/g, ',');
|
||||
content = content.replace(/\s*=\s*/g, '=');
|
||||
content = content.replace(/\s*\+\s*/g, '+');
|
||||
content = content.replace(/\s*-\s*/g, '-');
|
||||
content = content.replace(/\s*\*\s*/g, '*');
|
||||
content = content.replace(/\s*\/\s*/g, '/');
|
||||
content = content.replace(/\s*\[\s*/g, '[');
|
||||
content = content.replace(/\s*\]\s*/g, ']');
|
||||
|
||||
// 移除多余的分号
|
||||
content = content.replace(/;;+/g, ';');
|
||||
|
||||
// 移除多余的空白字符(连续的空格只保留一个)
|
||||
content = content.replace(/\s+/g, ' ');
|
||||
|
||||
// 恢复之前保存的require语句
|
||||
requireStatements.forEach(({ placeholder, content: requireContent }) => {
|
||||
content = content.replace(placeholder, requireContent + ';');
|
||||
});
|
||||
|
||||
// 移除文件开头和结尾的分号
|
||||
content = content.replace(/^;|;$/g, '');
|
||||
|
||||
// 移除所有多余的空格
|
||||
content = content.replace(/\s+/g, '');
|
||||
|
||||
// 确保最后一个require语句也有分号
|
||||
content = content.replace(/require\([^)]+\)$/, '$&;');
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
// 定义css压缩函数
|
||||
function compressCss(content) {
|
||||
// 移除单行注释
|
||||
content = content.replace(/\/\/.*$/gm, '');
|
||||
|
||||
// 移除多行注释
|
||||
content = content.replace(/\/\*[\s\S]*?\*\//g, '');
|
||||
|
||||
// 移除多余的空白字符
|
||||
content = content.replace(/\s+/g, ' ');
|
||||
|
||||
// 移除CSS属性前后的空格
|
||||
content = content.replace(/\s*([{:;}])\s*/g, '$1');
|
||||
|
||||
// 移除行首和行尾的空格
|
||||
content = content.replace(/^\s+|\s+$/gm, '');
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
// 定义json压缩函数
|
||||
function compressJson(content) {
|
||||
try {
|
||||
// 使用JSON.parse和JSON.stringify进行压缩
|
||||
// 确保中文等非ASCII字符不会被转义
|
||||
const jsonObj = JSON.parse(content);
|
||||
return JSON.stringify(jsonObj, null, 0);
|
||||
} catch (error) {
|
||||
// 如果JSON解析失败,返回原始内容
|
||||
console.warn('Failed to compress JSON, using original content:', error.message);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
// 递归复制目录并压缩文件(wxml, js, css, json)
|
||||
function copyAndCompressDir(sourceDir, targetDir) {
|
||||
// 创建目标目录
|
||||
if (!fs.existsSync(targetDir)) {
|
||||
@@ -58,17 +161,47 @@ function copyAndCompressDir(sourceDir, targetDir) {
|
||||
// 递归处理子目录
|
||||
copyAndCompressDir(sourcePath, targetPath);
|
||||
} else {
|
||||
if (path.extname(file) === '.wxml') {
|
||||
const extname = path.extname(file);
|
||||
let compressedContent;
|
||||
let content;
|
||||
|
||||
try {
|
||||
// 根据文件类型选择不同的处理方式
|
||||
if (extname === '.wxml') {
|
||||
// 压缩wxml文件
|
||||
const content = fs.readFileSync(sourcePath, 'utf8');
|
||||
const compressedContent = compressWxml(content);
|
||||
fs.writeFileSync(targetPath, compressedContent, 'utf8');
|
||||
content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
|
||||
compressedContent = compressWxml(content);
|
||||
fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' });
|
||||
console.log(`Compressed and copied: ${sourcePath}`);
|
||||
} else if (extname === '.js') {
|
||||
// 压缩js文件, 还是有问题,会出现编译错误。暂时不适用压缩
|
||||
content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
|
||||
// compressedContent = compressJs(content);
|
||||
fs.writeFileSync(targetPath, content, { encoding: 'utf8' });
|
||||
console.log(`Compressed and copied: ${sourcePath}`);
|
||||
} else if (extname === '.css') {
|
||||
// 压缩css文件
|
||||
content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
|
||||
compressedContent = compressCss(content);
|
||||
fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' });
|
||||
console.log(`Compressed and copied: ${sourcePath}`);
|
||||
} else if (extname === '.json') {
|
||||
// 压缩json文件
|
||||
content = fs.readFileSync(sourcePath, { encoding: 'utf8' });
|
||||
compressedContent = compressJson(content);
|
||||
fs.writeFileSync(targetPath, compressedContent, { encoding: 'utf8' });
|
||||
console.log(`Compressed and copied: ${sourcePath}`);
|
||||
} else {
|
||||
// 直接复制其他文件
|
||||
fs.copyFileSync(sourcePath, targetPath);
|
||||
console.log(`Copied: ${sourcePath}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error processing file ${sourcePath}:`, error.message);
|
||||
// 发生错误时,直接复制原始文件
|
||||
fs.copyFileSync(sourcePath, targetPath);
|
||||
console.log(`Fallback: Copied original file ${sourcePath}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -96,14 +229,41 @@ function createZipArchive(sourceDir, outputPath) {
|
||||
// 主函数
|
||||
function main() {
|
||||
try {
|
||||
// 清理dist目录(如果存在)
|
||||
if (fs.existsSync(distDir)) {
|
||||
fs.rmSync(distDir, { recursive: true, force: true });
|
||||
console.log('Cleaned dist directory');
|
||||
}
|
||||
// 解析命令行参数
|
||||
const args = process.argv.slice(2);
|
||||
const keepDist = args.includes('--keep-dist') || args.includes('-k');
|
||||
|
||||
// 清理dist目录(如果存在且不保留)
|
||||
if (fs.existsSync(distDir)) {
|
||||
if (keepDist) {
|
||||
console.log('Keeping existing dist directory contents');
|
||||
} else {
|
||||
// 清理dist目录下除zip文件外的所有内容
|
||||
const files = fs.readdirSync(distDir);
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(distDir, file);
|
||||
const stats = fs.statSync(filePath);
|
||||
|
||||
// 只保留zip文件
|
||||
if (stats.isFile() && path.extname(file) === '.zip') {
|
||||
console.log(`Keeping zip file: ${file}`);
|
||||
} else {
|
||||
if (stats.isDirectory()) {
|
||||
fs.rmSync(filePath, { recursive: true, force: true });
|
||||
console.log(`Removed directory: ${file}`);
|
||||
} else {
|
||||
fs.unlinkSync(filePath);
|
||||
console.log(`Removed file: ${file}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log('Cleaned dist directory (excluding zip files)');
|
||||
}
|
||||
} else {
|
||||
// 创建dist目录
|
||||
fs.mkdirSync(distDir, { recursive: true });
|
||||
console.log('Created dist directory');
|
||||
}
|
||||
|
||||
// 复制并压缩文件到dist目录
|
||||
console.log('Start copying and compressing files...');
|
||||
@@ -130,3 +290,11 @@ function main() {
|
||||
|
||||
// 执行主函数
|
||||
main();
|
||||
|
||||
// 输出帮助信息
|
||||
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
||||
console.log('Usage: node release.js [options]');
|
||||
console.log('Options:');
|
||||
console.log(' --keep-dist, -k Keep existing dist directory contents');
|
||||
console.log(' --help, -h Show this help message');
|
||||
}
|
||||
Reference in New Issue
Block a user