@qse/edu-scripts 0.0.0-beta.4 → 0.0.0-beta.6

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.
@@ -1,6 +1,6 @@
1
- const { defineConfig } = require('@qse/edu-scripts')
1
+ import { defineConfig } from '@qse/edu-scripts'
2
2
 
3
- module.exports = defineConfig({
3
+ export default defineConfig({
4
4
  startup: ({ logger, chalk }) => {
5
5
  logger.info('本地免登录开发地址:', chalk.cyan(`http://127.0.0.1:${process.env.PORT}/index.html`))
6
6
  },
@@ -1,5 +1,5 @@
1
1
  /** @type {import('tailwindcss').Config} */
2
- module.exports = {
2
+ export default {
3
3
  content: ['./src/**/*.{js,jsx,ts,tsx}'],
4
4
  theme: {
5
5
  extend: {},
package/dist/cli.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module";
3
+ import "@swc-node/register/esm-register";
3
4
  import fs from "fs-extra";
4
5
  import path from "path";
5
6
  import { globby, globbySync } from "globby";
@@ -58,9 +59,8 @@ const paths = {
58
59
  jsconfig: resolveApp("jsconfig.json"),
59
60
  package: resolveApp("package.json"),
60
61
  tailwind: resolveApp("tailwind.config.js"),
61
- indexJS: resolveApp("src", "index.js"),
62
62
  pages: resolveApp("src", "pages"),
63
- override: resolveApp("edu-scripts.override.js"),
63
+ override: getExistPath(resolveApp("edu-scripts.override.js"), resolveApp("edu-scripts.override.ts")),
64
64
  indexHTML: globbySync("./public/*.html", { absolute: true }),
65
65
  src: resolveApp("src"),
66
66
  public: resolveApp("public"),
@@ -166,7 +166,13 @@ const PostcssSafeAreaPlugin = () => {
166
166
  };
167
167
 
168
168
  //#endregion
169
- //#region src/config/webpackConfig.js
169
+ //#region src/utils/resolveModule.ts
170
+ function resolveModule(mod) {
171
+ return mod.default ? mod.default : mod;
172
+ }
173
+
174
+ //#endregion
175
+ //#region src/config/webpackConfig.ts
170
176
  const require$2 = createRequire(import.meta.url);
171
177
  const appPkg$1 = fs.readJsonSync(paths.package);
172
178
  const jsMainPath = appConfig.grayscale ? `${appPkg$1.name}/beta/${appPkg$1.name}` : `${appPkg$1.name}/${appPkg$1.name}`;
@@ -191,10 +197,6 @@ const qseCDN = (() => {
191
197
  isUseQsbSchemeRender: include("qsb-scheme-render.min.js")
192
198
  };
193
199
  })();
194
- /**
195
- * @param {*} args
196
- * @param {import('../utils/defineConfig.js').Configuration} override
197
- */
198
200
  function getWebpackConfig(args, override) {
199
201
  const isDev = process.env.NODE_ENV === "development";
200
202
  const isProd = process.env.NODE_ENV === "production";
@@ -225,7 +227,7 @@ function getWebpackConfig(args, override) {
225
227
  isProd && PostcssSafeAreaPlugin(),
226
228
  isProd && [require$2.resolve("postcss-momentum-scrolling"), ["scroll", "auto"]],
227
229
  require$2.resolve("postcss-normalize"),
228
- ...override.extraPostCSSPlugins
230
+ ...override.extraPostCSSPlugins || []
229
231
  ].filter(Boolean)
230
232
  },
231
233
  sourceMap: isDev
@@ -237,7 +239,7 @@ function getWebpackConfig(args, override) {
237
239
  options: {
238
240
  lessOptions: {
239
241
  javascriptEnabled: true,
240
- modifyVars: fs.existsSync(paths.theme) ? require$2(paths.theme) : void 0
242
+ modifyVars: fs.existsSync(paths.theme) ? resolveModule(require$2(paths.theme)) : void 0
241
243
  },
242
244
  sourceMap: true
243
245
  }
@@ -304,7 +306,11 @@ function getWebpackConfig(args, override) {
304
306
  ".tsx",
305
307
  ".json",
306
308
  ".wasm"
307
- ]
309
+ ],
310
+ tsConfig: {
311
+ configFile: paths.tsconfig,
312
+ references: "auto"
313
+ }
308
314
  },
309
315
  stats: false,
310
316
  devtool: isDev ? "cheap-module-source-map" : false,
@@ -322,8 +328,9 @@ function getWebpackConfig(args, override) {
322
328
  env: { targets: process.env.BROWSERSLIST },
323
329
  rspackExperiments: { import: [{
324
330
  libraryName: "lodash",
325
- customName: "lodash/{{member}}"
326
- }, ...override.import] },
331
+ libraryDirectory: "",
332
+ camelToDashComponentName: false
333
+ }, ...override.import || []] },
327
334
  isModule: "unknown",
328
335
  jsc: {
329
336
  parser: {
@@ -526,7 +533,6 @@ function getWebpackConfig(args, override) {
526
533
  //#endregion
527
534
  //#region src/config/plugins/mock-server/index.ts
528
535
  const require$1 = createRequire(import.meta.url);
529
- const { register } = require$1("@swc-node/register/register");
530
536
  let mockCache = {};
531
537
  let isSetup = false;
532
538
  const setupMock = debounce(function setupMock() {
@@ -537,8 +543,7 @@ const setupMock = debounce(function setupMock() {
537
543
  for (const file of files) {
538
544
  delete require$1.cache[require$1.resolve(file)];
539
545
  try {
540
- let mock = require$1(file);
541
- mock = mock.default || mock;
546
+ const mock = resolveModule(require$1(file));
542
547
  for (const key in mock) {
543
548
  const [method, path] = key.split(" ");
544
549
  mockCache[key] = {
@@ -622,7 +627,6 @@ const mockMiddlewave = function mockMiddlewave(req, res, next) {
622
627
  };
623
628
  function setupMockServer(middelwaves, _devServer) {
624
629
  if (!fs.existsSync(paths.mock)) return;
625
- register();
626
630
  middelwaves.unshift({
627
631
  name: "edu-scripts-mock-middelwave",
628
632
  middleware: mockMiddlewave
@@ -633,7 +637,7 @@ function setupMockServer(middelwaves, _devServer) {
633
637
  }
634
638
 
635
639
  //#endregion
636
- //#region src/config/webpackDevServerConfig.js
640
+ //#region src/config/webpackDevServerConfig.ts
637
641
  function createProxy(context, target, origin) {
638
642
  const url = new URL(origin || target);
639
643
  return {
@@ -647,13 +651,8 @@ function createProxy(context, target, origin) {
647
651
  }
648
652
  };
649
653
  }
650
- /**
651
- * @param {*} args
652
- * @param {import('../utils/defineConfig.js').Configuration} override
653
- */
654
654
  function getWebpackDevServerConfig(args, override) {
655
655
  const host = process.env.HOST || "0.0.0.0";
656
- /** @type {import('@rspack/dev-server').Configuration} */
657
656
  const devServer = {
658
657
  allowedHosts: "all",
659
658
  historyApiFallback: true,
@@ -680,10 +679,10 @@ function getWebpackDevServerConfig(args, override) {
680
679
  compress: true
681
680
  };
682
681
  if (override.proxy) {
683
- if (Array.isArray(override.proxy)) devServer.proxy = [...override.proxy, ...devServer.proxy];
682
+ if (Array.isArray(override.proxy)) devServer.proxy = [...override.proxy, ...devServer.proxy || []];
684
683
  else if (typeof override.proxy === "object") devServer.proxy = [...Object.entries(override.proxy).map(([context, target]) => {
685
684
  return createProxy(context, target);
686
- }), ...devServer.proxy];
685
+ }), ...devServer.proxy || []];
687
686
  else throw new Error("proxy 必须是数组或对象");
688
687
  const proxyMap = /* @__PURE__ */ new Map();
689
688
  devServer.proxy = devServer.proxy.filter((item) => {
@@ -713,7 +712,7 @@ function getOverride() {
713
712
  if (override) return override;
714
713
  override = Object.assign({}, defaultOverride);
715
714
  if (fs.existsSync(paths.override)) {
716
- const userOverride = require(paths.override);
715
+ const userOverride = resolveModule(require(paths.override));
717
716
  if (typeof userOverride !== "object") throw new Error("格式错误,请使用 npx edu g override 生成文件");
718
717
  Object.assign(override, userOverride);
719
718
  }
@@ -770,7 +769,7 @@ async function start(args) {
770
769
  }
771
770
 
772
771
  //#endregion
773
- //#region src/utils/FileSizeReporter.js
772
+ //#region src/utils/FileSizeReporter.ts
774
773
  /**
775
774
  * Copyright (c) 2015-present, Facebook, Inc.
776
775
  *
@@ -781,15 +780,15 @@ function canReadAsset(asset) {
781
780
  return /\.(js|css)$/.test(asset) && !/service-worker\.js/.test(asset) && !/precache-manifest\.[0-9a-f]+\.js/.test(asset);
782
781
  }
783
782
  function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, maxBundleGzipSize, maxChunkGzipSize) {
784
- var root = previousSizeMap.root;
785
- var sizes = previousSizeMap.sizes;
786
- var assets = (webpackStats.stats || [webpackStats]).map((stats) => stats.toJson({
783
+ const root = previousSizeMap.root;
784
+ const sizes = previousSizeMap.sizes;
785
+ const assets = (webpackStats.stats || [webpackStats]).map((stats) => stats.toJson({
787
786
  all: false,
788
787
  assets: true
789
788
  }).assets.filter((asset) => canReadAsset(asset.name)).map((asset) => {
790
- var size = gzipSizeSync(fs.readFileSync(path.join(root, asset.name)));
791
- var previousSize = sizes[removeFileNameHash(root, asset.name)];
792
- var difference = getDifferenceLabel(size, previousSize);
789
+ const size = gzipSizeSync(fs.readFileSync(path.join(root, asset.name)));
790
+ const previousSize = sizes[removeFileNameHash(root, asset.name)];
791
+ const difference = getDifferenceLabel(size, previousSize);
793
792
  return {
794
793
  folder: path.join(path.basename(buildFolder), path.dirname(asset.name)),
795
794
  name: path.basename(asset.name),
@@ -800,20 +799,20 @@ function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, ma
800
799
  if (assets.length === 0) return;
801
800
  console.log("\ngzip 后文件大小:\n");
802
801
  assets.sort((a, b) => b.size - a.size);
803
- var mainAssetIdx = assets.findIndex((asset) => /_\d+\.\d+\.\d+/.test(asset.name));
802
+ const mainAssetIdx = assets.findIndex((asset) => /_\d+\.\d+\.\d+/.test(asset.name));
804
803
  assets.unshift(assets.splice(mainAssetIdx, 1)[0]);
805
- var longestSizeLabelLength = Math.max.apply(null, assets.map((a) => stripAnsi(a.sizeLabel).length));
806
- var suggestBundleSplitting = false;
804
+ const longestSizeLabelLength = Math.max.apply(null, assets.map((a) => stripAnsi(a.sizeLabel).length));
805
+ let suggestBundleSplitting = false;
807
806
  assets.forEach((asset) => {
808
- var sizeLabel = asset.sizeLabel;
809
- var sizeLength = stripAnsi(sizeLabel).length;
807
+ let sizeLabel = asset.sizeLabel;
808
+ const sizeLength = stripAnsi(sizeLabel).length;
810
809
  if (sizeLength < longestSizeLabelLength) {
811
- var rightPadding = " ".repeat(longestSizeLabelLength - sizeLength);
810
+ const rightPadding = " ".repeat(longestSizeLabelLength - sizeLength);
812
811
  sizeLabel += rightPadding;
813
812
  }
814
- var isMainBundle = /_\d+\.\d+\.\d+\./.test(asset.name);
815
- var maxRecommendedSize = isMainBundle ? maxBundleGzipSize : maxChunkGzipSize;
816
- var isLarge = maxRecommendedSize && asset.size > maxRecommendedSize;
813
+ const isMainBundle = /_\d+\.\d+\.\d+\./.test(asset.name);
814
+ const maxRecommendedSize = isMainBundle ? maxBundleGzipSize : maxChunkGzipSize;
815
+ const isLarge = maxRecommendedSize && asset.size > maxRecommendedSize;
817
816
  if (isLarge && path.extname(asset.name) === ".js") suggestBundleSplitting = true;
818
817
  console.log(" " + (isLarge ? chalk.yellow(sizeLabel) : sizeLabel) + " " + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name));
819
818
  if (isMainBundle) console.log("");
@@ -830,9 +829,9 @@ function removeFileNameHash(buildFolder, fileName) {
830
829
  return fileName.replace(buildFolder, "").replace(/\\/g, "/").replace(/\/\d+\.\d+\.\d+\//, "/").replace(/\/?(.*)(\.[0-9a-f]+)(\.chunk)?(\.js|\.css)/, (match, p1, p2, p3, p4) => p1 + p4);
831
830
  }
832
831
  function getDifferenceLabel(currentSize, previousSize) {
833
- var FIFTY_KILOBYTES = 1024 * 50;
834
- var difference = currentSize - previousSize;
835
- var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
832
+ const FIFTY_KILOBYTES = 1024 * 50;
833
+ const difference = currentSize - previousSize;
834
+ const fileSize = !Number.isNaN(difference) ? filesize(difference) : 0;
836
835
  if (difference >= FIFTY_KILOBYTES) return chalk.red("+" + fileSize);
837
836
  else if (difference < FIFTY_KILOBYTES && difference > 0) return chalk.yellow("+" + fileSize);
838
837
  else if (difference < 0) return chalk.green(fileSize);
@@ -841,10 +840,10 @@ function getDifferenceLabel(currentSize, previousSize) {
841
840
  function measureFileSizesBeforeBuild(buildFolder) {
842
841
  return new Promise((resolve) => {
843
842
  recursive(buildFolder, (err, fileNames) => {
844
- var sizes;
843
+ let sizes;
845
844
  if (!err && fileNames) sizes = fileNames.filter(canReadAsset).reduce((memo, fileName) => {
846
- var contents = fs.readFileSync(fileName);
847
- var key = removeFileNameHash(buildFolder, fileName);
845
+ const contents = fs.readFileSync(fileName);
846
+ const key = removeFileNameHash(buildFolder, fileName);
848
847
  memo[key] = gzipSizeSync(contents);
849
848
  return memo;
850
849
  }, {});
@@ -899,7 +898,7 @@ async function build(args) {
899
898
  }
900
899
 
901
900
  //#endregion
902
- //#region src/utils/changeDeployVersion.js
901
+ //#region src/utils/changeDeployVersion.ts
903
902
  const TARGET_IDENTIFIER_NAME = "project_apiArr";
904
903
  const MODULE_IDENTIFIER_NAME = "module";
905
904
  function changeDeployVersion(code, pkg) {
@@ -911,9 +910,6 @@ function changeDeployVersion(code, pkg) {
911
910
  throw new Error(`代码解析错误: ${error.message}`, { cause: error });
912
911
  }
913
912
  const keyName = grayscale ? "grayscale" : "main";
914
- /**
915
- * @return {babel.NodePath<t.VariableDeclarator> | undefined}
916
- */
917
913
  function findTargetDeclarator(ast) {
918
914
  let res;
919
915
  traverse(ast, { VariableDeclarator(path) {
@@ -921,44 +917,33 @@ function changeDeployVersion(code, pkg) {
921
917
  } });
922
918
  return res;
923
919
  }
924
- /**
925
- * @param {babel.NodePath<t.VariableDeclarator>} path
926
- * @return {babel.NodePath<t.ObjectExpression> | undefined}
927
- */
928
920
  function findModuleObject(path) {
929
921
  let res;
930
922
  path.traverse({ ObjectExpression(path) {
931
- if (path.node.properties.some((node) => types.isIdentifier(node.key, { name: MODULE_IDENTIFIER_NAME }) && types.isLiteral(node.value, { value: name }))) res = path;
923
+ if (path.node.properties.some((node) => types.isObjectProperty(node) && types.isIdentifier(node.key, { name: MODULE_IDENTIFIER_NAME }) && types.isLiteral(node.value, { value: name }))) res = path;
932
924
  } });
933
925
  return res;
934
926
  }
935
- /**
936
- * @param {babel.NodePath<t.ObjectExpression>} path
937
- */
938
927
  function modifyModuleVersion(path) {
939
928
  let hasModify = false;
940
929
  path.traverse({ Property(path) {
941
- if (path.node.key.name === keyName) {
942
- path.node.value.value = version;
930
+ if (types.isObjectProperty(path.node) && types.isIdentifier(path.node.key, { name: keyName })) {
931
+ if (types.isStringLiteral(path.node.value)) path.node.value.value = version;
943
932
  hasModify = true;
944
933
  }
945
934
  } });
946
935
  if (!hasModify) path.node.properties.push(types.objectProperty(types.identifier(keyName), types.stringLiteral(version)));
947
936
  }
948
- /**
949
- * @param {babel.NodePath<t.ObjectExpression>} path
950
- */
951
937
  function deleteModuleComments(path) {
952
938
  path.traverse({ ObjectExpression(path) {
953
939
  delete path.node.leadingComments;
954
940
  } });
955
941
  }
956
- /**
957
- * @param {babel.NodePath<t.VariableDeclarator>} path
958
- */
959
942
  function addModuleToTarget(path) {
960
- const elements = path.node.init.elements;
961
- elements.splice(elements.length - 2, 0, types.objectExpression([types.objectProperty(types.identifier(MODULE_IDENTIFIER_NAME), types.stringLiteral(name)), types.objectProperty(types.identifier(keyName), types.stringLiteral(version))]));
943
+ if (types.isArrayExpression(path.node.init)) {
944
+ const elements = path.node.init.elements;
945
+ elements.splice(elements.length - 2, 0, types.objectExpression([types.objectProperty(types.identifier(MODULE_IDENTIFIER_NAME), types.stringLiteral(name)), types.objectProperty(types.identifier(keyName), types.stringLiteral(version))]));
946
+ }
962
947
  }
963
948
  const targetPath = findTargetDeclarator(ast);
964
949
  if (!targetPath) throw new Error(`ver.js 不合规范,未找到参数 ${TARGET_IDENTIFIER_NAME}`);
@@ -966,10 +951,12 @@ function changeDeployVersion(code, pkg) {
966
951
  if (moduleObjPath) modifyModuleVersion(moduleObjPath);
967
952
  else addModuleToTarget(targetPath);
968
953
  deleteModuleComments(targetPath);
969
- return transformFromAstSync(ast, void 0, {
954
+ const result = transformFromAstSync(ast, void 0, {
970
955
  filename: "ver.js",
971
956
  minified: true
972
- }).code;
957
+ });
958
+ if (!result || !result.code) throw new Error("代码转换失败");
959
+ return result.code;
973
960
  }
974
961
 
975
962
  //#endregion
@@ -1045,7 +1032,7 @@ async function normalDeploy(args) {
1045
1032
  try {
1046
1033
  await sftp.fastGet(remoteLogFile, tmpLogFile);
1047
1034
  content = await fs.readFile(tmpLogFile, "utf-8");
1048
- } catch (_error) {}
1035
+ } catch {}
1049
1036
  content = updateLogContent(content, info);
1050
1037
  await fs.writeFile(tmpLogFile, content);
1051
1038
  await sftp.fastPut(tmpLogFile, remoteLogFile);
@@ -1313,7 +1300,7 @@ function copyDistToRepo(info) {
1313
1300
  exec(`svn co ${info.distBranchDirURL} ${tmpdir}`);
1314
1301
  try {
1315
1302
  exec(`svn rm * --force -q`, { cwd: tmpdir });
1316
- } catch (_e) {}
1303
+ } catch {}
1317
1304
  fs.copySync(paths.dist, tmpdir);
1318
1305
  exec(`svn add * --force --auto-props --parents --depth infinity -q`, { cwd: tmpdir });
1319
1306
  exec(`svn ci -m "${`[edu-scripts] commit ${info.branch} dist #${info.revision} @${info.author}`}"`, { cwd: tmpdir });
package/dist/index.d.mts CHANGED
@@ -1,22 +1,18 @@
1
1
  import { Chalk } from "chalk";
2
- import { Compiler, Configuration } from "@rspack/core";
2
+ import { Compiler, Configuration, SwcLoaderOptions } from "@rspack/core";
3
3
  import { Configuration as Configuration$1 } from "@rspack/dev-server";
4
4
  import { RequestHandler } from "express";
5
5
 
6
6
  //#region src/utils/defineConfig.d.ts
7
7
  type ProxyConfigArray = NonNullable<Configuration$1['proxy']>;
8
- type BabelImportPlugin = {
9
- libraryName: string;
10
- libraryDirectory?: string;
11
- customName?: string;
12
- style?: boolean | 'css' | string;
13
- };
14
8
  type Configuration$2 = {
15
9
  webpack?: (config: Configuration) => Configuration | undefined;
16
10
  devServer?: (config: Configuration$1) => Configuration$1 | undefined;
17
11
  /**
18
12
  * webpack alias 配置,会与内置 alias 合并
19
13
  *
14
+ * 会自动读取 tsconfig 里 baseUrl + paths 的配置
15
+ *
20
16
  * @default
21
17
  * { '@': './src' }
22
18
  */
@@ -71,12 +67,10 @@ type Configuration$2 = {
71
67
  /**
72
68
  * 与 babel-plugin-import 类似,但是内部是 rspack 重构,libraryDirectory 默认值是 lib
73
69
  *
74
- * 如果 libraryDirectory 传 ’‘ 则必须使用 customName 来写
75
- *
76
70
  * @see https://rspack.rs/zh/guide/features/builtin-swc-loader#rspackexperimentsimport
77
- * @default [{libraryName: 'lodash', customName: 'lodash/{{member}}'}]
71
+ * @default [{libraryName: 'lodash',libraryDirectory: '',camelToDashComponentName: false}]
78
72
  */
79
- import?: BabelImportPlugin[];
73
+ import?: NonNullable<SwcLoaderOptions['rspackExperiments']>['import'];
80
74
  };
81
75
  declare function defineConfig(config: Configuration$2): Configuration$2;
82
76
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qse/edu-scripts",
3
- "version": "0.0.0-beta.4",
3
+ "version": "0.0.0-beta.6",
4
4
  "author": "Kinoko",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,7 +15,7 @@
15
15
  "docs:deploy": "ssh-sftp",
16
16
  "build": "tsdown",
17
17
  "deploy": "node scripts/deploy.js",
18
- "release": "npm run test && npm run build && npm publish && rimraf es",
18
+ "release": "npm run test && npm run build && npm publish && rimraf dist",
19
19
  "prettier": "prettier -c -w \"src/**/*.{js,jsx,tsx,ts,less,md,json}\"",
20
20
  "lint": "eslint --fix src",
21
21
  "postversion": "npm run release",
package/src/cli.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import '@swc-node/register/esm-register'
2
3
  import './utils/beforeStart'
3
4
 
4
5
  import fs from 'fs-extra'
@@ -61,10 +61,7 @@ function copyDistToRepo(info: WorkingCopyInfo) {
61
61
 
62
62
  try {
63
63
  exec(`svn rm * --force -q`, { cwd: tmpdir })
64
- } catch (_e:any) {
65
- // 如果目录为空,svn rm 会报错,忽略即可
66
- }
67
-
64
+ } catch {}
68
65
  fs.copySync(paths.dist, tmpdir)
69
66
 
70
67
  exec(`svn add * --force --auto-props --parents --depth infinity -q`, { cwd: tmpdir })
@@ -40,9 +40,8 @@ const paths = {
40
40
  jsconfig: resolveApp('jsconfig.json'),
41
41
  package: resolveApp('package.json'),
42
42
  tailwind: resolveApp('tailwind.config.js'),
43
- indexJS: resolveApp('src', 'index.js'),
44
43
  pages: resolveApp('src', 'pages'),
45
- override: resolveApp('edu-scripts.override.js'),
44
+ override: getExistPath(resolveApp('edu-scripts.override.js'), resolveApp('edu-scripts.override.ts')),
46
45
  indexHTML: globbySync('./public/*.html', { absolute: true }),
47
46
  src: resolveApp('src'),
48
47
  public: resolveApp('public'),
@@ -9,8 +9,8 @@ import cookieParser from 'cookie-parser'
9
9
  import multer from 'multer'
10
10
  import { pathToRegexp, type Key } from 'path-to-regexp'
11
11
  import { createRequire } from 'node:module'
12
+ import { resolveModule } from '@/utils/resolveModule'
12
13
  const require = createRequire(import.meta.url)
13
- const { register } = require('@swc-node/register/register')
14
14
 
15
15
  let mockCache: Record<string, { handler: any; method: string; path: string }> = {}
16
16
  let isSetup = false
@@ -31,8 +31,7 @@ const setupMock = debounce(function setupMock() {
31
31
  for (const file of files) {
32
32
  delete require.cache[require.resolve(file)]
33
33
  try {
34
- let mock = require(file)
35
- mock = mock.default || mock
34
+ const mock = resolveModule(require(file))
36
35
 
37
36
  for (const key in mock) {
38
37
  const [method, path] = key.split(' ')
@@ -129,8 +128,6 @@ type Middlewares = Parameters<
129
128
  function setupMockServer(middelwaves: Middlewares, _devServer: any) {
130
129
  if (!fs.existsSync(paths.mock)) return
131
130
 
132
- register()
133
-
134
131
  middelwaves.unshift({
135
132
  name: 'edu-scripts-mock-middelwave',
136
133
  middleware: mockMiddlewave as any,
@@ -1,15 +1,19 @@
1
1
  import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin'
2
2
  import { rspack } from '@rspack/core'
3
+ import type { Configuration, Compiler, RuleSetRule, SwcLoaderOptions } from '@rspack/core'
3
4
  import ReactRefreshPlugin from '@rspack/plugin-react-refresh'
4
5
  import chalk from 'chalk'
5
6
  import fs from 'fs-extra'
6
7
  import HtmlWebpackPlugin from 'html-webpack-plugin'
7
8
  import { createRequire } from 'node:module'
8
- import appConfig from '../utils/appConfig.js'
9
- import paths from './paths.js'
10
- import PostcssSafeAreaPlugin from './plugins/postcss-safe-area.js'
9
+ import appConfig from '../utils/appConfig'
10
+ import type { Configuration as CustomConfiguration } from '../utils/defineConfig'
11
+ import paths from './paths'
12
+ import PostcssSafeAreaPlugin from './plugins/postcss-safe-area'
13
+ import { resolveModule } from '@/utils/resolveModule'
14
+
11
15
  const require = createRequire(import.meta.url)
12
- const appPkg = fs.readJsonSync(paths.package)
16
+ const appPkg = fs.readJsonSync(paths.package) as { name: string; version: string }
13
17
 
14
18
  const jsMainPath = appConfig.grayscale
15
19
  ? `${appPkg.name}/beta/${appPkg.name}`
@@ -25,10 +29,19 @@ const lessModuleRegex = /\.module\.less$/
25
29
 
26
30
  const imageInlineSizeLimit = 10 * 1024
27
31
 
28
- const qseCDN = (() => {
32
+ interface QseCDN {
33
+ isUseCommon: boolean
34
+ isUseAxios: boolean
35
+ isUseMoment: boolean
36
+ isUseAntd: boolean
37
+ isUseQsbAntd: boolean
38
+ isUseQsbSchemeRender: boolean
39
+ }
40
+
41
+ const qseCDN: QseCDN = (() => {
29
42
  const contents = paths.indexHTML.map((url) => fs.readFileSync(url, 'utf-8'))
30
43
 
31
- function include(pattern) {
44
+ function include(pattern: string | RegExp): boolean {
32
45
  const regexp = new RegExp(pattern)
33
46
  return contents.some((content) => regexp.test(content))
34
47
  }
@@ -43,16 +56,21 @@ const qseCDN = (() => {
43
56
  }
44
57
  })()
45
58
 
46
- /**
47
- * @param {*} args
48
- * @param {import('../utils/defineConfig.js').Configuration} override
49
- */
50
- export default function getWebpackConfig(args, override) {
59
+ interface CSSLoaderOptions {
60
+ importLoaders: number
61
+ sourceMap: boolean
62
+ modules: {
63
+ mode: 'global' | 'local'
64
+ localIdentName: string
65
+ }
66
+ }
67
+
68
+ export default function getWebpackConfig(args: any, override: CustomConfiguration): Configuration {
51
69
  const isDev = process.env.NODE_ENV === 'development'
52
70
  const isProd = process.env.NODE_ENV === 'production'
53
71
 
54
72
  // common function to get style loaders
55
- const getStyleLoaders = (cssOptions, preProcessor) => {
73
+ const getStyleLoaders = (cssOptions: CSSLoaderOptions, preProcessor?: string) => {
56
74
  const loaders = [
57
75
  {
58
76
  loader: require.resolve('style-loader'),
@@ -89,7 +107,7 @@ export default function getWebpackConfig(args, override) {
89
107
  isProd && PostcssSafeAreaPlugin(),
90
108
  isProd && [require.resolve('postcss-momentum-scrolling'), ['scroll', 'auto']],
91
109
  require.resolve('postcss-normalize'),
92
- ...override.extraPostCSSPlugins,
110
+ ...(override.extraPostCSSPlugins || []),
93
111
  ].filter(Boolean),
94
112
  },
95
113
  sourceMap: isDev,
@@ -102,19 +120,20 @@ export default function getWebpackConfig(args, override) {
102
120
  options: {
103
121
  lessOptions: {
104
122
  javascriptEnabled: true,
105
- modifyVars: fs.existsSync(paths.theme) ? require(paths.theme) : undefined,
123
+ modifyVars: fs.existsSync(paths.theme)
124
+ ? resolveModule(require(paths.theme))
125
+ : undefined,
106
126
  },
107
127
  sourceMap: true,
108
128
  },
109
- })
129
+ } as any)
110
130
  }
111
131
  return loaders
112
132
  }
113
133
 
114
- /** @type {import('@rspack/core').Configuration} */
115
- const config = {
134
+ const config: Configuration = {
116
135
  context: process.cwd(),
117
- mode: process.env.NODE_ENV,
136
+ mode: process.env.NODE_ENV as 'development' | 'production' | 'none',
118
137
  entry: './src/index',
119
138
  target: 'browserslist',
120
139
  output: {
@@ -184,6 +203,10 @@ export default function getWebpackConfig(args, override) {
184
203
  ...override.alias,
185
204
  },
186
205
  extensions: ['.web.js', '.web.mjs', '.js', '.mjs', '.jsx', '.ts', '.tsx', '.json', '.wasm'],
206
+ tsConfig: {
207
+ configFile: paths.tsconfig,
208
+ references: 'auto',
209
+ },
187
210
  },
188
211
  stats: false,
189
212
  devtool: isDev ? 'cheap-module-source-map' : false,
@@ -207,9 +230,10 @@ export default function getWebpackConfig(args, override) {
207
230
  import: [
208
231
  {
209
232
  libraryName: 'lodash',
210
- customName: 'lodash/{{member}}',
233
+ libraryDirectory: '',
234
+ camelToDashComponentName: false,
211
235
  },
212
- ...override.import,
236
+ ...(override.import || []),
213
237
  ],
214
238
  },
215
239
  isModule: 'unknown',
@@ -229,7 +253,7 @@ export default function getWebpackConfig(args, override) {
229
253
  },
230
254
  },
231
255
  },
232
- },
256
+ } satisfies SwcLoaderOptions,
233
257
  },
234
258
  ],
235
259
  },
@@ -365,7 +389,7 @@ export default function getWebpackConfig(args, override) {
365
389
  test: /\.(?!(?:js|mjs|jsx|ts|tsx|html|json)$)[^.]+$/,
366
390
  type: 'asset/resource',
367
391
  },
368
- ].filter(Boolean),
392
+ ].filter(Boolean) as RuleSetRule[],
369
393
  },
370
394
  ],
371
395
  },
@@ -417,7 +441,7 @@ export default function getWebpackConfig(args, override) {
417
441
  : []),
418
442
  process.env.ANALYZE && isProd && new RsdoctorRspackPlugin(),
419
443
  isDev &&
420
- ((compiler) => {
444
+ ((compiler: Compiler) => {
421
445
  let isFirst = true
422
446
  compiler.hooks.afterDone.tap('edu-scripts-startup', (stats) => {
423
447
  if (!isFirst) console.clear()
@@ -1,6 +1,15 @@
1
+ import type { Configuration } from '@rspack/dev-server'
2
+ import type { Configuration as CustomConfiguration } from '../utils/defineConfig'
1
3
  import setupMockServer from './plugins/mock-server'
2
4
 
3
- function createProxy(context, target, origin) {
5
+ interface ProxyConfig {
6
+ context: string[]
7
+ target: string
8
+ changeOrigin: boolean
9
+ onProxyReq: (proxyReq: any) => void
10
+ }
11
+
12
+ function createProxy(context: string, target: string, origin?: string): ProxyConfig {
4
13
  const url = new URL(origin || target)
5
14
 
6
15
  return {
@@ -15,15 +24,10 @@ function createProxy(context, target, origin) {
15
24
  }
16
25
  }
17
26
 
18
- /**
19
- * @param {*} args
20
- * @param {import('../utils/defineConfig.js').Configuration} override
21
- */
22
- export default function getWebpackDevServerConfig(args, override) {
27
+ export default function getWebpackDevServerConfig(args: any, override: CustomConfiguration): Configuration {
23
28
  const host = process.env.HOST || '0.0.0.0'
24
29
 
25
- /** @type {import('@rspack/dev-server').Configuration} */
26
- const devServer = {
30
+ const devServer: Configuration = {
27
31
  allowedHosts: 'all',
28
32
  historyApiFallback: true,
29
33
  port: args.port,
@@ -56,19 +60,19 @@ export default function getWebpackDevServerConfig(args, override) {
56
60
 
57
61
  if (override.proxy) {
58
62
  if (Array.isArray(override.proxy)) {
59
- devServer.proxy = [...override.proxy, ...devServer.proxy]
63
+ devServer.proxy = [...override.proxy, ...(devServer.proxy || [])]
60
64
  } else if (typeof override.proxy === 'object') {
61
65
  const proxies = Object.entries(override.proxy).map(([context, target]) => {
62
- return createProxy(context, target)
66
+ return createProxy(context, target as string)
63
67
  })
64
- devServer.proxy = [...proxies, ...devServer.proxy]
68
+ devServer.proxy = [...proxies, ...(devServer.proxy || [])]
65
69
  } else {
66
70
  throw new Error('proxy 必须是数组或对象')
67
71
  }
68
72
 
69
73
  // 清理重复的代理配置
70
- const proxyMap = new Map()
71
- devServer.proxy = devServer.proxy.filter((item) => {
74
+ const proxyMap = new Map<string, boolean>()
75
+ devServer.proxy = (devServer.proxy as ProxyConfig[]).filter((item) => {
72
76
  const key = JSON.stringify([...item.context].sort())
73
77
  if (!proxyMap.has(key)) {
74
78
  proxyMap.set(key, true)
package/src/deploy.ts CHANGED
@@ -96,7 +96,7 @@ async function normalDeploy(args: DeployArgs) {
96
96
  try {
97
97
  await sftp.fastGet(remoteLogFile, tmpLogFile)
98
98
  content = await fs.readFile(tmpLogFile, 'utf-8')
99
- } catch (_error: any) {}
99
+ } catch {}
100
100
  content = updateLogContent(content, info)
101
101
  await fs.writeFile(tmpLogFile, content)
102
102
  await sftp.fastPut(tmpLogFile, remoteLogFile)
@@ -9,11 +9,22 @@ import fs from 'fs-extra'
9
9
  import path from 'path'
10
10
  import chalk from 'chalk'
11
11
  import filesize from 'filesize'
12
+ // @ts-ignore
12
13
  import recursive from 'recursive-readdir'
13
14
  import stripAnsi from 'strip-ansi'
14
15
  import { gzipSizeSync } from 'gzip-size'
16
+ import type { Stats } from '@rspack/core'
15
17
 
16
- function canReadAsset(asset) {
18
+ interface SizeMap {
19
+ root: string
20
+ sizes: Record<string, number>
21
+ }
22
+
23
+ interface WebpackStats extends Stats {
24
+ stats?: Stats[]
25
+ }
26
+
27
+ function canReadAsset(asset: string): boolean {
17
28
  return (
18
29
  /\.(js|css)$/.test(asset) &&
19
30
  !/service-worker\.js/.test(asset) &&
@@ -23,24 +34,24 @@ function canReadAsset(asset) {
23
34
 
24
35
  // Prints a detailed summary of build files.
25
36
  function printFileSizesAfterBuild(
26
- webpackStats,
27
- previousSizeMap,
28
- buildFolder,
29
- maxBundleGzipSize,
30
- maxChunkGzipSize
31
- ) {
32
- var root = previousSizeMap.root
33
- var sizes = previousSizeMap.sizes
34
- var assets = (webpackStats.stats || [webpackStats])
37
+ webpackStats: WebpackStats,
38
+ previousSizeMap: SizeMap,
39
+ buildFolder: string,
40
+ maxBundleGzipSize: number,
41
+ maxChunkGzipSize: number
42
+ ): void {
43
+ const root = previousSizeMap.root
44
+ const sizes = previousSizeMap.sizes
45
+ const assets = (webpackStats.stats || [webpackStats])
35
46
  .map((stats) =>
36
47
  stats
37
48
  .toJson({ all: false, assets: true })
38
- .assets.filter((asset) => canReadAsset(asset.name))
49
+ .assets!.filter((asset) => canReadAsset(asset.name))
39
50
  .map((asset) => {
40
- var fileContents = fs.readFileSync(path.join(root, asset.name))
41
- var size = gzipSizeSync(fileContents)
42
- var previousSize = sizes[removeFileNameHash(root, asset.name)]
43
- var difference = getDifferenceLabel(size, previousSize)
51
+ const fileContents = fs.readFileSync(path.join(root, asset.name))
52
+ const size = gzipSizeSync(fileContents)
53
+ const previousSize = sizes[removeFileNameHash(root, asset.name)]
54
+ const difference = getDifferenceLabel(size, previousSize)
44
55
  return {
45
56
  folder: path.join(path.basename(buildFolder), path.dirname(asset.name)),
46
57
  name: path.basename(asset.name),
@@ -58,24 +69,24 @@ function printFileSizesAfterBuild(
58
69
  assets.sort((a, b) => b.size - a.size)
59
70
 
60
71
  // move main file to first
61
- var mainAssetIdx = assets.findIndex((asset) => /_\d+\.\d+\.\d+/.test(asset.name))
72
+ const mainAssetIdx = assets.findIndex((asset) => /_\d+\.\d+\.\d+/.test(asset.name))
62
73
  assets.unshift(assets.splice(mainAssetIdx, 1)[0])
63
74
 
64
- var longestSizeLabelLength = Math.max.apply(
75
+ const longestSizeLabelLength = Math.max.apply(
65
76
  null,
66
77
  assets.map((a) => stripAnsi(a.sizeLabel).length)
67
78
  )
68
- var suggestBundleSplitting = false
79
+ let suggestBundleSplitting = false
69
80
  assets.forEach((asset) => {
70
- var sizeLabel = asset.sizeLabel
71
- var sizeLength = stripAnsi(sizeLabel).length
81
+ let sizeLabel = asset.sizeLabel
82
+ const sizeLength = stripAnsi(sizeLabel).length
72
83
  if (sizeLength < longestSizeLabelLength) {
73
- var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength)
84
+ const rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength)
74
85
  sizeLabel += rightPadding
75
86
  }
76
- var isMainBundle = /_\d+\.\d+\.\d+\./.test(asset.name)
77
- var maxRecommendedSize = isMainBundle ? maxBundleGzipSize : maxChunkGzipSize
78
- var isLarge = maxRecommendedSize && asset.size > maxRecommendedSize
87
+ const isMainBundle = /_\d+\.\d+\.\d+\./.test(asset.name)
88
+ const maxRecommendedSize = isMainBundle ? maxBundleGzipSize : maxChunkGzipSize
89
+ const isLarge = maxRecommendedSize && asset.size > maxRecommendedSize
79
90
  if (isLarge && path.extname(asset.name) === '.js') {
80
91
  suggestBundleSplitting = true
81
92
  }
@@ -100,7 +111,7 @@ function printFileSizesAfterBuild(
100
111
  console.log()
101
112
  }
102
113
 
103
- function removeFileNameHash(buildFolder, fileName) {
114
+ function removeFileNameHash(buildFolder: string, fileName: string): string {
104
115
  return fileName
105
116
  .replace(buildFolder, '')
106
117
  .replace(/\\/g, '/')
@@ -110,10 +121,10 @@ function removeFileNameHash(buildFolder, fileName) {
110
121
 
111
122
  // Input: 1024, 2048
112
123
  // Output: "(+1 KB)"
113
- function getDifferenceLabel(currentSize, previousSize) {
114
- var FIFTY_KILOBYTES = 1024 * 50
115
- var difference = currentSize - previousSize
116
- var fileSize = !Number.isNaN(difference) ? filesize(difference) : 0
124
+ function getDifferenceLabel(currentSize: number, previousSize: number): string {
125
+ const FIFTY_KILOBYTES = 1024 * 50
126
+ const difference = currentSize - previousSize
127
+ const fileSize = !Number.isNaN(difference) ? filesize(difference) : 0
117
128
  if (difference >= FIFTY_KILOBYTES) {
118
129
  return chalk.red('+' + fileSize)
119
130
  } else if (difference < FIFTY_KILOBYTES && difference > 0) {
@@ -125,17 +136,20 @@ function getDifferenceLabel(currentSize, previousSize) {
125
136
  }
126
137
  }
127
138
 
128
- function measureFileSizesBeforeBuild(buildFolder) {
139
+ function measureFileSizesBeforeBuild(buildFolder: string): Promise<SizeMap> {
129
140
  return new Promise((resolve) => {
130
- recursive(buildFolder, (err, fileNames) => {
131
- var sizes
141
+ recursive(buildFolder, (err: any, fileNames: any) => {
142
+ let sizes: Record<string, number> | undefined
132
143
  if (!err && fileNames) {
133
- sizes = fileNames.filter(canReadAsset).reduce((memo, fileName) => {
134
- var contents = fs.readFileSync(fileName)
135
- var key = removeFileNameHash(buildFolder, fileName)
136
- memo[key] = gzipSizeSync(contents)
137
- return memo
138
- }, {})
144
+ sizes = fileNames.filter(canReadAsset).reduce(
145
+ (memo: any, fileName: any) => {
146
+ const contents = fs.readFileSync(fileName)
147
+ const key = removeFileNameHash(buildFolder, fileName)
148
+ memo[key] = gzipSizeSync(contents)
149
+ return memo
150
+ },
151
+ {} as Record<string, number>
152
+ )
139
153
  }
140
154
  resolve({
141
155
  root: buildFolder,
@@ -1,24 +1,28 @@
1
+ // @ts-nocheck
1
2
  import { parse, traverse, types as t, transformFromAstSync } from '@babel/core'
2
3
 
3
4
  // ver.js 中定义模块的数组
4
5
  const TARGET_IDENTIFIER_NAME = 'project_apiArr'
5
6
  const MODULE_IDENTIFIER_NAME = 'module'
6
7
 
7
- function changeDeployVersion(code, pkg) {
8
+ interface PackageInfo {
9
+ name: string
10
+ version: string
11
+ grayscale?: boolean
12
+ }
13
+
14
+ function changeDeployVersion(code: string, pkg: PackageInfo): string {
8
15
  const { name, version, grayscale } = pkg
9
16
  let ast
10
17
  try {
11
18
  ast = parse(code, { filename: 'ver.js' })
12
- } catch (error) {
19
+ } catch (error: any) {
13
20
  throw new Error(`代码解析错误: ${error.message}`, { cause: error })
14
21
  }
15
22
  const keyName = grayscale ? 'grayscale' : 'main'
16
23
 
17
- /**
18
- * @return {babel.NodePath<t.VariableDeclarator> | undefined}
19
- */
20
- function findTargetDeclarator(ast) {
21
- let res
24
+ function findTargetDeclarator(ast: any): any | undefined {
25
+ let res: any | undefined
22
26
 
23
27
  traverse(ast, {
24
28
  VariableDeclarator(path) {
@@ -34,18 +38,15 @@ function changeDeployVersion(code, pkg) {
34
38
  return res
35
39
  }
36
40
 
37
- /**
38
- * @param {babel.NodePath<t.VariableDeclarator>} path
39
- * @return {babel.NodePath<t.ObjectExpression> | undefined}
40
- */
41
- function findModuleObject(path) {
42
- let res
41
+ function findModuleObject(path: any): any | undefined {
42
+ let res: any | undefined
43
43
 
44
44
  path.traverse({
45
45
  ObjectExpression(path) {
46
46
  if (
47
47
  path.node.properties.some(
48
48
  (node) =>
49
+ t.isObjectProperty(node) &&
49
50
  t.isIdentifier(node.key, { name: MODULE_IDENTIFIER_NAME }) &&
50
51
  t.isLiteral(node.value, { value: name })
51
52
  )
@@ -58,15 +59,14 @@ function changeDeployVersion(code, pkg) {
58
59
  return res
59
60
  }
60
61
 
61
- /**
62
- * @param {babel.NodePath<t.ObjectExpression>} path
63
- */
64
- function modifyModuleVersion(path) {
62
+ function modifyModuleVersion(path: any): void {
65
63
  let hasModify = false
66
64
  path.traverse({
67
65
  Property(path) {
68
- if (path.node.key.name === keyName) {
69
- path.node.value.value = version
66
+ if (t.isObjectProperty(path.node) && t.isIdentifier(path.node.key, { name: keyName })) {
67
+ if (t.isStringLiteral(path.node.value)) {
68
+ path.node.value.value = version
69
+ }
70
70
  hasModify = true
71
71
  }
72
72
  },
@@ -76,10 +76,8 @@ function changeDeployVersion(code, pkg) {
76
76
  path.node.properties.push(t.objectProperty(t.identifier(keyName), t.stringLiteral(version)))
77
77
  }
78
78
  }
79
- /**
80
- * @param {babel.NodePath<t.ObjectExpression>} path
81
- */
82
- function deleteModuleComments(path) {
79
+
80
+ function deleteModuleComments(path: any): void {
83
81
  path.traverse({
84
82
  ObjectExpression(path) {
85
83
  delete path.node.leadingComments
@@ -87,19 +85,18 @@ function changeDeployVersion(code, pkg) {
87
85
  })
88
86
  }
89
87
 
90
- /**
91
- * @param {babel.NodePath<t.VariableDeclarator>} path
92
- */
93
- function addModuleToTarget(path) {
94
- const elements = path.node.init.elements
95
- elements.splice(
96
- elements.length - 2,
97
- 0,
98
- t.objectExpression([
99
- t.objectProperty(t.identifier(MODULE_IDENTIFIER_NAME), t.stringLiteral(name)),
100
- t.objectProperty(t.identifier(keyName), t.stringLiteral(version)),
101
- ])
102
- )
88
+ function addModuleToTarget(path: any): void {
89
+ if (t.isArrayExpression(path.node.init)) {
90
+ const elements = path.node.init.elements
91
+ elements.splice(
92
+ elements.length - 2,
93
+ 0,
94
+ t.objectExpression([
95
+ t.objectProperty(t.identifier(MODULE_IDENTIFIER_NAME), t.stringLiteral(name)),
96
+ t.objectProperty(t.identifier(keyName), t.stringLiteral(version)),
97
+ ])
98
+ )
99
+ }
103
100
  }
104
101
 
105
102
  const targetPath = findTargetDeclarator(ast)
@@ -113,7 +110,12 @@ function changeDeployVersion(code, pkg) {
113
110
  }
114
111
  deleteModuleComments(targetPath)
115
112
 
116
- return transformFromAstSync(ast, undefined, { filename: 'ver.js', minified: true }).code
113
+ const result = transformFromAstSync(ast, undefined, { filename: 'ver.js', minified: true })
114
+ if (!result || !result.code) {
115
+ throw new Error('代码转换失败')
116
+ }
117
+
118
+ return result.code
117
119
  }
118
120
 
119
121
  export default changeDeployVersion
@@ -1,22 +1,17 @@
1
1
  import type { Chalk } from 'chalk'
2
- import type { Compiler, Configuration as RspackConfiguration } from '@rspack/core'
2
+ import type { Compiler, Configuration as RspackConfiguration, SwcLoaderOptions } from '@rspack/core'
3
3
  import type { Configuration as DevServerConfiguration } from '@rspack/dev-server'
4
4
 
5
5
  type ProxyConfigArray = NonNullable<DevServerConfiguration['proxy']>
6
6
 
7
- export type BabelImportPlugin = {
8
- libraryName: string
9
- libraryDirectory?: string
10
- customName?: string
11
- style?: boolean | 'css' | string
12
- }
13
-
14
7
  export type Configuration = {
15
8
  webpack?: (config: RspackConfiguration) => RspackConfiguration | undefined
16
9
  devServer?: (config: DevServerConfiguration) => DevServerConfiguration | undefined
17
10
  /**
18
11
  * webpack alias 配置,会与内置 alias 合并
19
12
  *
13
+ * 会自动读取 tsconfig 里 baseUrl + paths 的配置
14
+ *
20
15
  * @default
21
16
  * { '@': './src' }
22
17
  */
@@ -76,12 +71,10 @@ export type Configuration = {
76
71
  /**
77
72
  * 与 babel-plugin-import 类似,但是内部是 rspack 重构,libraryDirectory 默认值是 lib
78
73
  *
79
- * 如果 libraryDirectory 传 ’‘ 则必须使用 customName 来写
80
- *
81
74
  * @see https://rspack.rs/zh/guide/features/builtin-swc-loader#rspackexperimentsimport
82
- * @default [{libraryName: 'lodash', customName: 'lodash/{{member}}'}]
75
+ * @default [{libraryName: 'lodash',libraryDirectory: '',camelToDashComponentName: false}]
83
76
  */
84
- import?: BabelImportPlugin[]
77
+ import?: NonNullable<SwcLoaderOptions['rspackExperiments']>['import']
85
78
  }
86
79
  export function defineConfig(config: Configuration) {
87
80
  return config
@@ -2,6 +2,7 @@ import fs from 'fs-extra'
2
2
  import paths from '../config/paths'
3
3
  import { createRequire } from 'node:module'
4
4
  import { type Configuration } from './defineConfig'
5
+ import { resolveModule } from './resolveModule'
5
6
 
6
7
  const require = createRequire(import.meta.url)
7
8
 
@@ -21,7 +22,7 @@ export default function getOverride(): Configuration {
21
22
  override = Object.assign({}, defaultOverride)
22
23
 
23
24
  if (fs.existsSync(paths.override)) {
24
- const userOverride = require(paths.override)
25
+ const userOverride = resolveModule(require(paths.override))
25
26
  if (typeof userOverride !== 'object')
26
27
  throw new Error('格式错误,请使用 npx edu g override 生成文件')
27
28
  Object.assign(override, userOverride)
@@ -0,0 +1,3 @@
1
+ export function resolveModule(mod: any) {
2
+ return mod.default ? mod.default : mod
3
+ }