docs: 更新 readme 反映 H5 自动 ZIP 打包和统一配置方式
This commit is contained in:
69
readme.md
69
readme.md
@@ -83,37 +83,24 @@
|
||||
📌 **测试版**保留原有 `/hwappx/test/`
|
||||
💡 **个性化定制示例**:`/hwappx/2811/`,其中 2811 为定制化版客户编号
|
||||
|
||||
3. 选择菜单栏「发行」 → 「自定义发行」 →(「H5-xcx.aigc-quickapp.com」查看.local.config.js中站点的网址前缀,站点的网址前缀是什么就选自定义发行中相同的格式)
|
||||
例如:网址是5g.aigc-quickapp.com,自定义发行就选H5-5g.aigc-quickapp.com
|
||||
网址是dev.aigc-quickapp.com,自定义发行就选H5-xcx.aigc-quickapp.com
|
||||
3. 选择菜单栏「发行」 → 「自定义发行」 → 选择对应的站点脚本
|
||||
💡 例如:网址是 `5g.aigc-quickapp.com` 选 `H5-5g.aigc-quickapp.com`
|
||||
4. 修改以下配置:
|
||||
1. **网站标题**:快应用
|
||||
2. **网站域名**:当前客户域名(示例:xcx.aigc-quickapp.com或者5g.aigc-quickapp.com)
|
||||
2. **网站域名**:当前客户域名
|
||||
3. 确认后点击「发行」等待构建完成
|
||||
|
||||
⚠️ **注意**:底部控制台弹出“项目 lucky_shop 导出Web成功,路径为:D:\项目文件\项目根目录\unpackage\dist\build\web”后再执行下一步
|
||||
💡 **示例**:`项目 lucky_shop 导出Web成功,路径为:D:\0.项目源码\lucky_shop\unpackage\dist\build\web`
|
||||
5. 按控制台提示的路径找到 `web` 目录,将该目录下所有文件手动打包成一个 `.zip` 压缩包
|
||||
*仅打包文件,不包含外层 web 目录*
|
||||
⚠️ **注意**:构建完成后自动输出到 `unpackage/dist/build/h5/`,格式为 `{域名}-{base路径}.zip`
|
||||
💡 **示例**:`xcx.aigc-quickapp.com-hwappx.common-3bff91e-20260511_1058.zip`
|
||||
|
||||
##### 4.2.1.2 【重命名】
|
||||
1. 按版本类型规范重命名压缩包:
|
||||
- **通用版**:`hwappx-common-域名-时间.zip`
|
||||
💡 **示例**:`hwappx-common-xcx.aigc-quickapp.com-2026-01-24.zip`
|
||||
|
||||
- **定制化版**:`客户名称-定制化---hwappx-客户编号-域名-时间.zip`
|
||||
💡 **示例**:`POCT检测分析平台-定制化---hwappx-2811-xcx.aigc-quickapp.com-2026-01-24.zip`
|
||||
|
||||
🚫 **禁止**:压缩包命名禁止包含 `/ \ : * ? " < > |` 等特殊字符
|
||||
|
||||
##### 4.2.1.3 【交付与最终发布】🔍
|
||||
|
||||
1. 将重命名后的压缩包发送给运维人员
|
||||
##### 4.2.1.2 【交付与最终发布】🔍
|
||||
1. 将生成的 `.zip` 文件发送给运维人员
|
||||
2. **运维人员操作流程**:
|
||||
1. 解压压缩包
|
||||
2. 打开快应用开发者工具,导入解压后的代码目录
|
||||
3. 验证代码无报错后,执行上传发布操作
|
||||
##### 4.2.1.3 【测试流程】
|
||||
|
||||
##### 4.2.1.3 【测试流程】
|
||||
H5:打开自己的浏览器输入网址(https://5g.aigc-quickapp.com/hwappx/common/?uniacid=75)改站点
|
||||
如果是test就把hwappx/common/改为hwappx/test/----------改站点
|
||||
|
||||
@@ -134,22 +121,40 @@ H5:打开自己的浏览器输入网址(https://5g.aigc-quickapp.com/hwappx/co
|
||||
- **commitId**:当前构建的 Git 短提交 ID
|
||||
- **buildTime**:构建时间
|
||||
|
||||
> **开发模式**:HMR 热更新时自动跳过重复注入,不影响开发体验。
|
||||
> **开发模式**:HMR 热更新时由 webpack emit 钩子自动处理,不影响开发体验。
|
||||
|
||||
### 5.2 可用的 npm 脚本命令
|
||||
### 5.2 自动 ZIP 打包
|
||||
|
||||
| 命令 | 说明 |
|
||||
**H5 自定义发行**构建完成后自动执行:
|
||||
|
||||
| 步骤 | 说明 |
|
||||
|------|------|
|
||||
| `npm run mp-weixin` | 拷贝 site.js + config 文件 + 创建 ZIP 压缩包(用于手动触发) |
|
||||
| 重命名输出目录 | `{域名}-{base路径用.连接}`(如 `xcx.aigc-quickapp.com-hwappx.common`) |
|
||||
| 创建 ZIP 文件 | 文件名格式:`{目录名}-{Git提交ID}-{上海时区时间戳}.zip` |
|
||||
| 清理 | ZIP 创建完成后自动删除源目录 |
|
||||
|
||||
> 生产构建时,ZIP 打包由构建插件自动触发,通常无需手动执行此命令。
|
||||
💡 **示例 ZIP**:`xcx.aigc-quickapp.com-hwappx.common-3bff91e-20260511_1058.zip`
|
||||
|
||||
### 5.3 构建后处理功能(mp-weixin.patch.js)
|
||||
**微信小程序**生产构建时自动执行:
|
||||
- 拷贝 `site.js` / `project.config.json` / `project.private.config.json` 到构建目录
|
||||
- 创建 ZIP 包(文件名包含 Git 提交 ID)
|
||||
|
||||
- 复制 `project.config.json` 和 `project.private.config.json` 到构建目录
|
||||
- 复制 `site.js` 到构建目录
|
||||
- 创建 ZIP 压缩包(文件名包含 Git 提交 ID)
|
||||
- 自动打开 ZIP 文件所在目录
|
||||
### 5.3 环境配置
|
||||
|
||||
域名配置统一通过 `package.json` 中各脚本的 `env.UNI_APP_DOMAIN` 传入:
|
||||
|
||||
```json
|
||||
"h5-xcx.aigc-quickapp.com": {
|
||||
"title": "...",
|
||||
"env": {
|
||||
"UNI_PLATFORM": "h5",
|
||||
"UNI_APP_DOMAIN": "https://xcx.aigc-quickapp.com/"
|
||||
},
|
||||
"define": { "PRODUCTION": true }
|
||||
}
|
||||
```
|
||||
|
||||
`config.js` 和 `vue.config.js` 均通过 `process.env.UNI_APP_DOMAIN` 读取,**新增/删除脚本无需改动代码**。
|
||||
|
||||
---
|
||||
|
||||
|
||||
106
vue.config.js
106
vue.config.js
@@ -1,4 +1,5 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { execSync } = require('child_process');
|
||||
const { zionUniMpLoadPackagePlugin } = require('zion-uniapp-mp-load-package/webpack');
|
||||
|
||||
@@ -25,11 +26,8 @@ try {
|
||||
// 从 manifest.json 读取 h5.router.base,拼接到输出路径
|
||||
let baseSuffix = '';
|
||||
try {
|
||||
const manifest = require('./manifest.json');
|
||||
if (manifest?.h5?.router?.base) {
|
||||
// 将 /hwappx/common/ 转换为 hwappx.common
|
||||
baseSuffix = manifest.h5.router.base.replace(/^\/+|\/+$/g, '').replace(/\//g, '.');
|
||||
}
|
||||
const manifestPath = path.join(__dirname, 'manifest.json');
|
||||
baseSuffix = _readManifestBase(manifestPath);
|
||||
} catch (e) {}
|
||||
// 从脚本 env 中获取域名(优先使用 UNI_APP_DOMAIN,否则从 UNI_SCRIPT 提取)
|
||||
let domain = '';
|
||||
@@ -52,6 +50,25 @@ try {
|
||||
console.log('NODE_ENV 环境变量未设置,默认使用开发模式');
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 manifest.json 中的 h5.router.base,去掉注释后解析
|
||||
* 返回 base 路径的 . 连接形式(如 /hwappx/common/ → hwappx.common)
|
||||
*/
|
||||
function _readManifestBase(manifestPath) {
|
||||
try {
|
||||
const raw = fs.readFileSync(manifestPath, 'utf8');
|
||||
// 去掉 /* */ 和 // 注释(HBuilder 生成的 JSON 允许注释)
|
||||
const clean = raw.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/.*$/gm, '');
|
||||
const manifest = JSON.parse(clean);
|
||||
if (manifest?.h5?.router?.base) {
|
||||
return manifest.h5.router.base.replace(/^\/+|\/+$/g, '').replace(/\//g, '.');
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[manifest] 读取 h5.router.base 失败:', e.message);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义 webpack 插件:在通用产物(vendor.js)中内联注入版本数据
|
||||
* 利用 emit 钩子在资源写入磁盘前处理,支持 HMR(每次重编译都会自动注入)
|
||||
@@ -148,8 +165,8 @@ class VersionInjectPlugin {
|
||||
} catch (e) {
|
||||
console.error('补丁脚本执行失败:', e.message);
|
||||
}
|
||||
} else if (platform === 'h5' && UNI_SCRIPT && this._cachedCommitId) {
|
||||
this._zipH5Build(UNI_SCRIPT, this._cachedCommitId);
|
||||
} else if (platform === 'h5' && UNI_SCRIPT) {
|
||||
this._zipH5Build(compilation);
|
||||
}
|
||||
|
||||
callback();
|
||||
@@ -157,15 +174,9 @@ class VersionInjectPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
_zipH5Build(UNI_SCRIPT, commitId) {
|
||||
// 计算输出目录名(与 UNI_OUTPUT_DIR 逻辑一致)
|
||||
let baseSuffix = '';
|
||||
try {
|
||||
const manifest = require('./manifest.json');
|
||||
if (manifest?.h5?.router?.base) {
|
||||
baseSuffix = manifest.h5.router.base.replace(/^\/+|\/+$/g, '').replace(/\//g, '.');
|
||||
}
|
||||
} catch (e) {}
|
||||
_computeH5OutputName() {
|
||||
// 计算输出目录名: {域名}-{base用.连接}
|
||||
let baseSuffix = _readManifestBase(path.join(__dirname, 'manifest.json'));
|
||||
let domain = '';
|
||||
if (process.env.UNI_APP_DOMAIN) {
|
||||
try {
|
||||
@@ -174,45 +185,76 @@ class VersionInjectPlugin {
|
||||
domain = process.env.UNI_APP_DOMAIN.replace(/^https?:\/\//, '').replace(/\/.*$/, '');
|
||||
}
|
||||
} else {
|
||||
domain = UNI_SCRIPT.replace(/^h5-/, '');
|
||||
domain = (process.env.UNI_SCRIPT || '').replace(/^h5-/, '');
|
||||
}
|
||||
const outputDirName = baseSuffix ? `${domain}-${baseSuffix}` : domain;
|
||||
const result = baseSuffix ? `${domain}-${baseSuffix}` : domain;
|
||||
console.log('[H5Zip] 输出目录名:', result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 上海时区时间(UTC+8)
|
||||
_zipH5Build(compilation) {
|
||||
const outputDirName = this._computeH5OutputName();
|
||||
const buildDir = process.env.NODE_ENV === 'production' ? 'build' : 'dev';
|
||||
const h5Dir = path.join(__dirname, 'unpackage', 'dist', buildDir, 'h5');
|
||||
|
||||
// 实际构建输出目录(由 webpack 决定)
|
||||
const actualOutput = compilation.compiler.outputPath;
|
||||
const targetDir = path.join(h5Dir, outputDirName);
|
||||
|
||||
// 如果路径一致,跳过重命名
|
||||
if (actualOutput !== targetDir) {
|
||||
try {
|
||||
if (fs.existsSync(targetDir)) {
|
||||
fs.rmSync(targetDir, { recursive: true });
|
||||
}
|
||||
fs.renameSync(actualOutput, targetDir);
|
||||
console.log(`[H5Zip] 输出目录已重命名为: ${outputDirName}`);
|
||||
} catch (e) {
|
||||
console.error('[H5Zip] 目录重命名失败:', e.message);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
console.log(`[H5Zip] 输出目录名正确: ${outputDirName}`);
|
||||
}
|
||||
|
||||
// 上海时区时间戳格式: 20260511_1058
|
||||
const now = new Date();
|
||||
const shanghaiOffset = 8 * 60;
|
||||
const shanghaiTime = new Date(now.getTime() + shanghaiOffset * 60 * 1000);
|
||||
const ts = shanghaiTime.toISOString().replace(/[^0-9]/g, '').slice(0, 14);
|
||||
const y = shanghaiTime.getFullYear();
|
||||
const M = String(shanghaiTime.getMonth() + 1).padStart(2, '0');
|
||||
const d = String(shanghaiTime.getDate()).padStart(2, '0');
|
||||
const h = String(shanghaiTime.getHours()).padStart(2, '0');
|
||||
const m = String(shanghaiTime.getMinutes()).padStart(2, '0');
|
||||
const ts = `${y}${M}${d}_${h}${m}`;
|
||||
|
||||
const buildDir = process.env.NODE_ENV === 'production' ? 'build' : 'dev';
|
||||
const sourceDir = path.join(__dirname, 'unpackage', 'dist', buildDir, 'h5', outputDirName);
|
||||
const destDir = path.join(__dirname, 'unpackage', 'dist', buildDir, 'h5');
|
||||
const zipFileName = `${outputDirName}-${commitId}-${ts}.zip`;
|
||||
const zipFilePath = path.join(destDir, zipFileName);
|
||||
const zipFileName = `${outputDirName}-${this._cachedCommitId}-${ts}.zip`;
|
||||
const zipFilePath = path.join(h5Dir, zipFileName);
|
||||
|
||||
console.log(`\n📦 H5 构建完成,打包 ZIP: ${zipFileName}...`);
|
||||
console.log(`\n📦 H5 ZIP: ${zipFileName}...`);
|
||||
|
||||
let command;
|
||||
const sourcePath = sourceDir.replace(/'/g, "''");
|
||||
const sourcePath = targetDir.replace(/'/g, "''");
|
||||
const destPath = zipFilePath.replace(/'/g, "''");
|
||||
if (process.platform === 'win32') {
|
||||
command = `powershell -Command "Compress-Archive -Path '${sourcePath}\\*' -DestinationPath '${destPath}' -Force"`;
|
||||
} else {
|
||||
const sourceBase = path.dirname(sourceDir);
|
||||
const sourceName = path.basename(sourceDir);
|
||||
const sourceBase = path.dirname(targetDir);
|
||||
const sourceName = path.basename(targetDir);
|
||||
command = `cd '${sourceBase}' && zip -r '${zipFilePath}' '${sourceName}' -x '*/node_modules/*' '*.git/*' '*.DS_Store'`;
|
||||
}
|
||||
|
||||
try {
|
||||
execSync(command, { stdio: 'inherit' });
|
||||
console.log(`✅ H5 ZIP 文件已创建: ${zipFileName}`);
|
||||
console.log(`✅ H5 ZIP: ${zipFileName}`);
|
||||
// 删除已打包的源目录
|
||||
fs.rmSync(targetDir, { recursive: true, force: true });
|
||||
console.log(`[H5Zip] 已删除源目录: ${outputDirName}`);
|
||||
} catch (e) {
|
||||
console.error('H5 ZIP 打包失败:', e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导出配置
|
||||
module.exports = {
|
||||
|
||||
Reference in New Issue
Block a user