chore(vue.config.js): 优化构建配置,新增鸿蒙元服务构建清理逻辑
1. 统一修复代码缩进格式,对齐代码风格 2. 新增构建平台控制台输出日志 3. 新增鸿蒙元服务构建前清理输出目录逻辑 4. 完善环境变量缺失的错误提示 5. 优化注释内容,补充说明用途
This commit is contained in:
167
vue.config.js
167
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('配置极限压缩完成');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user