From 181717a7abefc0d52b09d1e04d80712fdbf859ea Mon Sep 17 00:00:00 2001 From: ZF sun <34314687@qq.com> Date: Sat, 4 Jul 2026 17:28:25 +0800 Subject: [PATCH] =?UTF-8?q?chore(vue.config.js):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E9=85=8D=E7=BD=AE=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=B8=BF=E8=92=99=E5=85=83=E6=9C=8D=E5=8A=A1=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E6=B8=85=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 统一修复代码缩进格式,对齐代码风格 2. 新增构建平台控制台输出日志 3. 新增鸿蒙元服务构建前清理输出目录逻辑 4. 完善环境变量缺失的错误提示 5. 优化注释内容,补充说明用途 --- vue.config.js | 167 +++++++++++++++++++++++++++----------------------- 1 file changed, 91 insertions(+), 76 deletions(-) diff --git a/vue.config.js b/vue.config.js index 1eb470c..276fc88 100644 --- a/vue.config.js +++ b/vue.config.js @@ -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('配置极限压缩完成'); }