Files
lucky_shop/scripts/mp-weixin.patch.js
ZF sun e8ccb87266 feat(脚本): 增强微信小程序补丁脚本功能
- 添加新的 npm scripts 支持不同模式运行补丁脚本
- 支持命令行参数 --no-zip 和 --mode 控制 ZIP 文件生成和运行模式
- 自动复制项目配置文件到目标目录
- 更新使用说明文档
2026-01-23 10:12:30 +08:00

170 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* fix-wechat-miniapp.js
*
* 该脚本用于修复微信小程序的一些问题:
* 1. 将项目根目录下的 site.js 文件拷贝到 unpackage/dist/build/mp-weixin 目录下,如果文件存在则覆盖
* 2. 将 `import site from "../site.js";` 这段代码追加到
* unpackage/dist/build/mp-weixin/common/vendor.js 文件内容开头部分,
* 如果这个文件开头已经有了这行代码,则不追加
*
* 使用:
* node fix-wechat-miniapp.js # 打补丁并创建 ZIP 文件(默认 mode=production
* node fix-wechat-miniapp.js --no-zip # 只打补丁,不创建 ZIP 文件
* node fix-wechat-miniapp.js --mode development # 使用 development 模式打补丁
* node fix-wechat-miniapp.js --mode production # 使用 production 模式打补丁(默认)
*
* 注意:
* - 在 Windows 上路径使用反斜杠也是可以的;脚本使用 path.join 来兼容不同平台。
* - 运行前请确认在项目根目录运行site.js 在当前工作目录下)。
*/
const fs = require('fs');
const fsp = fs.promises;
const path = require('path');
const { openFileDirectory } = require('./open-directory');
const { createZipWithSystemCommand } = require('./create-zip');
async function commonPatch(mode = 'production') {
try {
// 根据当前脚本所在目录scripts定位到项目根目录
const cwd = path.join(__dirname, '..');
const srcSitePath = path.join(cwd, 'site.js');
const destDir = path.join(cwd, 'unpackage', 'dist', mode === 'production' ? 'build' : 'dev', 'mp-weixin');
const destSitePath = path.join(destDir, 'site.js');
const vendorPath = path.join(destDir, 'common', 'vendor.js');
// 1) 检查源文件是否存在
const srcExists = await exists(srcSitePath);
if (!srcExists) {
console.error(`源文件不存在: ${srcSitePath}`);
process.exitCode = 2;
return;
}
// 确保目标目录存在
await ensureDir(destDir);
// 复制 project.config.json 及 project.private.config.json 文件到 destDir 下面
const configFiles = ['project.config.json', 'project.private.config.json'];
for (const fileName of configFiles) {
const srcPath = path.join(cwd, fileName);
const destPath = path.join(destDir, fileName);
// 检查源文件是否存在
const fileExists = await exists(srcPath);
if (fileExists) {
await fsp.copyFile(srcPath, destPath);
console.log(`已拷贝: ${srcPath} -> ${destPath}`);
} else {
console.warn(`源文件不存在,跳过复制: ${srcPath}`);
}
}
// 复制 site.js 到目标目录(覆盖)
await fsp.copyFile(srcSitePath, destSitePath);
console.log(`已拷贝: ${srcSitePath} -> ${destSitePath}`);
// 2) 处理 vendor.js在开头追加 import 语句(如果还没有的话)
const vendorExists = await exists(vendorPath);
if (!vendorExists) {
console.warn(`目标 vendor.js 不存在,跳过追加 import。路径: ${vendorPath}`);
return;
}
let vendorContent = await fsp.readFile(vendorPath, 'utf8');
const importLine = 'import site from "../site.js";';
// 检查文件开头(例如前 5 行或前 400 字符)是否已经包含该 import 语句
const inspectPrefix = vendorContent.slice(0, 400);
const importRegex = new RegExp(
// 匹配可能存在的引号或分号差异,但我们只需要确切匹配这行文字
'^\\s*import\\s+site\\s+from\\s+[\'"]\\.\\./site\\.js[\'"];?',
'm'
);
if (importRegex.test(inspectPrefix)) {
console.log('vendor.js 开头已包含 import site 语句,跳过追加。');
return;
}
// 如果文件以 shebang 或者注释开头,决定放在哪:通常我们把 import 放在文件最顶部index 0
// 但如果文件以 "use strict"; 等指令开头import 必须在所有非-import/非-comment 语句之前。
// 简单实现:如果文件开头有 UTF BOM保留它然后把 importLine + newline 插入文件最前面。
// 保留原始换行风格(若可能)
const eol = vendorContent.includes('\r\n') ? '\r\n' : '\n';
let prefix = '';
// 保留可能的 BOM
if (vendorContent.charCodeAt(0) === 0xfeff) {
prefix = '\uFEFF';
vendorContent = vendorContent.slice(1);
}
const newContent = prefix + importLine + eol + vendorContent;
await fsp.writeFile(vendorPath, newContent, 'utf8');
console.log(`已在 vendor.js 开头追加: ${importLine}`);
} catch (err) {
console.error('发生错误:', err);
process.exitCode = 1;
}
}
async function main() {
// 解析命令行参数
const argv = process.argv.slice(2);
const options = {
noZip: argv.includes('--no-zip'),
mode: 'production' // 默认值
};
// 解析 --mode 参数
const modeIndex = argv.indexOf('--mode');
if (modeIndex !== -1 && modeIndex + 1 < argv.length) {
options.mode = argv[modeIndex + 1];
}
// 1) 打补丁
await commonPatch(options.mode);
// await commonPatch('development');
// 2) 创建 ZIP 文件(如果未指定 --no-zip
if (!options.noZip) {
const cwd = path.join(__dirname, '..');
const sourceDir = path.join(cwd, 'unpackage', 'dist', 'build', 'mp-weixin');
const destDir = path.join(cwd, 'unpackage', 'dist', 'build');
const zipFilePath = await createZipWithSystemCommand(sourceDir, destDir);
console.log(`ZIP 文件路径: ${zipFilePath}`);
// 3) 自动打开zip所在的目录
await openFileDirectory(zipFilePath);
} else {
console.log('跳过创建 ZIP 文件和打开目录');
}
}
async function exists(p) {
try {
await fsp.access(p, fs.constants.F_OK);
return true;
} catch (e) {
return false;
}
}
async function ensureDir(dirPath) {
try {
await fsp.mkdir(dirPath, { recursive: true });
} catch (e) {
// ignore if exists
if (e.code !== 'EEXIST') throw e;
}
}
main();