@infly/libs 2.0.25 → 2.0.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/cli.js +1 -0
- package/build/build-dist/index.js +64 -32
- package/build/webpack5/remove-legacy-assets-plugin.js +84 -0
- package/build/webpack5/webpack.base.js +218 -19
- package/index.js +10 -0
- package/module/Permission.js +101 -42
- package/module/REST.js +62 -15
- package/module/Router.js +15 -0
- package/module/Uts.js +299 -288
- package/package.json +89 -88
- package/script/git-automation/index.js +165 -18
- package/script/index.js +3 -3
- package/script/webhook/webhook.js +5 -4
- package/store/modules/user.js +94 -9
- package/tools/file-export.js +20 -1
- package/tools/file-process.js +3 -0
- package/types/unused.index.d.ts +14 -14
- package/dataInit/commonTypeMap.js +0 -31
- package/dataInit/marketingActivitiesMap.js +0 -214
- package/dataInit/orderMap.js +0 -13
- package/dataInit/personalMap.js +0 -19
- package/dataInit/settlementMap.js +0 -17
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
## 软件架构
|
|
12
12
|
|
|
13
|
-
infly
|
|
13
|
+
@infly/libs
|
|
14
14
|
├── bin - 脚本文件暴露为可直接调用的命令
|
|
15
15
|
│ └── cli.js - 命令入口调用方法判断
|
|
16
16
|
├── build - 构建相关工具库
|
|
@@ -35,5 +35,5 @@ infly-libs
|
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
# 项目安装
|
|
38
|
-
npm/pnpm install infly
|
|
38
|
+
npm/pnpm install @infly/libs
|
|
39
39
|
```
|
package/bin/cli.js
CHANGED
|
@@ -25,7 +25,6 @@ const { postVersionFileAndMsg } = require("../../script/webhook/webhook.js");
|
|
|
25
25
|
const { scriptWrite, targetProjectFileResolve, currentProjectFileResolve } = require("../../tools/file-process.js");
|
|
26
26
|
const {
|
|
27
27
|
autoBranchProcess,
|
|
28
|
-
checkGitStatus,
|
|
29
28
|
autoGitProcess,
|
|
30
29
|
getCurrentBranch,
|
|
31
30
|
getLatestCommitInfo,
|
|
@@ -35,7 +34,7 @@ const {
|
|
|
35
34
|
|
|
36
35
|
const scriptEvent = process.env.npm_lifecycle_event;
|
|
37
36
|
const isBuilZipScript = process.env.npm_lifecycle_event;
|
|
38
|
-
const testScript = "
|
|
37
|
+
const testScript = "build:test";
|
|
39
38
|
const versionFileName = "package.json";
|
|
40
39
|
const oldVersionFileName = "version-config.json";
|
|
41
40
|
const npmPackageConfigKey = "infly";
|
|
@@ -53,36 +52,35 @@ const { infly: currentInflyConfig } = currentPackageJsonConfig || {};
|
|
|
53
52
|
const targetProjectVersionConfigPath = targetProjectFileResolve(oldVersionFileName);
|
|
54
53
|
const targetProjectVueConfigPath = targetProjectFileResolve("vue.config.js");
|
|
55
54
|
const targetProjectPackageJSON = targetProjectFileResolve("package.json");
|
|
55
|
+
const targetProjectSettingsJS = targetProjectFileResolve("src/settings.js");
|
|
56
56
|
const targetPackageJsonConfig = JSON.parse(fs.readFileSync(targetProjectPackageJSON, "utf-8"));
|
|
57
57
|
const { name: projectName, version: projectVersion = "", infly: targetInflyConfig } = targetPackageJsonConfig || {};
|
|
58
58
|
const [major = "", minor = "", patch = ""] = projectVersion.split(".");
|
|
59
|
+
const { title: projectTitle } = fs.existsSync(targetProjectSettingsJS) ? require(targetProjectSettingsJS) || {} : {};
|
|
59
60
|
|
|
60
61
|
const isExistTargetProjectVersionConfig = fs.existsSync(targetProjectVersionConfigPath); // 安装依赖项目下是否存在旧版本控制文件
|
|
61
62
|
const isExistVueConfigFile = fs.existsSync(targetProjectVueConfigPath); // 安装依赖项目下是否存在vue.config.js文件
|
|
62
63
|
const isMaster = currentBranch === "master"; // 是否在master分支
|
|
63
|
-
const dealBranch = isMaster ? "master" : "release";
|
|
64
64
|
const isPkg = versionFileName === "package.json";
|
|
65
65
|
|
|
66
66
|
const targetProjectVueConfig = isExistVueConfigFile ? require(targetProjectVueConfigPath) : {};
|
|
67
67
|
const { outputDir: targetProjectOutputDir, configureWebpack } = targetProjectVueConfig || {};
|
|
68
68
|
|
|
69
|
-
const { updateDevText } =
|
|
70
|
-
{ master: { updateDevText: "正式环境" }, release: { updateDevText: "测试环境" } }[dealBranch] || {}; // 更新环境和处理分支
|
|
69
|
+
const { updateDevText = "测试环境" } = { master: { updateDevText: "正式环境" } }[currentBranch] || {}; // 更新环境和处理分支
|
|
71
70
|
|
|
72
71
|
const configPath = path.resolve(projectRoot, versionFileName);
|
|
73
72
|
let buildConfig = JSON.parse(fs.readFileSync(configPath, "utf-8")) || {};
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
73
|
+
|
|
74
|
+
buildConfig = normalizeBuildConfig(buildConfig, npmPackageConfigKey, currentBranch, projectTitle);
|
|
77
75
|
|
|
78
76
|
// 准备构建信息
|
|
79
|
-
const {
|
|
77
|
+
const { buildConfigs, versionConfig } = buildConfig || {};
|
|
80
78
|
const {
|
|
81
79
|
buildFoldName: zipBuildFoldName, // 构建后文件名称
|
|
82
80
|
outputPath, // 输出路径
|
|
83
81
|
gitAuto, // 是否自动提交git
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
gitAutoPushReposBranchMap, // 自动提交文件到对应仓库分支配置
|
|
83
|
+
gitAutoPushRepos = gitAutoPushReposBranchMap, // 自动提交文件到对应仓库
|
|
86
84
|
gitAutoCommitText = "", // git自动提交信息
|
|
87
85
|
enablePreview, // 启用预览
|
|
88
86
|
openExplorer, // 启用打开资源管理器
|
|
@@ -90,7 +88,7 @@ const {
|
|
|
90
88
|
webhookAtUser, // 企业微信机器人@用户
|
|
91
89
|
enableClipboard, // 启用粘贴板
|
|
92
90
|
disableUpdateVersionEnv // 禁止更新版本信息环境
|
|
93
|
-
} =
|
|
91
|
+
} = buildConfigs || {};
|
|
94
92
|
const buildFoldName = zipBuildFoldName || targetProjectOutputDir || "dist";
|
|
95
93
|
const { mainVersion: verMainVersion, platformName, baseName, versionList = [], links } = versionConfig || {};
|
|
96
94
|
const mainVersion = verMainVersion || major; // 主版本号
|
|
@@ -116,7 +114,10 @@ async function init() {
|
|
|
116
114
|
const newFileName = baseFileName.replace("{version}", newVersion).replace("{timestamp}", timestamp);
|
|
117
115
|
const gitInfo = getLatestCommitInfo() || {};
|
|
118
116
|
const { branch, commitMsg } = gitInfo || {};
|
|
119
|
-
|
|
117
|
+
let tempLink = typeof links === "object" ? links[branch] : links || "";
|
|
118
|
+
if (typeof tempLink === "object") {
|
|
119
|
+
tempLink = tempLink[process.env.VUE_APP_PLATFORM] || tempLink["DEFAULT"] || JSON.stringify(tempLink);
|
|
120
|
+
}
|
|
120
121
|
const publishText = `${platformName}:\n更新到:${tempLink}\n更新时间:${timestamp}\n版本号:v${newVersion}\n分支:${branch}\n更新环境:${updateDevText}\n更新内容:\n${commitMsg}`;
|
|
121
122
|
const newZipFileInfo = [
|
|
122
123
|
{
|
|
@@ -157,7 +158,6 @@ async function init() {
|
|
|
157
158
|
projectName
|
|
158
159
|
};
|
|
159
160
|
|
|
160
|
-
checkGitStatus(buildFoldName, newFileName, checkGitStatusParams);
|
|
161
161
|
autoGitProcess(buildFoldName, newFileName, {
|
|
162
162
|
gitInfo,
|
|
163
163
|
gitAutoCommitText,
|
|
@@ -180,7 +180,8 @@ async function init() {
|
|
|
180
180
|
newFileName,
|
|
181
181
|
gitInfo,
|
|
182
182
|
targetProjectOutputDir,
|
|
183
|
-
|
|
183
|
+
repos: path.relative(__dirname, targetProjectOutputDir).replace(/^(\.\.\\){4}apps\\/, ""),
|
|
184
|
+
...buildConfigs
|
|
184
185
|
});
|
|
185
186
|
}
|
|
186
187
|
|
|
@@ -193,6 +194,44 @@ async function init() {
|
|
|
193
194
|
}
|
|
194
195
|
}
|
|
195
196
|
|
|
197
|
+
/**
|
|
198
|
+
* 规范化构建配置
|
|
199
|
+
* @param {Object} config - 原始配置对象
|
|
200
|
+
* @param {String} packageKey - 包配置键名
|
|
201
|
+
* @param {String} branch - 当前分支
|
|
202
|
+
* @param {String} title - 项目标题
|
|
203
|
+
* @returns {Object} 规范化后的配置对象
|
|
204
|
+
*/
|
|
205
|
+
function normalizeBuildConfig(config, packageKey, branch, title) {
|
|
206
|
+
let normalizedConfig = config;
|
|
207
|
+
|
|
208
|
+
// 提取嵌套的配置
|
|
209
|
+
if (normalizedConfig[packageKey]) {
|
|
210
|
+
normalizedConfig = normalizedConfig[packageKey];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// 自动启用 gitAutoPushRepos
|
|
214
|
+
if (!normalizedConfig.gitAutoPushRepos && normalizedConfig.gitAutoPushReposBranchMap) {
|
|
215
|
+
normalizedConfig.gitAutoPushRepos = true;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 处理平台名称配置
|
|
219
|
+
if (typeof normalizedConfig?.versionConfig?.platformName === "object") {
|
|
220
|
+
normalizedConfig.versionConfig.platformName =
|
|
221
|
+
normalizedConfig.versionConfig.platformName[branch] ||
|
|
222
|
+
normalizedConfig.versionConfig.platformName["master"] ||
|
|
223
|
+
"构建平台";
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// 使用项目标题作为默认平台名称
|
|
227
|
+
if (title && !normalizedConfig.versionConfig?.platformName) {
|
|
228
|
+
normalizedConfig.versionConfig = normalizedConfig.versionConfig || {};
|
|
229
|
+
normalizedConfig.versionConfig.platformName = title;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return normalizedConfig;
|
|
233
|
+
}
|
|
234
|
+
|
|
196
235
|
/**
|
|
197
236
|
* 用户确认提示
|
|
198
237
|
* @param {string} message - 提示信息
|
|
@@ -235,32 +274,25 @@ async function validateConfig(buildConfig) {
|
|
|
235
274
|
process.exit(1);
|
|
236
275
|
}
|
|
237
276
|
|
|
238
|
-
if (buildConfig?.
|
|
277
|
+
if (buildConfig?.buildConfigs?.enabled === false) {
|
|
239
278
|
console.warn(global.logColor.error, `⚠️ ZIP压缩已禁用,版本控制文件${versionFileName}中的enabled属性设置为false`);
|
|
240
279
|
process.exit(0);
|
|
241
280
|
}
|
|
242
281
|
|
|
243
|
-
if (
|
|
282
|
+
if (!buildConfig?.buildConfigs?.gitAutoPushReposBranchMap[currentBranch]) {
|
|
244
283
|
if (![testScript].includes(scriptEvent)) {
|
|
245
|
-
console.error(global.logColor.error, `❌ 当前分支非
|
|
284
|
+
console.error(global.logColor.error, `❌ 当前分支非gitAutoPushReposBranchMap配置可构建分支,请检查`);
|
|
246
285
|
process.exit(1);
|
|
247
286
|
}
|
|
248
287
|
}
|
|
249
288
|
|
|
250
|
-
if (currentBranch !== "master" && currentBranch !== "release" && !/^release/.test(currentBranch)) {
|
|
251
|
-
console.warn(
|
|
252
|
-
global.logColor.warning,
|
|
253
|
-
`⚠️ 当前分支为 ${currentBranch},非测试需求请在 master/release/release/xxx 等可构建分支上执行此脚本`
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
289
|
if (currentBranch === "master" && !process.env.npm_lifecycle_event.includes("prod")) {
|
|
258
290
|
console.error(global.logColor.error, `❌ 当前分支为 master 分支,请使用正式环境构建命令进行构建`);
|
|
259
291
|
process.exit(1);
|
|
260
292
|
}
|
|
261
293
|
|
|
262
|
-
if (currentBranch
|
|
263
|
-
console.warn(global.logColor.warning, `⚠️ 当前分支为
|
|
294
|
+
if (currentBranch !== "master" && !process.env.npm_lifecycle_event.includes("stage")) {
|
|
295
|
+
console.warn(global.logColor.warning, `⚠️ 当前分支为 ${currentBranch} 分支,建议使用测试环境构建命令`);
|
|
264
296
|
console.log(global.logColor.info, `推荐命令: npm run infly:build:stage`);
|
|
265
297
|
|
|
266
298
|
const shouldContinue = await askUserConfirmation("确定要继续当前构建吗?", false);
|
|
@@ -373,7 +405,7 @@ function checkIsDisableUpdateVersionEnv(disableUpdateVersionEnv = []) {
|
|
|
373
405
|
*/
|
|
374
406
|
function updateVersionList(zipFiles = [], extraParams) {
|
|
375
407
|
const { opt = "update", buildConfig, configPath } = extraParams || {};
|
|
376
|
-
const { versionConfig
|
|
408
|
+
const { versionConfig } = buildConfig || {};
|
|
377
409
|
const { versionList = [] } = versionConfig || {};
|
|
378
410
|
const { disableUpdateVersionEnv } = versionConfig || {};
|
|
379
411
|
const isDisableUpdateVersionEnv = checkIsDisableUpdateVersionEnv(disableUpdateVersionEnv);
|
|
@@ -541,12 +573,12 @@ function scriptInit() {
|
|
|
541
573
|
// 如果存在以前的版本管理文件则进行配置迁移
|
|
542
574
|
if (isExistTargetProjectVersionConfig) {
|
|
543
575
|
tempInflyConfig = JSON.parse(fs.readFileSync(targetProjectVersionConfigPath, "utf-8"));
|
|
544
|
-
const { versionConfig = {},
|
|
576
|
+
const { versionConfig = {}, buildConfigs = {} } = tempInflyConfig || {};
|
|
545
577
|
if (versionConfig.versionList) {
|
|
546
578
|
tempInflyConfig.versionConfig.versionList = []; // 删除旧版本列表
|
|
547
579
|
}
|
|
548
|
-
if (
|
|
549
|
-
tempInflyConfig.
|
|
580
|
+
if (buildConfigs.buildFoldName) {
|
|
581
|
+
tempInflyConfig.buildConfigs.buildFoldName = "";
|
|
550
582
|
}
|
|
551
583
|
}
|
|
552
584
|
|
|
@@ -590,7 +622,7 @@ function copyVersionConfigFile() {
|
|
|
590
622
|
const tempVersionConfig = JSON.parse(data);
|
|
591
623
|
|
|
592
624
|
if (targetProjectOutputDir) {
|
|
593
|
-
tempVersionConfig.
|
|
625
|
+
tempVersionConfig.buildConfigs.buildFoldName = targetProjectOutputDir;
|
|
594
626
|
}
|
|
595
627
|
|
|
596
628
|
if (projectTitle) {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RemoveLegacyAssetsPlugin
|
|
3
|
+
* 用于处理 Vue CLI Modern Mode 的 legacy 文件问题
|
|
4
|
+
*
|
|
5
|
+
* 功能:
|
|
6
|
+
* 1. 在构建前创建占位文件,防止 ModernModePlugin 读取时报错
|
|
7
|
+
* 2. 在构建时删除 legacy 相关的资源
|
|
8
|
+
* 3. 在构建完成后清理占位文件
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
class RemoveLegacyAssetsPlugin {
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
this.options = {
|
|
19
|
+
legacyFiles: [
|
|
20
|
+
'legacy-assets-index.html.json',
|
|
21
|
+
'modern-assets-index.html.json'
|
|
22
|
+
],
|
|
23
|
+
...options
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
apply(compiler) {
|
|
28
|
+
const outputPath = compiler.options.output.path;
|
|
29
|
+
const { legacyFiles } = this.options;
|
|
30
|
+
|
|
31
|
+
// 🔥 Hook 1: 构建开始前创建占位文件
|
|
32
|
+
compiler.hooks.beforeRun.tapAsync('RemoveLegacyAssetsPlugin', (compiler, callback) => {
|
|
33
|
+
// 确保输出目录存在
|
|
34
|
+
if (!fs.existsSync(outputPath)) {
|
|
35
|
+
fs.mkdirSync(outputPath, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 创建空数组的 JSON 文件(Vue CLI 期望数组格式)
|
|
39
|
+
legacyFiles.forEach(file => {
|
|
40
|
+
const filePath = path.join(outputPath, file);
|
|
41
|
+
try {
|
|
42
|
+
fs.writeFileSync(filePath, '[]');
|
|
43
|
+
} catch (err) {
|
|
44
|
+
// 忽略创建失败的错误
|
|
45
|
+
console.warn(`⚠ Failed to create placeholder: ${file}`, err.message);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
callback();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// 🔥 Hook 2: 构建时删除编译产物中的 legacy 资源
|
|
53
|
+
compiler.hooks.emit.tapAsync('RemoveLegacyAssetsPlugin', (compilation, callback) => {
|
|
54
|
+
Object.keys(compilation.assets).forEach(filename => {
|
|
55
|
+
if (filename.includes('-legacy') || filename.includes('legacy-assets')) {
|
|
56
|
+
delete compilation.assets[filename];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
callback();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// 🔥 Hook 3: 构建完成后清理占位文件
|
|
63
|
+
compiler.hooks.done.tapAsync('RemoveLegacyAssetsPlugin', (stats, callback) => {
|
|
64
|
+
// 延迟执行,确保所有读取操作完成
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
legacyFiles.forEach(file => {
|
|
67
|
+
const filePath = path.join(outputPath, file);
|
|
68
|
+
try {
|
|
69
|
+
if (fs.existsSync(filePath)) {
|
|
70
|
+
fs.unlinkSync(filePath);
|
|
71
|
+
console.log(`\x1b[32m✓ Cleaned up: ${file}\x1b[0m`);
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
// 忽略删除失败的错误
|
|
75
|
+
console.warn(`⚠ Failed to cleanup: ${file}`, err.message);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
callback();
|
|
79
|
+
}, 100);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = RemoveLegacyAssetsPlugin;
|
|
@@ -2,12 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const InlineRuntimePlugin = require("./inline-runtime-plugin");
|
|
5
|
+
const RemoveLegacyAssetsPlugin = require("./remove-legacy-assets-plugin");
|
|
5
6
|
|
|
6
7
|
// 环境变量与常量配置
|
|
7
8
|
const ENV = {
|
|
8
|
-
IS_PROD: ["production", "staging"].includes(process.env.NODE_ENV)
|
|
9
|
+
IS_PROD: ["production", "staging"].includes(process.env.NODE_ENV),
|
|
10
|
+
IS_STAGING: process.env.ENV === "staging",
|
|
11
|
+
IS_DEV: process.env.ENV === "development"
|
|
9
12
|
};
|
|
10
13
|
|
|
14
|
+
// 强制禁用 modern mode(staging 环境)
|
|
15
|
+
if (ENV.IS_STAGING) {
|
|
16
|
+
process.env.VUE_CLI_MODERN_MODE = "false";
|
|
17
|
+
process.env.VUE_CLI_MODERN_BUILD = "false";
|
|
18
|
+
console.log("\n\x1b[36m⚡ Building for STAGING with Modern Bundle only (仅现代浏览器)...\x1b[0m");
|
|
19
|
+
}
|
|
20
|
+
|
|
11
21
|
/**
|
|
12
22
|
* 解析项目路径(兼容monorepo)
|
|
13
23
|
* @param {string} dir 相对路径
|
|
@@ -33,7 +43,8 @@ function createNodePolyfills() {
|
|
|
33
43
|
/**
|
|
34
44
|
* CSS/SCSS配置
|
|
35
45
|
*/
|
|
36
|
-
function cssModule(
|
|
46
|
+
function cssModule(cssConfig = {}) {
|
|
47
|
+
const { additionalData = "" } = cssConfig || {};
|
|
37
48
|
return {
|
|
38
49
|
loaderOptions: {
|
|
39
50
|
sass: {
|
|
@@ -41,8 +52,13 @@ function cssModule({ additionalData }) {
|
|
|
41
52
|
sassOptions: {
|
|
42
53
|
api: "modern",
|
|
43
54
|
quietDeps: true,
|
|
44
|
-
silenceDeprecations: ["legacy-js-api", "function-units"]
|
|
55
|
+
silenceDeprecations: ["legacy-js-api", "function-units", "import"],
|
|
56
|
+
// 添加以下配置来优化内存使用
|
|
57
|
+
outputStyle: "compressed", // 压缩输出
|
|
58
|
+
sourceMap: false // 禁用 source map(开发环境可启用)
|
|
45
59
|
},
|
|
60
|
+
// 使用 webpackImporter 来优化模块解析
|
|
61
|
+
webpackImporter: true,
|
|
46
62
|
additionalData
|
|
47
63
|
},
|
|
48
64
|
css: {
|
|
@@ -53,23 +69,33 @@ function cssModule({ additionalData }) {
|
|
|
53
69
|
}
|
|
54
70
|
}
|
|
55
71
|
},
|
|
56
|
-
extract: ENV.IS_PROD
|
|
72
|
+
extract: ENV.IS_PROD
|
|
73
|
+
? {
|
|
74
|
+
ignoreOrder: true,
|
|
75
|
+
// 添加缓存配置
|
|
76
|
+
chunkFilename: "css/[name].[contenthash:8].css"
|
|
77
|
+
}
|
|
78
|
+
: false
|
|
57
79
|
};
|
|
58
80
|
}
|
|
59
81
|
|
|
60
82
|
/**
|
|
61
83
|
* 基础 configureWebpack 配置
|
|
62
84
|
*/
|
|
63
|
-
function configureWebpack(
|
|
64
|
-
|
|
85
|
+
function configureWebpack(extraConfig = {}) {
|
|
86
|
+
const { name, alias } = extraConfig || {};
|
|
87
|
+
const config = {
|
|
65
88
|
name,
|
|
66
89
|
resolve: {
|
|
67
90
|
alias: {
|
|
68
91
|
vue$: "vue/dist/vue.esm.js",
|
|
69
|
-
|
|
70
|
-
"@
|
|
92
|
+
...(alias || {}),
|
|
93
|
+
"@": resolve("src")
|
|
71
94
|
},
|
|
72
|
-
fallback: createNodePolyfills()
|
|
95
|
+
fallback: createNodePolyfills(),
|
|
96
|
+
// 优化模块解析
|
|
97
|
+
extensions: [".js", ".vue", ".json", ".jsx"],
|
|
98
|
+
modules: ["node_modules"]
|
|
73
99
|
},
|
|
74
100
|
target: ["web", "es5"],
|
|
75
101
|
output: {
|
|
@@ -84,8 +110,29 @@ function configureWebpack({ name }) {
|
|
|
84
110
|
}
|
|
85
111
|
},
|
|
86
112
|
performance: { hints: false },
|
|
87
|
-
ignoreWarnings: [{ module: /sass-loader/ }]
|
|
113
|
+
ignoreWarnings: [{ module: /sass-loader/ }],
|
|
114
|
+
|
|
115
|
+
// 添加文件系统缓存(Webpack 5 核心优化)
|
|
116
|
+
cache: {
|
|
117
|
+
type: "filesystem",
|
|
118
|
+
cacheDirectory: resolve("node_modules/.cache/webpack"),
|
|
119
|
+
buildDependencies: {
|
|
120
|
+
config: [__filename]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
88
123
|
};
|
|
124
|
+
|
|
125
|
+
// 开发环境优化
|
|
126
|
+
if (ENV.IS_DEV) {
|
|
127
|
+
config.optimization = {
|
|
128
|
+
removeAvailableModules: false,
|
|
129
|
+
removeEmptyChunks: false,
|
|
130
|
+
splitChunks: false,
|
|
131
|
+
runtimeChunk: true
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return config;
|
|
89
136
|
}
|
|
90
137
|
|
|
91
138
|
/**
|
|
@@ -95,8 +142,79 @@ function chainWebpack(config) {
|
|
|
95
142
|
config.plugins.delete("preload");
|
|
96
143
|
config.plugins.delete("prefetch");
|
|
97
144
|
|
|
145
|
+
// 强制禁用 modern mode(staging 环境)
|
|
146
|
+
if (ENV.IS_STAGING) {
|
|
147
|
+
// 删除 @vue/cli-service 的 modern mode 相关插件
|
|
148
|
+
config.plugins.delete("modern-mode-plugin");
|
|
149
|
+
|
|
150
|
+
// 强制修改 HTML 插件配置
|
|
151
|
+
config.plugin("html").tap((args) => {
|
|
152
|
+
args[0] = args[0] || {};
|
|
153
|
+
|
|
154
|
+
// 彻底禁用 modern mode
|
|
155
|
+
args[0].modern = false;
|
|
156
|
+
args[0].modulePreload = false;
|
|
157
|
+
args[0].scriptLoading = "defer";
|
|
158
|
+
|
|
159
|
+
// 删除所有 modern/legacy 相关的钩子和回调
|
|
160
|
+
delete args[0].modernBuild;
|
|
161
|
+
delete args[0].legacyBuild;
|
|
162
|
+
delete args[0].modernManifest;
|
|
163
|
+
delete args[0].legacyManifest;
|
|
164
|
+
|
|
165
|
+
// 关键:重写 templateParameters 来阻止 modern mode 注入
|
|
166
|
+
const originalTemplateParameters = args[0].templateParameters || {};
|
|
167
|
+
args[0].templateParameters = (compilation, assets, assetTags, options) => {
|
|
168
|
+
const params =
|
|
169
|
+
typeof originalTemplateParameters === "function"
|
|
170
|
+
? originalTemplateParameters(compilation, assets, assetTags, options)
|
|
171
|
+
: originalTemplateParameters;
|
|
172
|
+
|
|
173
|
+
// 移除 modern/legacy 相关的参数
|
|
174
|
+
if (params) {
|
|
175
|
+
delete params.modernBuild;
|
|
176
|
+
delete params.legacyBuild;
|
|
177
|
+
delete params.modernManifest;
|
|
178
|
+
delete params.legacyManifest;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return params;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return args;
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// 添加自定义插件来处理 legacy 文件问题
|
|
188
|
+
config.plugin("remove-legacy-assets").use(RemoveLegacyAssetsPlugin);
|
|
189
|
+
|
|
190
|
+
// Babel 配置:只转译现代浏览器
|
|
191
|
+
config.module
|
|
192
|
+
.rule("js")
|
|
193
|
+
.use("babel-loader")
|
|
194
|
+
.tap((options) => ({
|
|
195
|
+
...options,
|
|
196
|
+
presets: [
|
|
197
|
+
[
|
|
198
|
+
"@babel/preset-env",
|
|
199
|
+
{
|
|
200
|
+
targets: {
|
|
201
|
+
esmodules: true,
|
|
202
|
+
chrome: "60",
|
|
203
|
+
firefox: "60",
|
|
204
|
+
safari: "11",
|
|
205
|
+
edge: "79"
|
|
206
|
+
},
|
|
207
|
+
modules: false
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
],
|
|
211
|
+
cacheDirectory: true,
|
|
212
|
+
cacheCompression: false
|
|
213
|
+
}));
|
|
214
|
+
}
|
|
215
|
+
|
|
98
216
|
// 注册 runtime 内联插件
|
|
99
|
-
config.plugin("inline-runtime").use(InlineRuntimePlugin)
|
|
217
|
+
config.plugin("inline-runtime").use(InlineRuntimePlugin);
|
|
100
218
|
|
|
101
219
|
// SVG图标
|
|
102
220
|
config.module.rule("svg").exclude.add(resolve("src/icons")).end();
|
|
@@ -110,7 +228,7 @@ function chainWebpack(config) {
|
|
|
110
228
|
.options({ symbolId: "icon-[name]" })
|
|
111
229
|
.end();
|
|
112
230
|
|
|
113
|
-
// Vue Loader
|
|
231
|
+
// Vue Loader 优化
|
|
114
232
|
config.module
|
|
115
233
|
.rule("vue")
|
|
116
234
|
.use("vue-loader")
|
|
@@ -125,6 +243,19 @@ function chainWebpack(config) {
|
|
|
125
243
|
}))
|
|
126
244
|
.end();
|
|
127
245
|
|
|
246
|
+
// 优化 Babel Loader 缓存(非 staging 环境)
|
|
247
|
+
if (!ENV.IS_STAGING) {
|
|
248
|
+
config.module
|
|
249
|
+
.rule("js")
|
|
250
|
+
.use("babel-loader")
|
|
251
|
+
.loader("babel-loader")
|
|
252
|
+
.tap((options) => ({
|
|
253
|
+
...options,
|
|
254
|
+
cacheDirectory: true,
|
|
255
|
+
cacheCompression: false
|
|
256
|
+
}));
|
|
257
|
+
}
|
|
258
|
+
|
|
128
259
|
// 图片资源
|
|
129
260
|
config.module
|
|
130
261
|
.rule("images")
|
|
@@ -178,17 +309,63 @@ function chainWebpack(config) {
|
|
|
178
309
|
maxInitialRequests: 30,
|
|
179
310
|
enforceSizeThreshold: 50000,
|
|
180
311
|
cacheGroups: {
|
|
312
|
+
// 最高优先级:ElementUI 框架(单独分包)
|
|
313
|
+
elementUI: {
|
|
314
|
+
name: "chunk-element-ui",
|
|
315
|
+
test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
|
|
316
|
+
priority: 40,
|
|
317
|
+
chunks: "all",
|
|
318
|
+
reuseExistingChunk: true
|
|
319
|
+
},
|
|
320
|
+
// 高优先级:ECharts 图表库(体积大,单独分包)
|
|
321
|
+
echarts: {
|
|
322
|
+
name: "chunk-echarts",
|
|
323
|
+
test: /[\\/]node_modules[\\/](echarts|zrender|v-charts)(.*)/,
|
|
324
|
+
priority: 35,
|
|
325
|
+
chunks: "async",
|
|
326
|
+
reuseExistingChunk: true
|
|
327
|
+
},
|
|
328
|
+
// Infly UI 组件库
|
|
329
|
+
inflyUI: {
|
|
330
|
+
name: "chunk-infly-ui",
|
|
331
|
+
test: /[\\/]packages[\\/]infly-ui[\\/]/,
|
|
332
|
+
priority: 31,
|
|
333
|
+
chunks: "all",
|
|
334
|
+
reuseExistingChunk: true
|
|
335
|
+
},
|
|
336
|
+
// Infly 工具库(monorepo 共享代码)
|
|
337
|
+
inflyLibs: {
|
|
338
|
+
name: "chunk-infly-libs",
|
|
339
|
+
test: /[\\/]packages[\\/]infly-libs[\\/]/,
|
|
340
|
+
priority: 30,
|
|
341
|
+
chunks: "all",
|
|
342
|
+
reuseExistingChunk: true
|
|
343
|
+
},
|
|
344
|
+
// Vue 全家桶(vue、vue-router、vuex)
|
|
345
|
+
vue: {
|
|
346
|
+
name: "chunk-vue",
|
|
347
|
+
test: /[\\/]node_modules[\\/](vue|vue-router|vuex)(.*)/,
|
|
348
|
+
priority: 25,
|
|
349
|
+
chunks: "all",
|
|
350
|
+
reuseExistingChunk: true
|
|
351
|
+
},
|
|
352
|
+
// 工具库(axios、lodash、moment 等)
|
|
353
|
+
utils: {
|
|
354
|
+
name: "chunk-utils",
|
|
355
|
+
test: /[\\/]node_modules[\\/](axios|nprogress|path-to-regexp|qrcanvas|html2canvas|element-china-area-data|vue-awesome-swiper|normalize\.css)(.*)/,
|
|
356
|
+
priority: 20,
|
|
357
|
+
chunks: "all",
|
|
358
|
+
reuseExistingChunk: true
|
|
359
|
+
},
|
|
360
|
+
// 其他 node_modules 库
|
|
181
361
|
libs: {
|
|
182
362
|
name: "chunk-libs",
|
|
183
363
|
test: /[\\/]node_modules[\\/]/,
|
|
184
364
|
priority: 10,
|
|
185
|
-
chunks: "initial"
|
|
186
|
-
|
|
187
|
-
elementUI: {
|
|
188
|
-
name: "chunk-elementUI",
|
|
189
|
-
priority: 20,
|
|
190
|
-
test: /[\\/]node_modules[\\/]_?element-ui(.*)/
|
|
365
|
+
chunks: "initial",
|
|
366
|
+
reuseExistingChunk: true
|
|
191
367
|
},
|
|
368
|
+
// 公共组件(被多次引用的组件)
|
|
192
369
|
commons: {
|
|
193
370
|
name: "chunk-commons",
|
|
194
371
|
test: resolve("src/components"),
|
|
@@ -220,8 +397,30 @@ function chainWebpack(config) {
|
|
|
220
397
|
}
|
|
221
398
|
}
|
|
222
399
|
|
|
400
|
+
/**
|
|
401
|
+
* devServer 优化配置
|
|
402
|
+
*/
|
|
403
|
+
function devServer() {
|
|
404
|
+
return {
|
|
405
|
+
hot: true,
|
|
406
|
+
client: {
|
|
407
|
+
logging: "warn", // 减少控制台日志
|
|
408
|
+
overlay: false
|
|
409
|
+
},
|
|
410
|
+
// 优化监听性能
|
|
411
|
+
watchFiles: {
|
|
412
|
+
options: {
|
|
413
|
+
ignored: /node_modules/,
|
|
414
|
+
usePolling: false
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
223
420
|
module.exports = {
|
|
224
421
|
cssModule,
|
|
225
422
|
configureWebpack,
|
|
226
|
-
chainWebpack
|
|
423
|
+
chainWebpack,
|
|
424
|
+
devServer,
|
|
425
|
+
projectResolve: resolve
|
|
227
426
|
};
|
package/index.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
const buildDist = require("./build/build-dist");
|
|
2
2
|
const projectPreview = require("./tools/project-preview");
|
|
3
|
+
const path = require("path");
|
|
3
4
|
|
|
4
5
|
function init() {
|
|
6
|
+
// 检查是否在 infly-libs 包自身目录中执行
|
|
7
|
+
const currentDir = process.cwd();
|
|
8
|
+
const packageDir = __dirname;
|
|
9
|
+
|
|
10
|
+
// 如果当前目录就是 infly-libs 包目录,跳过执行
|
|
11
|
+
if (currentDir === packageDir) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
5
15
|
projectPreview.scriptInit();
|
|
6
16
|
buildDist.scriptInit();
|
|
7
17
|
}
|