chore(vue.config.js): 优化构建配置,新增鸿蒙元服务构建清理逻辑

1. 统一修复代码缩进格式,对齐代码风格
2. 新增构建平台控制台输出日志
3. 新增鸿蒙元服务构建前清理输出目录逻辑
4. 完善环境变量缺失的错误提示
5. 优化注释内容,补充说明用途
This commit is contained in:
2026-07-04 17:28:25 +08:00
parent 112c9a2aa5
commit 181717a7ab

View File

@@ -13,9 +13,12 @@ if (!process.env.UNI_APP_DOMAIN && process.env.UNI_SCRIPT) {
if (scriptCfg?.env?.UNI_APP_DOMAIN) {
process.env.UNI_APP_DOMAIN = scriptCfg.env.UNI_APP_DOMAIN;
}
} catch (e) {}
} catch (e) { }
}
// 输出当前构建的平台
console.log(`🏠 当前构建的平台: [${process.env.UNI_PLATFORM || '(未知)'}]\n`);
// 输出 H5 域名信息到控制台
if (process.env.UNI_PLATFORM === 'h5') {
console.log(`\n[H5 发行] 脚本: ${process.env.UNI_SCRIPT || '(默认)'}`);
@@ -27,10 +30,10 @@ if (process.env.UNI_PLATFORM === 'h5') {
// console.log(key, process.env[key]);
// }
// 定义UNI_OUTPUT_DIR环境变量(H5 自定义发行脚本使用)
// 定义UNI_OUTPUT_DIR环境变量(H5 自定义发行脚本使用/及其他构建处理)
try {
if (!process.env.NODE_ENV) {
console.error(`❌ NODE_ENV 环境变量未设置`);
throw new Error('NODE_ENV 环境变量未设置');
}
@@ -38,6 +41,15 @@ try {
const platform = process.env.UNI_PLATFORM || '';
const UNI_SCRIPT = process.env.UNI_SCRIPT ?? '';
// 针对鸿蒙元服务的发布,先清理构建输出目录
if (platform == 'mp-harmony') {
try {
const assetDir = path.join(__dirname, `unpackage/dist/${buildDir}/.mp-harmony`);
console.log(`🧹 清理构建目录 ${assetDir}\n`);
fs.rmSync(assetDir, { recursive: true, force: true });
} catch (e) {}
}
// 所有 H5 自定义脚本统一处理,无需在 vue.config.js 中硬编码脚本名
if (platform === 'h5' && UNI_SCRIPT) {
// 从 manifest.json 读取 h5.router.base,拼接到输出路径
@@ -45,7 +57,7 @@ try {
try {
const manifestPath = path.join(__dirname, 'manifest.json');
baseSuffix = _readManifestBase(manifestPath);
} catch (e) {}
} catch (e) { }
// 从脚本 env 中获取域名(优先使用 UNI_APP_DOMAIN,否则从 UNI_SCRIPT 提取)
let domain = '';
if (process.env.UNI_APP_DOMAIN) {
@@ -95,59 +107,59 @@ function _readManifestBase(manifestPath) {
* 用 fs 静态解析, 避免 webpack 把整个 config-external.js 链入 vue.config 编译路径
*/
function _readLangSource() {
try {
const content = fs.readFileSync(path.join(__dirname, 'common/js/config-external.js'), 'utf-8');
const match = content.match(/source:\s*['"]([\w-]+)['"]/);
return match ? match[1] : null;
} catch (e) {
return null;
}
try {
const content = fs.readFileSync(path.join(__dirname, 'common/js/config-external.js'), 'utf-8');
const match = content.match(/source:\s*['"]([\w-]+)['"]/);
return match ? match[1] : null;
} catch (e) {
return null;
}
}
/**
* 通用Webpack的资源替换插件
*/
class NormalModuleReplacementPlugin {
constructor(resourceRegExp, newResource) {
this.resourceRegExp = resourceRegExp;
this.newResource = newResource;
}
constructor(resourceRegExp, newResource) {
this.resourceRegExp = resourceRegExp;
this.newResource = newResource;
}
apply(compiler) {
const resourceRegExp = this.resourceRegExp;
const newResource = this.newResource;
compiler.hooks.normalModuleFactory.tap(
"NormalModuleReplacementPlugin",
nmf => {
nmf.hooks.beforeResolve.tap("NormalModuleReplacementPlugin", result => {
if (!result) return;
if (resourceRegExp.test(result.request)) {
if (typeof newResource === "function") {
newResource(result);
} else {
result.request = newResource;
}
}
return result;
});
nmf.hooks.afterResolve.tap("NormalModuleReplacementPlugin", result => {
if (!result) return;
if (resourceRegExp.test(result.resource)) {
if (typeof newResource === "function") {
newResource(result);
} else {
result.resource = path.resolve(
path.dirname(result.resource),
newResource
);
}
}
return result;
});
}
);
}
apply(compiler) {
const resourceRegExp = this.resourceRegExp;
const newResource = this.newResource;
compiler.hooks.normalModuleFactory.tap(
"NormalModuleReplacementPlugin",
nmf => {
nmf.hooks.beforeResolve.tap("NormalModuleReplacementPlugin", result => {
if (!result) return;
if (resourceRegExp.test(result.request)) {
if (typeof newResource === "function") {
newResource(result);
} else {
result.request = newResource;
}
}
return result;
});
nmf.hooks.afterResolve.tap("NormalModuleReplacementPlugin", result => {
if (!result) return;
if (resourceRegExp.test(result.resource)) {
if (typeof newResource === "function") {
newResource(result);
} else {
result.resource = path.resolve(
path.dirname(result.resource),
newResource
);
}
}
return result;
});
}
);
}
}
/**
@@ -376,6 +388,9 @@ class VersionInjectPlugin {
if (fs.existsSync(destDir)) {
try {
fs.rmSync(destDir, { recursive: true, force: true });
if (fs.existsSync(destDir)) {
fs.rmSync(destDir, { recursive: true, force: true });
}
console.log(` ✅ 已清空目标目录 ${destDir}`);
} catch (cleanErr) {
console.warn(` ⚠️ 清空目标目录 ${destDir} 失败,将尝试覆盖: ${cleanErr.message}`);
@@ -412,35 +427,35 @@ class VersionInjectPlugin {
// 导出配置
module.exports = {
productionSourceMap: false,
configureWebpack: config => {
console.log('config.mode = ', config.mode);
productionSourceMap: false,
configureWebpack: config => {
console.log('config.mode = ', config.mode);
// lang/ 目录排除: 仅在 remote-only 模式下生效
// 原理: webpack 把 require(`@/lang/${lang}/${path}.js`) 解析为 ContextModule,
// 会扫描并打包 lang/ 下所有 .js. 替换为 stub 后, 真正的 lang 文件不进 bundle.
// 条件: source === 'remote-only' (由 common/js/config-external.js 配置)
const langSource = _readLangSource();
if (langSource === 'remote-only') {
try {
const webpack = require('webpack');
const stubPath = path.resolve(__dirname, 'common/js/empty-lang-stub.js');
if (webpack?.NormalModuleReplacementPlugin){
// lang/ 目录排除: 仅在 remote-only 模式下生效
// 原理: webpack 把 require(`@/lang/${lang}/${path}.js`) 解析为 ContextModule,
// 会扫描并打包 lang/ 下所有 .js. 替换为 stub 后, 真正的 lang 文件不进 bundle.
// 条件: source === 'remote-only' (由 common/js/config-external.js 配置)
const langSource = _readLangSource();
if (langSource === 'remote-only') {
try {
const webpack = require('webpack');
const stubPath = path.resolve(__dirname, 'common/js/empty-lang-stub.js');
if (webpack?.NormalModuleReplacementPlugin) {
config.plugins.push(
new NormalModuleReplacementPlugin(
// 匹配解析后的绝对路径: .../lang/xxx/yyy.js
/[\\/]lang[\\/].+\.js$/,
stubPath
)
new NormalModuleReplacementPlugin(
// 匹配解析后的绝对路径: .../lang/xxx/yyy.js
/[\\/]lang[\\/].+\.js$/,
stubPath
)
);
console.log(`[vue.config] ✅ lang/ 目录已替换为 stub (source=remote-only) — 节省 lang 包体积`);
}
} catch (e) {
console.error('[vue.config] 配置 lang/ 排除失败:', e.message);
}
} else {
console.log(`[vue.config] lang/ 目录保留 (source=${langSource || 'unknown'})`);
}
} catch (e) {
console.error('[vue.config] 配置 lang/ 排除失败:', e.message);
}
} else {
console.log(`[vue.config] lang/ 目录保留 (source=${langSource || 'unknown'})`);
}
if (config.mode === 'production') {
console.log('开始尝试配置极限压缩');
@@ -479,7 +494,7 @@ module.exports = {
// 区分平台配置压缩选项
const isMpHarmony = process.env.UNI_PLATFORM === 'mp-harmony';
// 基础压缩配置(通用)
const terserOptions = {
compress: {
@@ -528,7 +543,7 @@ module.exports = {
module: false,
sourceMap: false
};
config.optimization.minimizer[terserPluginIndex].options.terserOptions = terserOptions;
console.log('配置极限压缩完成');
}