@qse/edu-scripts 1.14.10 → 1.14.12

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,9 @@
1
1
  # 更新日志
2
2
 
3
+ ## 1.14.11 (2025-05-12)
4
+
5
+ - feat: 优化热更新能力,适配 v1 环境
6
+
3
7
  ## 1.14.10 (2025-05-08)
4
8
 
5
9
  - feat: 部署增加文曲智阅(钉钉一方化)
package/lib/build.js CHANGED
@@ -42,8 +42,6 @@ module.exports = async function build(args) {
42
42
  process.exit(1);
43
43
  }
44
44
  console.log(stats.toString({ colors: true, preset: "errors-warnings", timings: true }));
45
- console.log();
46
- console.log("gzip 后文件大小:\n");
47
45
  printFileSizesAfterBuild(
48
46
  stats,
49
47
  previousSizeMap,
@@ -51,7 +49,6 @@ module.exports = async function build(args) {
51
49
  WARN_AFTER_BUNDLE_GZIP_SIZE,
52
50
  WARN_AFTER_CHUNK_GZIP_SIZE
53
51
  );
54
- console.log();
55
52
  if (appConfig.single) {
56
53
  console.log(`打包完成,可以使用 ${chalk.green("@qse/ssh-sftp")} 自动部署代码到 v1`);
57
54
  } else {
@@ -1,3 +1,26 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from === "object" || typeof from === "function") {
9
+ for (let key of __getOwnPropNames(from))
10
+ if (!__hasOwnProp.call(to, key) && key !== except)
11
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ }
13
+ return to;
14
+ };
15
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
+ // If the importer is in node compatibility mode or this is not an ESM
17
+ // file that has been converted to a CommonJS file using a Babel-
18
+ // compatible transform (i.e. "__esModule" has not been set), then set
19
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
+ mod
22
+ ));
23
+
1
24
  // src/config/babel.dependencies.js
2
25
  var getOverride = require("../utils/getOverride");
3
26
  module.exports = function getBabelConfig(opts = {}) {
@@ -13,7 +36,7 @@ module.exports = function getBabelConfig(opts = {}) {
13
36
  inputSourceMap: isDev,
14
37
  presets: [
15
38
  [
16
- "@babel/preset-env",
39
+ require.resolve("@babel/preset-env"),
17
40
  {
18
41
  modules: opts.modules,
19
42
  useBuiltIns: "entry",
@@ -25,7 +48,7 @@ module.exports = function getBabelConfig(opts = {}) {
25
48
  ].filter(Boolean),
26
49
  plugins: [
27
50
  [
28
- "@babel/plugin-transform-runtime",
51
+ require.resolve("@babel/plugin-transform-runtime"),
29
52
  {
30
53
  corejs: false,
31
54
  helpers: true,
@@ -41,7 +64,7 @@ module.exports = function getBabelConfig(opts = {}) {
41
64
  }
42
65
  ],
43
66
  [
44
- "import",
67
+ require.resolve("babel-plugin-import"),
45
68
  { libraryName: "lodash", libraryDirectory: "", camel2DashComponentName: false },
46
69
  "lodash"
47
70
  ]
@@ -46,7 +46,7 @@ module.exports = function getBabelConfig(opts = {}) {
46
46
  configFile: false,
47
47
  presets: [
48
48
  [
49
- "@babel/preset-env",
49
+ require.resolve("@babel/preset-env"),
50
50
  {
51
51
  modules: opts.modules,
52
52
  useBuiltIns: "entry",
@@ -56,18 +56,18 @@ module.exports = function getBabelConfig(opts = {}) {
56
56
  }
57
57
  ],
58
58
  [
59
- "@babel/preset-react",
59
+ require.resolve("@babel/preset-react"),
60
60
  {
61
61
  development: isDev,
62
62
  runtime: hasJsxRuntime ? "automatic" : "classic",
63
63
  useBuiltIns: !hasJsxRuntime
64
64
  }
65
65
  ],
66
- isTypeScriptEnabled && "@babel/preset-typescript"
66
+ isTypeScriptEnabled && require.resolve("@babel/preset-typescript")
67
67
  ].filter(Boolean),
68
68
  plugins: [
69
69
  [
70
- "@babel/plugin-transform-runtime",
70
+ require.resolve("@babel/plugin-transform-runtime"),
71
71
  {
72
72
  corejs: false,
73
73
  helpers: true,
@@ -82,16 +82,13 @@ module.exports = function getBabelConfig(opts = {}) {
82
82
  // useESModules: true,
83
83
  }
84
84
  ],
85
- ["@babel/plugin-proposal-decorators", { legacy: true }],
86
- ["@babel/plugin-transform-class-properties", { loose: true }],
87
- ["@babel/plugin-transform-private-methods", { loose: true }],
88
- ["@babel/plugin-transform-private-property-in-object", { loose: true }],
85
+ [require.resolve("@babel/plugin-proposal-decorators"), { version: "2023-11" }],
89
86
  [
90
- "import",
87
+ require.resolve("babel-plugin-import"),
91
88
  { libraryName: "lodash", libraryDirectory: "", camel2DashComponentName: false },
92
89
  "lodash"
93
90
  ],
94
- isDev && "react-refresh/babel",
91
+ isDev && require.resolve("react-refresh/babel"),
95
92
  addWebpackChunkName
96
93
  ].filter(Boolean)
97
94
  };
@@ -0,0 +1,118 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/config/plugins/ws-utils-createSocketURL.js
20
+ var ws_utils_createSocketURL_exports = {};
21
+ __export(ws_utils_createSocketURL_exports, {
22
+ default: () => ws_utils_createSocketURL_default
23
+ });
24
+ module.exports = __toCommonJS(ws_utils_createSocketURL_exports);
25
+ function format(objURL) {
26
+ var protocol = objURL.protocol || "";
27
+ if (protocol && protocol.substr(-1) !== ":") {
28
+ protocol += ":";
29
+ }
30
+ var auth = objURL.auth || "";
31
+ if (auth) {
32
+ auth = encodeURIComponent(auth);
33
+ auth = auth.replace(/%3A/i, ":");
34
+ auth += "@";
35
+ }
36
+ var host = "";
37
+ if (objURL.hostname) {
38
+ host = auth + (objURL.hostname.indexOf(":") === -1 ? objURL.hostname : "[".concat(objURL.hostname, "]"));
39
+ if (objURL.port) {
40
+ host += ":".concat(objURL.port);
41
+ }
42
+ }
43
+ var pathname = objURL.pathname || "";
44
+ if (objURL.slashes) {
45
+ host = "//".concat(host || "");
46
+ if (pathname && pathname.charAt(0) !== "/") {
47
+ pathname = "/".concat(pathname);
48
+ }
49
+ } else if (!host) {
50
+ host = "";
51
+ }
52
+ var search = objURL.search || "";
53
+ if (search && search.charAt(0) !== "?") {
54
+ search = "?".concat(search);
55
+ }
56
+ var hash = objURL.hash || "";
57
+ if (hash && hash.charAt(0) !== "#") {
58
+ hash = "#".concat(hash);
59
+ }
60
+ pathname = pathname.replace(
61
+ /[?#]/g,
62
+ /**
63
+ * @param {string} match
64
+ * @returns {string}
65
+ */
66
+ function(match) {
67
+ return encodeURIComponent(match);
68
+ }
69
+ );
70
+ search = search.replace("#", "%23");
71
+ return "".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);
72
+ }
73
+ function createSocketURL(parsedURL) {
74
+ var hostname = parsedURL.hostname;
75
+ var isInAddrAny = hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]";
76
+ if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf("http") === 0) {
77
+ hostname = self.location.hostname;
78
+ }
79
+ var socketURLProtocol = parsedURL.protocol || self.location.protocol;
80
+ if (socketURLProtocol === "auto:" || hostname && isInAddrAny && self.location.protocol === "https:") {
81
+ socketURLProtocol = self.location.protocol;
82
+ }
83
+ socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, "ws");
84
+ var socketURLAuth = "";
85
+ if (parsedURL.username) {
86
+ socketURLAuth = parsedURL.username;
87
+ if (parsedURL.password) {
88
+ socketURLAuth = socketURLAuth.concat(":", parsedURL.password);
89
+ }
90
+ }
91
+ var socketURLHostname = (hostname || self.location.hostname || "localhost").replace(
92
+ /^\[(.*)\]$/,
93
+ "$1"
94
+ );
95
+ var socketURLPort = parsedURL.port;
96
+ if (!socketURLPort || socketURLPort === "0") {
97
+ socketURLPort = self.location.port;
98
+ }
99
+ var socketURLPathname = "/ws";
100
+ if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
101
+ socketURLPathname = parsedURL.pathname;
102
+ if (hostname.indexOf("zhidianbao.cn") > -1 || hostname.indexOf("qsban.cn") > -1) {
103
+ var ctx = self.location.pathname.split("/")[1];
104
+ if (ctx) {
105
+ socketURLPathname = "/" + ctx + socketURLPathname;
106
+ }
107
+ }
108
+ }
109
+ return format({
110
+ protocol: socketURLProtocol,
111
+ auth: socketURLAuth,
112
+ hostname: socketURLHostname,
113
+ port: socketURLPort,
114
+ pathname: socketURLPathname,
115
+ slashes: true
116
+ });
117
+ }
118
+ var ws_utils_createSocketURL_default = createSocketURL;
@@ -1,3 +1,26 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from === "object" || typeof from === "function") {
9
+ for (let key of __getOwnPropNames(from))
10
+ if (!__hasOwnProp.call(to, key) && key !== except)
11
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ }
13
+ return to;
14
+ };
15
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
+ // If the importer is in node compatibility mode or this is not an ESM
17
+ // file that has been converted to a CommonJS file using a Babel-
18
+ // compatible transform (i.e. "__esModule" has not been set), then set
19
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
+ mod
22
+ ));
23
+
1
24
  // src/config/webpackConfig.js
2
25
  var fs = require("fs");
3
26
  var webpack = require("webpack");
@@ -10,7 +33,6 @@ var CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
10
33
  var appPkg = require(paths.package);
11
34
  var appConfig = require("../utils/appConfig");
12
35
  var { ESBuildMinifyPlugin } = require("esbuild-loader");
13
- var ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
14
36
  var once = require("lodash/once");
15
37
  var jsMainPath = appConfig.grayscale ? `${appPkg.name}/beta/${appPkg.name}` : `${appPkg.name}/${appPkg.name}`;
16
38
  var assetPath = appConfig.grayscale ? `${appPkg.name}/beta/${appPkg.version}` : `${appPkg.name}/${appPkg.version}`;
@@ -40,18 +62,18 @@ module.exports = function getWebpackConfig(args, override) {
40
62
  const getStyleLoaders = (cssOptions, preProcessor) => {
41
63
  const loaders = [
42
64
  {
43
- loader: "style-loader",
65
+ loader: require.resolve("style-loader"),
44
66
  options: { attributes: { "data-module": appPkg.name, "data-version": appPkg.version } }
45
67
  },
46
68
  {
47
- loader: "css-loader",
69
+ loader: require.resolve("css-loader"),
48
70
  options: cssOptions
49
71
  },
50
72
  {
51
73
  // Options for PostCSS as we reference these options twice
52
74
  // Adds vendor prefixing based on your specified browser support in
53
75
  // package.json
54
- loader: "postcss-loader",
76
+ loader: require.resolve("postcss-loader"),
55
77
  options: {
56
78
  postcssOptions: {
57
79
  // Necessary for external CSS imports to work
@@ -60,10 +82,10 @@ module.exports = function getWebpackConfig(args, override) {
60
82
  config: false,
61
83
  plugins: [
62
84
  isProd && require("cssnano")({ preset: "default" }),
63
- fs.existsSync(paths.tailwind) && "tailwindcss",
64
- "postcss-flexbugs-fixes",
85
+ fs.existsSync(paths.tailwind) && require.resolve("tailwindcss"),
86
+ require.resolve("postcss-flexbugs-fixes"),
65
87
  [
66
- "postcss-preset-env",
88
+ require.resolve("postcss-preset-env"),
67
89
  {
68
90
  autoprefixer: {
69
91
  flexbox: "no-2009"
@@ -72,8 +94,8 @@ module.exports = function getWebpackConfig(args, override) {
72
94
  }
73
95
  ],
74
96
  isProd && require("./plugins/postcss-safe-area")(),
75
- isProd && ["postcss-momentum-scrolling", ["scroll", "auto"]],
76
- "postcss-normalize",
97
+ isProd && [require.resolve("postcss-momentum-scrolling"), ["scroll", "auto"]],
98
+ require.resolve("postcss-normalize"),
77
99
  ...override.extraPostCSSPlugins
78
100
  ].filter(Boolean)
79
101
  },
@@ -83,7 +105,7 @@ module.exports = function getWebpackConfig(args, override) {
83
105
  ];
84
106
  if (preProcessor === "less-loader") {
85
107
  loaders.push({
86
- loader: "less-loader",
108
+ loader: require.resolve("less-loader"),
87
109
  options: {
88
110
  lessOptions: {
89
111
  javascriptEnabled: true,
@@ -185,13 +207,13 @@ module.exports = function getWebpackConfig(args, override) {
185
207
  },
186
208
  {
187
209
  test: /\.(j|t)sx?$/,
188
- loader: "babel-loader",
210
+ loader: require.resolve("babel-loader"),
189
211
  exclude: /node_modules/,
190
212
  options: require("./babel")()
191
213
  },
192
214
  override.transformNodeModules && {
193
215
  test: /\.m?js$/,
194
- loader: "babel-loader",
216
+ loader: require.resolve("babel-loader"),
195
217
  exclude: /@babel(?:\/|\\{1,2})runtime/,
196
218
  options: require("./babel.dependencies")()
197
219
  },
@@ -276,7 +298,7 @@ module.exports = function getWebpackConfig(args, override) {
276
298
  test: /\.svg$/,
277
299
  use: [
278
300
  {
279
- loader: "@svgr/webpack",
301
+ loader: require.resolve("@svgr/webpack"),
280
302
  options: {
281
303
  prettier: false,
282
304
  svgo: false,
@@ -288,7 +310,7 @@ module.exports = function getWebpackConfig(args, override) {
288
310
  }
289
311
  },
290
312
  {
291
- loader: "url-loader",
313
+ loader: require.resolve("url-loader"),
292
314
  options: {
293
315
  limit: imageInlineSizeLimit
294
316
  }
@@ -318,6 +340,11 @@ module.exports = function getWebpackConfig(args, override) {
318
340
  qseCDN.isUseCommon && new webpack.DllReferencePlugin({
319
341
  manifest: require("../asset/dll/libcommon3-manifest.json")
320
342
  }),
343
+ new webpack.NormalModuleReplacementPlugin(/createSocketURL\.js$/, (resource) => {
344
+ if (resource.context.includes("webpack-dev-server")) {
345
+ resource.request = require.resolve("./plugins/ws-utils-createSocketURL");
346
+ }
347
+ }),
321
348
  new webpack.IgnorePlugin({
322
349
  resourceRegExp: /^\.\/locale$/,
323
350
  contextRegExp: /moment$/
@@ -327,8 +354,6 @@ module.exports = function getWebpackConfig(args, override) {
327
354
  "process.env.APP_VERSION": JSON.stringify(appPkg.version),
328
355
  "process.env.BABEL_ENV": JSON.stringify(process.env.BABEL_ENV),
329
356
  "process.env.BROWSERSLIST": JSON.stringify(process.env.BROWSERSLIST),
330
- "process.env.WDS_SOCKET_HOST": JSON.stringify(process.env.WDS_SOCKET_HOST),
331
- "process.env.WDS_SOCKET_PORT": JSON.stringify(process.env.WDS_SOCKET_PORT),
332
357
  ...override.define
333
358
  }),
334
359
  new webpack.ProgressPlugin(),
@@ -367,17 +392,6 @@ module.exports = function getWebpackConfig(args, override) {
367
392
  optimization: {
368
393
  minimize: isProd && override.minify !== false,
369
394
  minimizer: [
370
- override.minifyImage && new ImageMinimizerPlugin({
371
- minimizer: {
372
- implementation: ImageMinimizerPlugin.sharpMinify,
373
- options: {
374
- encodeOptions: {
375
- // Your options for `sharp`
376
- // https://sharp.pixelplumbing.com/api-output
377
- }
378
- }
379
- }
380
- }),
381
395
  override.minify === "esbuild" && new ESBuildMinifyPlugin({
382
396
  pure: override.pure_funcs ?? ["console.log"],
383
397
  drop: ["debugger"],
@@ -3,8 +3,6 @@ var WebpackDevServer = require("webpack-dev-server");
3
3
  var setupMockServer = require("./plugins/mock-server");
4
4
  module.exports = function getWebpackDevServerConfig(args, override) {
5
5
  const host = process.env.HOST || "0.0.0.0";
6
- const sockHost = process.env.WDS_SOCKET_HOST;
7
- const sockPort = process.env.WDS_SOCKET_PORT;
8
6
  const devServer = {
9
7
  hot: true,
10
8
  allowedHosts: "all",
@@ -13,7 +11,7 @@ module.exports = function getWebpackDevServerConfig(args, override) {
13
11
  open: args.open,
14
12
  host,
15
13
  client: {
16
- webSocketURL: { protocol: "auto:", hostname: sockHost, port: sockPort },
14
+ webSocketURL: "auto://0.0.0.0:0/ws",
17
15
  overlay: {
18
16
  runtimeErrors: false,
19
17
  errors: true,
package/lib/start.js CHANGED
@@ -10,14 +10,12 @@ var WebpackDevServer = require("webpack-dev-server");
10
10
  var webpack = require("webpack");
11
11
  var getConfig = require("./utils/getConfig");
12
12
  var chalk = require("chalk");
13
- process.env.WDS_SOCKET_HOST = WebpackDevServer.internalIPSync("v4") || "127.0.0.1";
14
13
  module.exports = async function start(args) {
15
14
  const basePort = process.env.WEBPACK_DEV_SERVER_BASE_PORT;
16
15
  const port = await WebpackDevServer.getFreePort(args.port || process.env.PORT);
17
16
  if (!(args.port || process.env.PORT) && +port !== +basePort) {
18
17
  console.log(chalk.bgYellow(`${basePort} 端口已被占用,现切换到 ${port} 端口运行`));
19
18
  }
20
- process.env.WDS_SOCKET_PORT = port;
21
19
  args.port = port;
22
20
  process.env.PORT = port;
23
21
  const compiler = webpack(getConfig(args));
@@ -26,6 +26,9 @@ function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, ma
26
26
  };
27
27
  })
28
28
  ).reduce((single, all) => all.concat(single), []);
29
+ if (assets.length === 0)
30
+ return;
31
+ console.log("\ngzip 后文件大小:\n");
29
32
  assets.sort((a, b) => b.size - a.size);
30
33
  var mainAssetIdx = assets.findIndex((asset) => /_\d+\.\d+\.\d+\./.test(asset.name));
31
34
  assets.unshift(assets.splice(mainAssetIdx, 1)[0]);
@@ -60,6 +63,7 @@ function printFileSizesAfterBuild(webpackStats, previousSizeMap, buildFolder, ma
60
63
  console.log(chalk.yellow("考虑下使用代码分割解决"));
61
64
  console.log(chalk.yellow("也可以使用 npm run analyze 命令分析产物"));
62
65
  }
66
+ console.log();
63
67
  }
64
68
  function removeFileNameHash(buildFolder, fileName) {
65
69
  return fileName.replace(buildFolder, "").replace(/\\/g, "/").replace(/\/\d+\.\d+\.\d+\//, "/").replace(/\/?(.*)(\.[0-9a-f]+)(\.chunk)?(\.js|\.css)/, (match, p1, p2, p3, p4) => p1 + p4);
@@ -1,3 +1,26 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from === "object" || typeof from === "function") {
9
+ for (let key of __getOwnPropNames(from))
10
+ if (!__hasOwnProp.call(to, key) && key !== except)
11
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ }
13
+ return to;
14
+ };
15
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
+ // If the importer is in node compatibility mode or this is not an ESM
17
+ // file that has been converted to a CommonJS file using a Babel-
18
+ // compatible transform (i.e. "__esModule" has not been set), then set
19
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
+ mod
22
+ ));
23
+
1
24
  // src/utils/getOverride.js
2
25
  var fs = require("fs");
3
26
  var paths = require("../config/paths");
@@ -21,5 +44,18 @@ module.exports = function getOverride() {
21
44
  }
22
45
  if (override.minify === true)
23
46
  override.minify = defaultOverride.minify;
47
+ if (override.babel) {
48
+ const old = override.babel;
49
+ override.babel = (config, context) => {
50
+ const newConfig = old(config, context) || config;
51
+ let plugin = config.plugins.find(
52
+ (plugin2) => Array.isArray(plugin2) && /^(babel-plugin-)?import$/.test(plugin2[0])
53
+ );
54
+ if (plugin) {
55
+ plugin[0] = require.resolve("babel-plugin-import");
56
+ }
57
+ return newConfig;
58
+ };
59
+ }
24
60
  return override;
25
61
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qse/edu-scripts",
3
- "version": "1.14.10",
3
+ "version": "1.14.12",
4
4
  "author": "Kinoko",
5
5
  "license": "MIT",
6
6
  "description": "教育工程化基础框架",
@@ -45,6 +45,7 @@
45
45
  "@pmmmwh/react-refresh-webpack-plugin": "^0.5.16",
46
46
  "@qse/ssh-sftp": "^1.0.1",
47
47
  "@svgr/webpack": "^8.1.0",
48
+ "@types/express": "^4.17.21",
48
49
  "babel-loader": "^9.2.1",
49
50
  "babel-plugin-import": "^1.13.8",
50
51
  "case-sensitive-paths-webpack-plugin": "^2.4.0",
@@ -61,7 +62,6 @@
61
62
  "globby": "^11.1.0",
62
63
  "gzip-size": "^6.0.0",
63
64
  "html-webpack-plugin": "^5.6.3",
64
- "image-minimizer-webpack-plugin": "^3.8.3",
65
65
  "inquirer": "^8.2.6",
66
66
  "less": "^3.13.1",
67
67
  "less-loader": "^10.2.0",
@@ -81,7 +81,6 @@
81
81
  "recursive-readdir": "^2.2.3",
82
82
  "rimraf": "^3.0.2",
83
83
  "semver": "^7.7.1",
84
- "sharp": "^0.32.6",
85
84
  "strip-ansi": "^6.0.1",
86
85
  "style-loader": "^3.3.4",
87
86
  "tailwindcss": "^3.4.17",
package/src/build.js CHANGED
@@ -48,9 +48,7 @@ module.exports = async function build(args) {
48
48
  }
49
49
 
50
50
  console.log(stats.toString({ colors: true, preset: 'errors-warnings', timings: true }))
51
- console.log()
52
51
 
53
- console.log('gzip 后文件大小:\n')
54
52
  printFileSizesAfterBuild(
55
53
  stats,
56
54
  previousSizeMap,
@@ -58,7 +56,6 @@ module.exports = async function build(args) {
58
56
  WARN_AFTER_BUNDLE_GZIP_SIZE,
59
57
  WARN_AFTER_CHUNK_GZIP_SIZE
60
58
  )
61
- console.log()
62
59
 
63
60
  if (appConfig.single) {
64
61
  console.log(`打包完成,可以使用 ${chalk.green('@qse/ssh-sftp')} 自动部署代码到 v1`)
@@ -21,7 +21,7 @@ module.exports = function getBabelConfig(opts = {}) {
21
21
  inputSourceMap: isDev,
22
22
  presets: [
23
23
  [
24
- '@babel/preset-env',
24
+ require.resolve('@babel/preset-env'),
25
25
  {
26
26
  modules: opts.modules,
27
27
  useBuiltIns: 'entry',
@@ -33,7 +33,7 @@ module.exports = function getBabelConfig(opts = {}) {
33
33
  ].filter(Boolean),
34
34
  plugins: [
35
35
  [
36
- '@babel/plugin-transform-runtime',
36
+ require.resolve('@babel/plugin-transform-runtime'),
37
37
  {
38
38
  corejs: false,
39
39
  helpers: true,
@@ -49,7 +49,7 @@ module.exports = function getBabelConfig(opts = {}) {
49
49
  },
50
50
  ],
51
51
  [
52
- 'import',
52
+ require.resolve('babel-plugin-import'),
53
53
  { libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false },
54
54
  'lodash',
55
55
  ],
@@ -31,7 +31,7 @@ module.exports = function getBabelConfig(opts = {}) {
31
31
  configFile: false,
32
32
  presets: [
33
33
  [
34
- '@babel/preset-env',
34
+ require.resolve('@babel/preset-env'),
35
35
  {
36
36
  modules: opts.modules,
37
37
  useBuiltIns: 'entry',
@@ -41,18 +41,18 @@ module.exports = function getBabelConfig(opts = {}) {
41
41
  },
42
42
  ],
43
43
  [
44
- '@babel/preset-react',
44
+ require.resolve('@babel/preset-react'),
45
45
  {
46
46
  development: isDev,
47
47
  runtime: hasJsxRuntime ? 'automatic' : 'classic',
48
48
  useBuiltIns: !hasJsxRuntime,
49
49
  },
50
50
  ],
51
- isTypeScriptEnabled && '@babel/preset-typescript',
51
+ isTypeScriptEnabled && require.resolve('@babel/preset-typescript'),
52
52
  ].filter(Boolean),
53
53
  plugins: [
54
54
  [
55
- '@babel/plugin-transform-runtime',
55
+ require.resolve('@babel/plugin-transform-runtime'),
56
56
  {
57
57
  corejs: false,
58
58
  helpers: true,
@@ -67,16 +67,13 @@ module.exports = function getBabelConfig(opts = {}) {
67
67
  // useESModules: true,
68
68
  },
69
69
  ],
70
- ['@babel/plugin-proposal-decorators', { legacy: true }],
71
- ['@babel/plugin-transform-class-properties', { loose: true }],
72
- ['@babel/plugin-transform-private-methods', { loose: true }],
73
- ['@babel/plugin-transform-private-property-in-object', { loose: true }],
70
+ [require.resolve('@babel/plugin-proposal-decorators'), { version: '2023-11' }],
74
71
  [
75
- 'import',
72
+ require.resolve('babel-plugin-import'),
76
73
  { libraryName: 'lodash', libraryDirectory: '', camel2DashComponentName: false },
77
74
  'lodash',
78
75
  ],
79
- isDev && 'react-refresh/babel',
76
+ isDev && require.resolve('react-refresh/babel'),
80
77
  addWebpackChunkName,
81
78
  ].filter(Boolean),
82
79
  }
@@ -0,0 +1,140 @@
1
+ /* eslint-disable no-restricted-globals */
2
+
3
+ /**
4
+ * @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL
5
+ * @returns {string}
6
+ */
7
+ function format(objURL) {
8
+ var protocol = objURL.protocol || ''
9
+ if (protocol && protocol.substr(-1) !== ':') {
10
+ protocol += ':'
11
+ }
12
+ var auth = objURL.auth || ''
13
+ if (auth) {
14
+ auth = encodeURIComponent(auth)
15
+ auth = auth.replace(/%3A/i, ':')
16
+ auth += '@'
17
+ }
18
+ var host = ''
19
+ if (objURL.hostname) {
20
+ host =
21
+ auth +
22
+ (objURL.hostname.indexOf(':') === -1 ? objURL.hostname : '['.concat(objURL.hostname, ']'))
23
+ if (objURL.port) {
24
+ host += ':'.concat(objURL.port)
25
+ }
26
+ }
27
+ var pathname = objURL.pathname || ''
28
+ if (objURL.slashes) {
29
+ host = '//'.concat(host || '')
30
+ if (pathname && pathname.charAt(0) !== '/') {
31
+ pathname = '/'.concat(pathname)
32
+ }
33
+ } else if (!host) {
34
+ host = ''
35
+ }
36
+ var search = objURL.search || ''
37
+ if (search && search.charAt(0) !== '?') {
38
+ search = '?'.concat(search)
39
+ }
40
+ var hash = objURL.hash || ''
41
+ if (hash && hash.charAt(0) !== '#') {
42
+ hash = '#'.concat(hash)
43
+ }
44
+ pathname = pathname.replace(
45
+ /[?#]/g,
46
+ /**
47
+ * @param {string} match
48
+ * @returns {string}
49
+ */
50
+ function (match) {
51
+ return encodeURIComponent(match)
52
+ }
53
+ )
54
+ search = search.replace('#', '%23')
55
+ return ''.concat(protocol).concat(host).concat(pathname).concat(search).concat(hash)
56
+ }
57
+
58
+ /**
59
+ * @param {URL & { fromCurrentScript?: boolean }} parsedURL
60
+ * @returns {string}
61
+ */
62
+ function createSocketURL(parsedURL) {
63
+ var hostname = parsedURL.hostname
64
+
65
+ // Node.js module parses it as `::`
66
+ // `new URL(urlString, [baseURLString])` parses it as '[::]'
67
+ var isInAddrAny = hostname === '0.0.0.0' || hostname === '::' || hostname === '[::]'
68
+
69
+ // why do we need this check?
70
+ // hostname n/a for file protocol (example, when using electron, ionic)
71
+ // see: https://github.com/webpack/webpack-dev-server/pull/384
72
+ if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf('http') === 0) {
73
+ hostname = self.location.hostname
74
+ }
75
+ var socketURLProtocol = parsedURL.protocol || self.location.protocol
76
+
77
+ // When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
78
+ if (
79
+ socketURLProtocol === 'auto:' ||
80
+ (hostname && isInAddrAny && self.location.protocol === 'https:')
81
+ ) {
82
+ socketURLProtocol = self.location.protocol
83
+ }
84
+ socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, 'ws')
85
+ var socketURLAuth = ''
86
+
87
+ // `new URL(urlString, [baseURLstring])` doesn't have `auth` property
88
+ // Parse authentication credentials in case we need them
89
+ if (parsedURL.username) {
90
+ socketURLAuth = parsedURL.username
91
+
92
+ // Since HTTP basic authentication does not allow empty username,
93
+ // we only include password if the username is not empty.
94
+ if (parsedURL.password) {
95
+ // Result: <username>:<password>
96
+ socketURLAuth = socketURLAuth.concat(':', parsedURL.password)
97
+ }
98
+ }
99
+
100
+ // In case the host is a raw IPv6 address, it can be enclosed in
101
+ // the brackets as the brackets are needed in the final URL string.
102
+ // Need to remove those as url.format blindly adds its own set of brackets
103
+ // if the host string contains colons. That would lead to non-working
104
+ // double brackets (e.g. [[::]]) host
105
+ //
106
+ // All of these web socket url params are optionally passed in through resourceQuery,
107
+ // so we need to fall back to the default if they are not provided
108
+ var socketURLHostname = (hostname || self.location.hostname || 'localhost').replace(
109
+ /^\[(.*)\]$/,
110
+ '$1'
111
+ )
112
+ var socketURLPort = parsedURL.port
113
+ if (!socketURLPort || socketURLPort === '0') {
114
+ socketURLPort = self.location.port
115
+ }
116
+
117
+ // If path is provided it'll be passed in via the resourceQuery as a
118
+ // query param so it has to be parsed out of the querystring in order for the
119
+ // client to open the socket to the correct location.
120
+ var socketURLPathname = '/ws'
121
+ if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
122
+ socketURLPathname = parsedURL.pathname
123
+
124
+ if (hostname.indexOf('zhidianbao.cn') > -1 || hostname.indexOf('qsban.cn') > -1) {
125
+ var ctx = self.location.pathname.split('/')[1]
126
+ if (ctx) {
127
+ socketURLPathname = '/' + ctx + socketURLPathname
128
+ }
129
+ }
130
+ }
131
+ return format({
132
+ protocol: socketURLProtocol,
133
+ auth: socketURLAuth,
134
+ hostname: socketURLHostname,
135
+ port: socketURLPort,
136
+ pathname: socketURLPathname,
137
+ slashes: true,
138
+ })
139
+ }
140
+ export default createSocketURL
@@ -9,7 +9,6 @@ const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
9
9
  const appPkg = require(paths.package)
10
10
  const appConfig = require('../utils/appConfig')
11
11
  const { ESBuildMinifyPlugin } = require('esbuild-loader')
12
- const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')
13
12
  const once = require('lodash/once')
14
13
 
15
14
  const jsMainPath = appConfig.grayscale
@@ -56,18 +55,18 @@ module.exports = function getWebpackConfig(args, override) {
56
55
  const getStyleLoaders = (cssOptions, preProcessor) => {
57
56
  const loaders = [
58
57
  {
59
- loader: 'style-loader',
58
+ loader: require.resolve('style-loader'),
60
59
  options: { attributes: { 'data-module': appPkg.name, 'data-version': appPkg.version } },
61
60
  },
62
61
  {
63
- loader: 'css-loader',
62
+ loader: require.resolve('css-loader'),
64
63
  options: cssOptions,
65
64
  },
66
65
  {
67
66
  // Options for PostCSS as we reference these options twice
68
67
  // Adds vendor prefixing based on your specified browser support in
69
68
  // package.json
70
- loader: 'postcss-loader',
69
+ loader: require.resolve('postcss-loader'),
71
70
  options: {
72
71
  postcssOptions: {
73
72
  // Necessary for external CSS imports to work
@@ -76,10 +75,10 @@ module.exports = function getWebpackConfig(args, override) {
76
75
  config: false,
77
76
  plugins: [
78
77
  isProd && require('cssnano')({ preset: 'default' }),
79
- fs.existsSync(paths.tailwind) && 'tailwindcss',
80
- 'postcss-flexbugs-fixes',
78
+ fs.existsSync(paths.tailwind) && require.resolve('tailwindcss'),
79
+ require.resolve('postcss-flexbugs-fixes'),
81
80
  [
82
- 'postcss-preset-env',
81
+ require.resolve('postcss-preset-env'),
83
82
  {
84
83
  autoprefixer: {
85
84
  flexbox: 'no-2009',
@@ -88,8 +87,8 @@ module.exports = function getWebpackConfig(args, override) {
88
87
  },
89
88
  ],
90
89
  isProd && require('./plugins/postcss-safe-area')(),
91
- isProd && ['postcss-momentum-scrolling', ['scroll', 'auto']],
92
- 'postcss-normalize',
90
+ isProd && [require.resolve('postcss-momentum-scrolling'), ['scroll', 'auto']],
91
+ require.resolve('postcss-normalize'),
93
92
  ...override.extraPostCSSPlugins,
94
93
  ].filter(Boolean),
95
94
  },
@@ -99,7 +98,7 @@ module.exports = function getWebpackConfig(args, override) {
99
98
  ]
100
99
  if (preProcessor === 'less-loader') {
101
100
  loaders.push({
102
- loader: 'less-loader',
101
+ loader: require.resolve('less-loader'),
103
102
  options: {
104
103
  lessOptions: {
105
104
  javascriptEnabled: true,
@@ -208,13 +207,13 @@ module.exports = function getWebpackConfig(args, override) {
208
207
  },
209
208
  {
210
209
  test: /\.(j|t)sx?$/,
211
- loader: 'babel-loader',
210
+ loader: require.resolve('babel-loader'),
212
211
  exclude: /node_modules/,
213
212
  options: require('./babel')(),
214
213
  },
215
214
  override.transformNodeModules && {
216
215
  test: /\.m?js$/,
217
- loader: 'babel-loader',
216
+ loader: require.resolve('babel-loader'),
218
217
  exclude: /@babel(?:\/|\\{1,2})runtime/,
219
218
  options: require('./babel.dependencies')(),
220
219
  },
@@ -297,7 +296,7 @@ module.exports = function getWebpackConfig(args, override) {
297
296
  test: /\.svg$/,
298
297
  use: [
299
298
  {
300
- loader: '@svgr/webpack',
299
+ loader: require.resolve('@svgr/webpack'),
301
300
  options: {
302
301
  prettier: false,
303
302
  svgo: false,
@@ -309,7 +308,7 @@ module.exports = function getWebpackConfig(args, override) {
309
308
  },
310
309
  },
311
310
  {
312
- loader: 'url-loader',
311
+ loader: require.resolve('url-loader'),
313
312
  options: {
314
313
  limit: imageInlineSizeLimit,
315
314
  },
@@ -340,6 +339,11 @@ module.exports = function getWebpackConfig(args, override) {
340
339
  new webpack.DllReferencePlugin({
341
340
  manifest: require('../asset/dll/libcommon3-manifest.json'),
342
341
  }),
342
+ new webpack.NormalModuleReplacementPlugin(/createSocketURL\.js$/, (resource) => {
343
+ if (resource.context.includes('webpack-dev-server')) {
344
+ resource.request = require.resolve('./plugins/ws-utils-createSocketURL')
345
+ }
346
+ }),
343
347
  new webpack.IgnorePlugin({
344
348
  resourceRegExp: /^\.\/locale$/,
345
349
  contextRegExp: /moment$/,
@@ -349,8 +353,6 @@ module.exports = function getWebpackConfig(args, override) {
349
353
  'process.env.APP_VERSION': JSON.stringify(appPkg.version),
350
354
  'process.env.BABEL_ENV': JSON.stringify(process.env.BABEL_ENV),
351
355
  'process.env.BROWSERSLIST': JSON.stringify(process.env.BROWSERSLIST),
352
- 'process.env.WDS_SOCKET_HOST': JSON.stringify(process.env.WDS_SOCKET_HOST),
353
- 'process.env.WDS_SOCKET_PORT': JSON.stringify(process.env.WDS_SOCKET_PORT),
354
356
  ...override.define,
355
357
  }),
356
358
  new webpack.ProgressPlugin(),
@@ -394,18 +396,6 @@ module.exports = function getWebpackConfig(args, override) {
394
396
  optimization: {
395
397
  minimize: isProd && override.minify !== false,
396
398
  minimizer: [
397
- override.minifyImage &&
398
- new ImageMinimizerPlugin({
399
- minimizer: {
400
- implementation: ImageMinimizerPlugin.sharpMinify,
401
- options: {
402
- encodeOptions: {
403
- // Your options for `sharp`
404
- // https://sharp.pixelplumbing.com/api-output
405
- },
406
- },
407
- },
408
- }),
409
399
  override.minify === 'esbuild' &&
410
400
  new ESBuildMinifyPlugin({
411
401
  pure: override.pure_funcs ?? ['console.log'],
@@ -7,8 +7,6 @@ const setupMockServer = require('./plugins/mock-server')
7
7
  */
8
8
  module.exports = function getWebpackDevServerConfig(args, override) {
9
9
  const host = process.env.HOST || '0.0.0.0'
10
- const sockHost = process.env.WDS_SOCKET_HOST
11
- const sockPort = process.env.WDS_SOCKET_PORT
12
10
 
13
11
  /** @type {WebpackDevServer.Configuration} */
14
12
  const devServer = {
@@ -19,7 +17,7 @@ module.exports = function getWebpackDevServerConfig(args, override) {
19
17
  open: args.open,
20
18
  host,
21
19
  client: {
22
- webSocketURL: { protocol: 'auto:', hostname: sockHost, port: sockPort },
20
+ webSocketURL: 'auto://0.0.0.0:0/ws',
23
21
  overlay: {
24
22
  runtimeErrors: false,
25
23
  errors: true,
package/src/start.js CHANGED
@@ -15,15 +15,12 @@ const webpack = require('webpack')
15
15
  const getConfig = require('./utils/getConfig')
16
16
  const chalk = require('chalk')
17
17
 
18
- process.env.WDS_SOCKET_HOST = WebpackDevServer.internalIPSync('v4') || '127.0.0.1'
19
-
20
18
  module.exports = async function start(args) {
21
19
  const basePort = process.env.WEBPACK_DEV_SERVER_BASE_PORT
22
20
  const port = await WebpackDevServer.getFreePort(args.port || process.env.PORT)
23
21
  if (!(args.port || process.env.PORT) && +port !== +basePort) {
24
22
  console.log(chalk.bgYellow(`${basePort} 端口已被占用,现切换到 ${port} 端口运行`))
25
23
  }
26
- process.env.WDS_SOCKET_PORT = port
27
24
  args.port = port
28
25
  process.env.PORT = port
29
26
 
@@ -50,6 +50,11 @@ function printFileSizesAfterBuild(
50
50
  })
51
51
  )
52
52
  .reduce((single, all) => all.concat(single), [])
53
+
54
+ if (assets.length === 0) return
55
+
56
+ console.log('\ngzip 后文件大小:\n')
57
+
53
58
  assets.sort((a, b) => b.size - a.size)
54
59
 
55
60
  // move main file to first
@@ -91,6 +96,8 @@ function printFileSizesAfterBuild(
91
96
  console.log(chalk.yellow('考虑下使用代码分割解决'))
92
97
  console.log(chalk.yellow('也可以使用 npm run analyze 命令分析产物'))
93
98
  }
99
+
100
+ console.log()
94
101
  }
95
102
 
96
103
  function removeFileNameHash(buildFolder, fileName) {
@@ -29,5 +29,20 @@ module.exports = function getOverride() {
29
29
 
30
30
  if (override.minify === true) override.minify = defaultOverride.minify
31
31
 
32
+ if (override.babel) {
33
+ const old = override.babel
34
+ override.babel = (config, context) => {
35
+ const newConfig = old(config, context) || config
36
+
37
+ let plugin = config.plugins.find(
38
+ (plugin) => Array.isArray(plugin) && /^(babel-plugin-)?import$/.test(plugin[0])
39
+ )
40
+ if (plugin) {
41
+ plugin[0] = require.resolve('babel-plugin-import')
42
+ }
43
+ return newConfig
44
+ }
45
+ }
46
+
32
47
  return override
33
48
  }