@qse/edu-scripts 2.0.2 → 2.0.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # 更新日志
2
2
 
3
+ ## 2.0.3 (2926-03-10)
4
+
5
+ - feat: 增加 cache 配置项
6
+ - feat: 增加 override 迁移提示
7
+ - fix: 修复 dll 在 pnpm 环境下失效
8
+
3
9
  ## 2.0.2 (2926-03-10)
4
10
 
5
11
  - fix: 修复 react 兼容问题
package/dist/cli.mjs CHANGED
@@ -49,13 +49,16 @@ function resolveOwn(...filePath) {
49
49
  }
50
50
  return path.resolve(current, ...filePath);
51
51
  }
52
+ function resolveExistPaths(...paths) {
53
+ return paths.filter((p) => fs.existsSync(p));
54
+ }
52
55
  function getExistPath(...paths) {
53
- for (const path of paths) if (fs.existsSync(path)) return path;
54
- return paths[0];
56
+ return resolveExistPaths(...paths)[0] || paths[0];
55
57
  }
56
58
  const paths = {
57
59
  resolveApp,
58
60
  resolveOwn,
61
+ resolveExistPaths,
59
62
  eduAppEnv: resolveApp("src", "edu-app-env.d.ts"),
60
63
  dist: resolveApp("dist"),
61
64
  sshSftp: resolveApp(".sftprc.json"),
@@ -210,6 +213,23 @@ const qseCDN = (() => {
210
213
  isUseQsbSchemeRender: include("qsb-scheme-render.min.js")
211
214
  };
212
215
  })();
216
+ function getPnpmCompatibleDllManifest(manifestPath) {
217
+ const manifest = fs.readJsonSync(manifestPath);
218
+ const normalizedContent = { ...manifest.content };
219
+ for (const [key, value] of Object.entries(manifest.content)) {
220
+ if (!key.startsWith("./node_modules/")) continue;
221
+ const request = key.replace("./node_modules/", "");
222
+ try {
223
+ const resolvedPath = require$2.resolve(request);
224
+ const relativePath = `./${path$1.relative(process.cwd(), resolvedPath).replace(/\\/g, "/")}`;
225
+ if (!normalizedContent[relativePath]) normalizedContent[relativePath] = value;
226
+ } catch {}
227
+ }
228
+ return {
229
+ ...manifest,
230
+ content: normalizedContent
231
+ };
232
+ }
213
233
  function getWebpackConfig(args, override) {
214
234
  const isDev = process.env.NODE_ENV === "development";
215
235
  const isProd = process.env.NODE_ENV === "production";
@@ -259,7 +279,7 @@ function getWebpackConfig(args, override) {
259
279
  });
260
280
  return loaders;
261
281
  };
262
- return {
282
+ const config = {
263
283
  context: process.cwd(),
264
284
  mode: process.env.NODE_ENV,
265
285
  entry: "./src/index",
@@ -271,6 +291,7 @@ function getWebpackConfig(args, override) {
271
291
  uniqueName: appPkg$1.name,
272
292
  publicPath: ""
273
293
  },
294
+ name: appPkg$1.name,
274
295
  externals: Object.assign({}, qseCDN.isUseCommon && {
275
296
  react: "React",
276
297
  "react-dom": "ReactDOM",
@@ -466,7 +487,7 @@ function getWebpackConfig(args, override) {
466
487
  }
467
488
  ].filter(Boolean) }] },
468
489
  plugins: [
469
- qseCDN.isUseCommon && new rspack.DllReferencePlugin({ manifest: fs.readJsonSync(paths.resolveOwn("asset", "dll", "libcommon3-manifest.json")) }),
490
+ qseCDN.isUseCommon && new rspack.DllReferencePlugin({ manifest: getPnpmCompatibleDllManifest(paths.resolveOwn("asset", "dll", "libcommon3-manifest.json")) }),
470
491
  new rspack.NormalModuleReplacementPlugin(/@rspack\/dev-server\/client\/index\.js/, (resource) => {
471
492
  const myClientPath = paths.resolveOwn("asset", "rspack-dev-server-client.js");
472
493
  resource.request = resource.request.replace(/.*dev-server\/client\/index\.js/, myClientPath);
@@ -543,6 +564,17 @@ function getWebpackConfig(args, override) {
543
564
  maxAssetSize: 2 * 1024 * 1024
544
565
  }
545
566
  };
567
+ if (override.cache) {
568
+ config.cache = true;
569
+ config.experiments = {
570
+ ...config.experiments,
571
+ cache: {
572
+ type: "persistent",
573
+ buildDependencies: paths.resolveExistPaths(fileURLToPath(import.meta.url), paths.package, paths.tsconfig, paths.override)
574
+ }
575
+ };
576
+ }
577
+ return config;
546
578
  }
547
579
 
548
580
  //#endregion
@@ -722,6 +754,15 @@ const defaultOverride = {
722
754
  import: [],
723
755
  pure_funcs: ["console.log"]
724
756
  };
757
+ function migrateOverride(override) {
758
+ if ("transformNodeModules" in override) console.warn("transformNodeModules 配置已废弃,请删除这个配置项");
759
+ if ("minifyImage" in override) console.warn("minifyImage 配置已废弃,请删除这个配置项");
760
+ if (typeof override.minify !== "boolean") {
761
+ console.warn("minify 类型错误,请使用boolean类型,已自动设置为 true");
762
+ override.minify = true;
763
+ }
764
+ if ("babel" in override) throw new Error("babel 配置已废弃,请删除这个配置项。如果有 babel-plugin-import 相关的配置,请直接使用 import 选项");
765
+ }
725
766
  let override = null;
726
767
  function getOverride() {
727
768
  if (override) return override;
@@ -730,6 +771,7 @@ function getOverride() {
730
771
  const userOverride = resolveModule(require(paths.override));
731
772
  if (typeof userOverride !== "object") throw new Error("格式错误,请使用 npx edu g override 生成文件");
732
773
  Object.assign(override, userOverride);
774
+ migrateOverride(override);
733
775
  }
734
776
  return override;
735
777
  }
@@ -902,14 +944,15 @@ async function build(args) {
902
944
  }));
903
945
  process.exit(1);
904
946
  }
947
+ printFileSizesAfterBuild(stats, previousSizeMap, paths.dist, WARN_AFTER_BUNDLE_GZIP_SIZE, WARN_AFTER_CHUNK_GZIP_SIZE);
948
+ if (appConfig.single) console.log(`打包完成,可以使用 ${chalk.green("@qse/ssh-sftp")} 自动部署代码到 v1`);
949
+ else console.log(`打包完成,可以运行 ${chalk.green("npx edu-scripts deploy")} 部署代码到 v1`);
950
+ console.log();
905
951
  console.log(stats.toString({
906
952
  colors: true,
907
953
  preset: "errors-warnings",
908
954
  timings: true
909
955
  }));
910
- printFileSizesAfterBuild(stats, previousSizeMap, paths.dist, WARN_AFTER_BUNDLE_GZIP_SIZE, WARN_AFTER_CHUNK_GZIP_SIZE);
911
- if (appConfig.single) console.log(`打包完成,可以使用 ${chalk.green("@qse/ssh-sftp")} 自动部署代码到 v1`);
912
- else console.log(`打包完成,可以运行 ${chalk.green("npx edu-scripts deploy")} 部署代码到 v1`);
913
956
  console.log();
914
957
  });
915
958
  }
package/dist/index.d.mts CHANGED
@@ -71,6 +71,13 @@ type Configuration$2 = {
71
71
  * @default [{libraryName: 'lodash',libraryDirectory: '',camelToDashComponentName: false}]
72
72
  */
73
73
  import?: NonNullable<SwcLoaderOptions['rspackExperiments']>['import'];
74
+ /**
75
+ * 该选项可以开启 Rspack 构建过程中对快照及中间产物的缓存,可以使用它们来提升构建的速度。\
76
+ * 这会增加磁盘空间的使用,但能显著提升构建性能,特别是在大型项目中。建议在开发环境中开启,在生产环境中根据需要选择是否开启。\
77
+ * 项目会自动清理7天未使用的缓存文件,确保磁盘空间不会被过度占用。
78
+ * @default false
79
+ */
80
+ cache?: boolean;
74
81
  };
75
82
  declare function defineConfig(config: Configuration$2): Configuration$2;
76
83
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qse/edu-scripts",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "author": "Kinoko",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/build.ts CHANGED
@@ -53,8 +53,6 @@ export default async function build(args: BuildArgs) {
53
53
  process.exit(1)
54
54
  }
55
55
 
56
- console.log(stats.toString({ colors: true, preset: 'errors-warnings', timings: true }))
57
-
58
56
  printFileSizesAfterBuild(
59
57
  stats,
60
58
  previousSizeMap,
@@ -69,5 +67,7 @@ export default async function build(args: BuildArgs) {
69
67
  console.log(`打包完成,可以运行 ${chalk.green('npx edu-scripts deploy')} 部署代码到 v1`)
70
68
  }
71
69
  console.log()
70
+ console.log(stats.toString({ colors: true, preset: 'errors-warnings', timings: true }))
71
+ console.log()
72
72
  })
73
73
  }
@@ -20,18 +20,19 @@ function resolveOwn(...filePath: string[]) {
20
20
  return path.resolve(current, ...filePath)
21
21
  }
22
22
 
23
+ function resolveExistPaths(...paths: string[]) {
24
+ return paths.filter((p) => fs.existsSync(p))
25
+ }
26
+
23
27
  function getExistPath(...paths: string[]) {
24
- for (const path of paths) {
25
- if (fs.existsSync(path)) {
26
- return path
27
- }
28
- }
29
- return paths[0]
28
+ const existPaths = resolveExistPaths(...paths)
29
+ return existPaths[0] || paths[0]
30
30
  }
31
31
 
32
32
  const paths = {
33
33
  resolveApp,
34
34
  resolveOwn,
35
+ resolveExistPaths,
35
36
  eduAppEnv: resolveApp('src', 'edu-app-env.d.ts'),
36
37
  dist: resolveApp('dist'),
37
38
  sshSftp: resolveApp('.sftprc.json'),
@@ -41,7 +42,10 @@ const paths = {
41
42
  package: resolveApp('package.json'),
42
43
  tailwind: resolveApp('tailwind.config.js'),
43
44
  pages: resolveApp('src', 'pages'),
44
- override: getExistPath(resolveApp('edu-scripts.override.js'), resolveApp('edu-scripts.override.ts')),
45
+ override: getExistPath(
46
+ resolveApp('edu-scripts.override.js'),
47
+ resolveApp('edu-scripts.override.ts')
48
+ ),
45
49
  indexHTML: globbySync('./public/*.html', { absolute: true }),
46
50
  src: resolveApp('src'),
47
51
  public: resolveApp('public'),
@@ -12,6 +12,7 @@ import appConfig from '../utils/appConfig'
12
12
  import type { Configuration as CustomConfiguration } from '../utils/defineConfig'
13
13
  import paths from './paths'
14
14
  import PostcssSafeAreaPlugin from './plugins/postcss-safe-area'
15
+ import { fileURLToPath } from 'node:url'
15
16
 
16
17
  const require = createRequire(import.meta.url)
17
18
  const appPkg = fs.readJsonSync(paths.package) as { name: string; version: string }
@@ -75,6 +76,32 @@ interface CSSLoaderOptions {
75
76
  }
76
77
  }
77
78
 
79
+ interface DllManifest {
80
+ name: string
81
+ content: Record<string, { id: number | string }>
82
+ }
83
+
84
+ function getPnpmCompatibleDllManifest(manifestPath: string): DllManifest {
85
+ const manifest = fs.readJsonSync(manifestPath) as DllManifest
86
+ const normalizedContent = { ...manifest.content }
87
+
88
+ for (const [key, value] of Object.entries(manifest.content)) {
89
+ if (!key.startsWith('./node_modules/')) continue
90
+
91
+ const request = key.replace('./node_modules/', '')
92
+ try {
93
+ const resolvedPath = require.resolve(request)
94
+ const relativePath = `./${path.relative(process.cwd(), resolvedPath).replace(/\\/g, '/')}`
95
+
96
+ if (!normalizedContent[relativePath]) {
97
+ normalizedContent[relativePath] = value
98
+ }
99
+ } catch {}
100
+ }
101
+
102
+ return { ...manifest, content: normalizedContent }
103
+ }
104
+
78
105
  export default function getWebpackConfig(args: any, override: CustomConfiguration): Configuration {
79
106
  const isDev = process.env.NODE_ENV === 'development'
80
107
  const isProd = process.env.NODE_ENV === 'production'
@@ -143,7 +170,7 @@ export default function getWebpackConfig(args: any, override: CustomConfiguratio
143
170
 
144
171
  const config: Configuration = {
145
172
  context: process.cwd(),
146
- mode: process.env.NODE_ENV as 'development' | 'production' | 'none',
173
+ mode: process.env.NODE_ENV as 'development' | 'production',
147
174
  entry: './src/index',
148
175
  target: 'browserslist',
149
176
  output: {
@@ -155,6 +182,7 @@ export default function getWebpackConfig(args: any, override: CustomConfiguratio
155
182
  uniqueName: appPkg.name,
156
183
  publicPath: '',
157
184
  },
185
+ name: appPkg.name,
158
186
  externals: Object.assign(
159
187
  {},
160
188
  qseCDN.isUseCommon && {
@@ -407,7 +435,9 @@ export default function getWebpackConfig(args: any, override: CustomConfiguratio
407
435
  plugins: [
408
436
  qseCDN.isUseCommon &&
409
437
  new rspack.DllReferencePlugin({
410
- manifest: fs.readJsonSync(paths.resolveOwn('asset', 'dll', 'libcommon3-manifest.json')),
438
+ manifest: getPnpmCompatibleDllManifest(
439
+ paths.resolveOwn('asset', 'dll', 'libcommon3-manifest.json')
440
+ ),
411
441
  }),
412
442
  new rspack.NormalModuleReplacementPlugin(
413
443
  /@rspack\/dev-server\/client\/index\.js/,
@@ -505,5 +535,21 @@ export default function getWebpackConfig(args: any, override: CustomConfiguratio
505
535
  },
506
536
  }
507
537
 
538
+ if (override.cache) {
539
+ config.cache = true
540
+ config.experiments = {
541
+ ...config.experiments,
542
+ cache: {
543
+ type: 'persistent',
544
+ buildDependencies: paths.resolveExistPaths(
545
+ fileURLToPath(import.meta.url),
546
+ paths.package,
547
+ paths.tsconfig,
548
+ paths.override
549
+ ),
550
+ },
551
+ }
552
+ }
553
+
508
554
  return config
509
555
  }
@@ -75,6 +75,14 @@ export type Configuration = {
75
75
  * @default [{libraryName: 'lodash',libraryDirectory: '',camelToDashComponentName: false}]
76
76
  */
77
77
  import?: NonNullable<SwcLoaderOptions['rspackExperiments']>['import']
78
+
79
+ /**
80
+ * 该选项可以开启 Rspack 构建过程中对快照及中间产物的缓存,可以使用它们来提升构建的速度。\
81
+ * 这会增加磁盘空间的使用,但能显著提升构建性能,特别是在大型项目中。建议在开发环境中开启,在生产环境中根据需要选择是否开启。\
82
+ * 项目会自动清理7天未使用的缓存文件,确保磁盘空间不会被过度占用。
83
+ * @default false
84
+ */
85
+ cache?: boolean
78
86
  }
79
87
  export function defineConfig(config: Configuration) {
80
88
  return config
@@ -14,6 +14,28 @@ const defaultOverride: Configuration = {
14
14
  pure_funcs: ['console.log'],
15
15
  }
16
16
 
17
+ function migrateOverride(override: Configuration) {
18
+ // 迁移提示 v1 -> v2,后续版本会删除这些废弃的配置项
19
+ if ('transformNodeModules' in override) {
20
+ console.warn('transformNodeModules 配置已废弃,请删除这个配置项')
21
+ }
22
+
23
+ if ('minifyImage' in override) {
24
+ console.warn('minifyImage 配置已废弃,请删除这个配置项')
25
+ }
26
+
27
+ if (typeof override.minify !== 'boolean') {
28
+ console.warn('minify 类型错误,请使用boolean类型,已自动设置为 true')
29
+ override.minify = true
30
+ }
31
+
32
+ if ('babel' in override) {
33
+ throw new Error(
34
+ 'babel 配置已废弃,请删除这个配置项。如果有 babel-plugin-import 相关的配置,请直接使用 import 选项'
35
+ )
36
+ }
37
+ }
38
+
17
39
  let override: Configuration | null = null
18
40
 
19
41
  export default function getOverride(): Configuration {
@@ -26,6 +48,8 @@ export default function getOverride(): Configuration {
26
48
  if (typeof userOverride !== 'object')
27
49
  throw new Error('格式错误,请使用 npx edu g override 生成文件')
28
50
  Object.assign(override, userOverride)
51
+
52
+ migrateOverride(override)
29
53
  }
30
54
 
31
55
  return override