@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 CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  ## 软件架构
12
12
 
13
- infly-libs
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-libs
38
+ npm/pnpm install @infly/libs
39
39
  ```
package/bin/cli.js CHANGED
@@ -8,6 +8,7 @@ const commandMap = {
8
8
  afterBuild: buildInit,
9
9
  initZip: buildInit,
10
10
  preview: previewInit,
11
+ "--preview": previewInit,
11
12
  beforeBuild: beforeBuild,
12
13
  scriptOverride: () => {
13
14
  previewScriptInit();
@@ -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 = "infly:build:test";
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
- if (buildConfig[npmPackageConfigKey]) {
75
- buildConfig = buildConfig[npmPackageConfigKey];
76
- }
73
+
74
+ buildConfig = normalizeBuildConfig(buildConfig, npmPackageConfigKey, currentBranch, projectTitle);
77
75
 
78
76
  // 准备构建信息
79
- const { zipOptions, versionConfig } = buildConfig || {};
77
+ const { buildConfigs, versionConfig } = buildConfig || {};
80
78
  const {
81
79
  buildFoldName: zipBuildFoldName, // 构建后文件名称
82
80
  outputPath, // 输出路径
83
81
  gitAuto, // 是否自动提交git
84
- gitAutoPushRepos, // 自动提交文件到对应仓库
85
- gitAutoPushReposBranchMap = {}, // 自动提交文件到对应仓库分支配置
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
- } = zipOptions || {};
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
- const tempLink = typeof links === "object" ? links[dealBranch] : links || "";
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
- ...zipOptions
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?.zipOptions?.enabled === false) {
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 (!/^release/.test(currentBranch) && currentBranch !== "master") {
282
+ if (!buildConfig?.buildConfigs?.gitAutoPushReposBranchMap[currentBranch]) {
244
283
  if (![testScript].includes(scriptEvent)) {
245
- console.error(global.logColor.error, `❌ 当前分支非release、release/xx、master等可构建分支,请检查`);
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 === "release" && !process.env.npm_lifecycle_event.includes("stage")) {
263
- console.warn(global.logColor.warning, `⚠️ 当前分支为 release 分支,建议使用测试环境构建命令`);
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, zipOptions } = buildConfig || {};
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 = {}, zipOptions = {} } = tempInflyConfig || {};
576
+ const { versionConfig = {}, buildConfigs = {} } = tempInflyConfig || {};
545
577
  if (versionConfig.versionList) {
546
578
  tempInflyConfig.versionConfig.versionList = []; // 删除旧版本列表
547
579
  }
548
- if (zipOptions.buildFoldName) {
549
- tempInflyConfig.zipOptions.buildFoldName = "";
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.zipOptions.buildFoldName = targetProjectOutputDir;
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({ additionalData }) {
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 ? { ignoreOrder: true } : false
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({ name }) {
64
- return {
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
- "@": resolve("src"),
70
- "@postal-benefits-platform": resolve("../postal-benefits-platform/src"),
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
  }