@qse/edu-scripts 1.14.17 → 2.0.0

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.
Files changed (92) hide show
  1. package/CHANGELOG.md +2 -483
  2. package/asset/rspack-dev-server-client.js +534 -0
  3. package/{src/asset → asset}/template/edu-scripts.override.js.tpl +2 -2
  4. package/{lib/asset → asset}/template/tailwind.config.js.tpl +1 -1
  5. package/babel.config.json +6 -0
  6. package/dist/cli.d.mts +1 -0
  7. package/dist/cli.mjs +1426 -0
  8. package/dist/index.d.mts +83 -0
  9. package/dist/index.mjs +13 -0
  10. package/eslint.config.mjs +3 -0
  11. package/{jest.config.js → jest.config.mjs} +8 -4
  12. package/package.json +52 -57
  13. package/src/{auto-refactor.js → auto-refactor.ts} +51 -59
  14. package/src/{build.js → build.ts} +22 -16
  15. package/src/{cli.js → cli.ts} +25 -21
  16. package/src/{commit-dist.js → commit-dist.ts} +28 -21
  17. package/src/config/paths.ts +52 -0
  18. package/src/config/plugins/mock-server/{index.js → index.ts} +30 -41
  19. package/src/config/plugins/{postcss-safe-area.js → postcss-safe-area.ts} +4 -2
  20. package/src/config/{webpackConfig.js → webpackConfig.ts} +152 -126
  21. package/src/config/{webpackDevServerConfig.js → webpackDevServerConfig.ts} +18 -18
  22. package/src/{deploy.js → deploy.ts} +36 -25
  23. package/src/{generator.js → generator.ts} +5 -14
  24. package/src/start.ts +52 -0
  25. package/src/utils/FileSizeReporter.ts +166 -0
  26. package/src/utils/{appConfig.js → appConfig.ts} +5 -4
  27. package/src/utils/{beforeStart.js → beforeStart.ts} +18 -29
  28. package/src/utils/{changeDeployVersion.js → changeDeployVersion.ts} +43 -48
  29. package/src/utils/defineConfig.ts +19 -36
  30. package/src/utils/{exec.js → exec.ts} +3 -3
  31. package/src/utils/{getConfig.js → getConfig.ts} +7 -5
  32. package/src/utils/getOverride.ts +32 -0
  33. package/src/utils/resolveModule.ts +3 -0
  34. package/tsconfig.json +3 -15
  35. package/tsdown.config.ts +5 -0
  36. package/docs/changelog.md +0 -5
  37. package/docs/debug.md +0 -17
  38. package/docs/deploy.md +0 -54
  39. package/docs/faq.md +0 -144
  40. package/docs/feat.md +0 -167
  41. package/docs/grayscale.md +0 -31
  42. package/docs/index.md +0 -5
  43. package/docs/mode.md +0 -42
  44. package/docs/override.md +0 -193
  45. package/docs/refactor-react-16.md +0 -37
  46. package/docs/refactor.md +0 -67
  47. package/docs/static.md +0 -24
  48. package/lib/asset/template/edu-scripts.override.js.tpl +0 -7
  49. package/lib/auto-refactor.js +0 -151
  50. package/lib/build.js +0 -59
  51. package/lib/cli.js +0 -66
  52. package/lib/commit-dist.js +0 -79
  53. package/lib/config/babel.dependencies.js +0 -79
  54. package/lib/config/babel.js +0 -107
  55. package/lib/config/paths.js +0 -36
  56. package/lib/config/plugins/babel-plugin-add-webpack-chunk-name.js +0 -31
  57. package/lib/config/plugins/mock-server/defineMock.d.ts +0 -6
  58. package/lib/config/plugins/mock-server/defineMock.js +0 -31
  59. package/lib/config/plugins/mock-server/index.js +0 -122
  60. package/lib/config/plugins/postcss-safe-area.js +0 -19
  61. package/lib/config/plugins/ws-utils-createSocketURL.js +0 -118
  62. package/lib/config/webpackConfig.js +0 -462
  63. package/lib/config/webpackDevServerConfig.js +0 -72
  64. package/lib/deploy.js +0 -143
  65. package/lib/generator.js +0 -50
  66. package/lib/index.d.ts +0 -2
  67. package/lib/index.js +0 -32
  68. package/lib/start.js +0 -36
  69. package/lib/utils/FileSizeReporter.js +0 -107
  70. package/lib/utils/appConfig.js +0 -32
  71. package/lib/utils/beforeStart.js +0 -62
  72. package/lib/utils/changeDeployVersion.js +0 -89
  73. package/lib/utils/defineConfig.d.ts +0 -93
  74. package/lib/utils/defineConfig.js +0 -31
  75. package/lib/utils/exec.js +0 -7
  76. package/lib/utils/getConfig.js +0 -20
  77. package/lib/utils/getOverride.js +0 -61
  78. package/src/asset/dll/libcommon3-manifest.json +0 -181
  79. package/src/asset/template/edu-app-env.d.ts.tpl +0 -20
  80. package/src/asset/template/tailwind.config.js.tpl +0 -11
  81. package/src/asset/template/tsconfig.json.tpl +0 -24
  82. package/src/config/babel.dependencies.js +0 -66
  83. package/src/config/babel.js +0 -94
  84. package/src/config/paths.js +0 -38
  85. package/src/config/plugins/babel-plugin-add-webpack-chunk-name.js +0 -55
  86. package/src/config/plugins/ws-utils-createSocketURL.js +0 -140
  87. package/src/start.js +0 -44
  88. package/src/utils/FileSizeReporter.js +0 -151
  89. package/src/utils/getOverride.js +0 -48
  90. /package/{lib/asset → asset}/dll/libcommon3-manifest.json +0 -0
  91. /package/{lib/asset → asset}/template/edu-app-env.d.ts.tpl +0 -0
  92. /package/{lib/asset → asset}/template/tsconfig.json.tpl +0 -0
package/src/start.ts ADDED
@@ -0,0 +1,52 @@
1
+ import { rspack } from '@rspack/core'
2
+ import { RspackDevServer } from '@rspack/dev-server'
3
+ import getConfig from './utils/getConfig.js'
4
+ import chalk from 'chalk'
5
+
6
+ interface StartArgs {
7
+ port?: string
8
+ }
9
+ export default async function start(args: StartArgs) {
10
+ process.env.NODE_ENV = 'development'
11
+ process.env.BABEL_ENV = 'development'
12
+ process.env.BROWSERSLIST = 'chrome >= 70'
13
+ process.env.WEBPACK_DEV_SERVER_BASE_PORT = '3000'
14
+ process.env.BROWSERSLIST_IGNORE_OLD_DATA = 'true'
15
+
16
+ const basePort = process.env.WEBPACK_DEV_SERVER_BASE_PORT
17
+ // @ts-ignore
18
+ const port = await RspackDevServer.getFreePort(args.port || process.env.PORT)
19
+ if (!(args.port || process.env.PORT) && +port !== +basePort) {
20
+ console.log(chalk.bgYellow(`${basePort} 端口已被占用,现切换到 ${port} 端口运行`))
21
+ }
22
+ args.port = port
23
+ process.env.PORT = port
24
+
25
+ const config = getConfig(args)
26
+ const compiler = rspack(config)
27
+ const middleware = rspack.lazyCompilationMiddleware(compiler)
28
+ const oldSetupMiddlewares = config.devServer!.setupMiddlewares
29
+ config.devServer!.setupMiddlewares = (middlewares: any, devServer: any) => {
30
+ if (oldSetupMiddlewares) {
31
+ middlewares = oldSetupMiddlewares(middlewares, devServer)
32
+ }
33
+ middlewares.unshift(middleware)
34
+ return middlewares
35
+ }
36
+ const devServer = new RspackDevServer(config.devServer!, compiler)
37
+ devServer.start()
38
+ ;['SIGINT', 'SIGTERM'].forEach(function (sig) {
39
+ process.on(sig, function () {
40
+ devServer.stop()
41
+ process.exit()
42
+ })
43
+ })
44
+
45
+ if (process.env.CI !== 'true') {
46
+ // Gracefully exit when stdin ends
47
+ process.stdin.on('end', function () {
48
+ devServer.stop()
49
+ process.exit()
50
+ })
51
+ }
52
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import fs from 'fs-extra'
9
+ import path from 'path'
10
+ import chalk from 'chalk'
11
+ import filesize from 'filesize'
12
+ // @ts-ignore
13
+ import recursive from 'recursive-readdir'
14
+ import stripAnsi from 'strip-ansi'
15
+ import { gzipSizeSync } from 'gzip-size'
16
+ import type { Stats } from '@rspack/core'
17
+
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 {
28
+ return (
29
+ /\.(js|css)$/.test(asset) &&
30
+ !/service-worker\.js/.test(asset) &&
31
+ !/precache-manifest\.[0-9a-f]+\.js/.test(asset)
32
+ )
33
+ }
34
+
35
+ // Prints a detailed summary of build files.
36
+ function printFileSizesAfterBuild(
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])
46
+ .map((stats) =>
47
+ stats
48
+ .toJson({ all: false, assets: true })
49
+ .assets!.filter((asset) => canReadAsset(asset.name))
50
+ .map((asset) => {
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)
55
+ return {
56
+ folder: path.join(path.basename(buildFolder), path.dirname(asset.name)),
57
+ name: path.basename(asset.name),
58
+ size: size,
59
+ sizeLabel: filesize(size) + (difference ? ' (' + difference + ')' : ''),
60
+ }
61
+ })
62
+ )
63
+ .reduce((single, all) => all.concat(single), [])
64
+
65
+ if (assets.length === 0) return
66
+
67
+ console.log('\ngzip 后文件大小:\n')
68
+
69
+ assets.sort((a, b) => b.size - a.size)
70
+
71
+ // move main file to first
72
+ const mainAssetIdx = assets.findIndex((asset) => /_\d+\.\d+\.\d+/.test(asset.name))
73
+ assets.unshift(assets.splice(mainAssetIdx, 1)[0])
74
+
75
+ const longestSizeLabelLength = Math.max.apply(
76
+ null,
77
+ assets.map((a) => stripAnsi(a.sizeLabel).length)
78
+ )
79
+ let suggestBundleSplitting = false
80
+ assets.forEach((asset) => {
81
+ let sizeLabel = asset.sizeLabel
82
+ const sizeLength = stripAnsi(sizeLabel).length
83
+ if (sizeLength < longestSizeLabelLength) {
84
+ const rightPadding = ' '.repeat(longestSizeLabelLength - sizeLength)
85
+ sizeLabel += rightPadding
86
+ }
87
+ const isMainBundle = /_\d+\.\d+\.\d+/.test(asset.name)
88
+ const maxRecommendedSize = isMainBundle ? maxBundleGzipSize : maxChunkGzipSize
89
+ const isLarge = maxRecommendedSize && asset.size > maxRecommendedSize
90
+ if (isLarge && path.extname(asset.name) === '.js') {
91
+ suggestBundleSplitting = true
92
+ }
93
+ console.log(
94
+ ' ' +
95
+ (isLarge ? chalk.yellow(sizeLabel) : sizeLabel) +
96
+ ' ' +
97
+ chalk.dim(asset.folder + path.sep) +
98
+ chalk.cyan(asset.name)
99
+ )
100
+ if (isMainBundle) {
101
+ console.log('')
102
+ }
103
+ })
104
+ if (suggestBundleSplitting) {
105
+ console.log()
106
+ console.log(
107
+ chalk.yellow(
108
+ `产物大小明显大于推荐的大小 (主文件 ${filesize(maxBundleGzipSize)}, chunk ${filesize(maxChunkGzipSize)}, 黄色标注为偏大)`
109
+ )
110
+ )
111
+ console.log(chalk.yellow('考虑下使用代码分割解决'))
112
+ console.log(chalk.yellow('也可以使用 npm run analyze 命令分析产物'))
113
+ }
114
+
115
+ console.log()
116
+ }
117
+
118
+ function removeFileNameHash(buildFolder: string, fileName: string): string {
119
+ return fileName
120
+ .replace(buildFolder, '')
121
+ .replace(/\\/g, '/')
122
+ .replace(/\/\d+\.\d+\.\d+\//, '/')
123
+ .replace(/\/?(.*)(\.[0-9a-f]+)(\.chunk)?(\.js|\.css)/, (match, p1, p2, p3, p4) => p1 + p4)
124
+ }
125
+
126
+ // Input: 1024, 2048
127
+ // Output: "(+1 KB)"
128
+ function getDifferenceLabel(currentSize: number, previousSize: number): string {
129
+ const FIFTY_KILOBYTES = 1024 * 50
130
+ const difference = currentSize - previousSize
131
+ const fileSize = !Number.isNaN(difference) ? filesize(difference) : 0
132
+ if (difference >= FIFTY_KILOBYTES) {
133
+ return chalk.red('+' + fileSize)
134
+ } else if (difference < FIFTY_KILOBYTES && difference > 0) {
135
+ return chalk.yellow('+' + fileSize)
136
+ } else if (difference < 0) {
137
+ return chalk.green(fileSize)
138
+ } else {
139
+ return ''
140
+ }
141
+ }
142
+
143
+ function measureFileSizesBeforeBuild(buildFolder: string): Promise<SizeMap> {
144
+ return new Promise((resolve) => {
145
+ recursive(buildFolder, (err: any, fileNames: any) => {
146
+ let sizes: Record<string, number> | undefined
147
+ if (!err && fileNames) {
148
+ sizes = fileNames.filter(canReadAsset).reduce(
149
+ (memo: any, fileName: any) => {
150
+ const contents = fs.readFileSync(fileName)
151
+ const key = removeFileNameHash(buildFolder, fileName)
152
+ memo[key] = gzipSizeSync(contents)
153
+ return memo
154
+ },
155
+ {} as Record<string, number>
156
+ )
157
+ }
158
+ resolve({
159
+ root: buildFolder,
160
+ sizes: sizes || {},
161
+ })
162
+ })
163
+ })
164
+ }
165
+
166
+ export { measureFileSizesBeforeBuild, printFileSizesAfterBuild }
@@ -1,6 +1,7 @@
1
- const paths = require('../config/paths')
2
- const appPkg = require(paths.package)
3
- const fs = require('fs')
1
+ import paths from '../config/paths'
2
+ import fs from 'fs-extra'
3
+
4
+ const appPkg = fs.readJsonSync(paths.package)
4
5
 
5
6
  const edu = appPkg.edu || {}
6
7
 
@@ -32,4 +33,4 @@ const appConfig = {
32
33
  },
33
34
  }
34
35
 
35
- module.exports = appConfig
36
+ export default appConfig
@@ -1,33 +1,11 @@
1
- const fs = require('fs')
2
- const paths = require('../config/paths')
3
- const chalk = require('chalk')
4
- const pkg = require('../../package.json')
5
- const updateNotifier = require('update-notifier')
6
- const semver = require('semver')
1
+ import fs from 'fs-extra'
2
+ import paths from '../config/paths'
3
+ import chalk from 'chalk'
4
+ import semver from 'semver'
5
+ import appConfig from './appConfig'
7
6
 
8
- const notifier = updateNotifier({
9
- pkg,
10
- shouldNotifyInNpmScript: true,
11
- updateCheckInterval: 1000 * 60, // 时刻保持更新
12
- })
13
- if (notifier.update && ['minor', 'major'].includes(notifier.update.type)) {
14
- const message =
15
- '发现新版本 ' +
16
- chalk.dim('{currentVersion}') +
17
- chalk.reset(' → ') +
18
- chalk.green('{latestVersion}') +
19
- ' \n运行 ' +
20
- chalk.cyan('{updateCommand}') +
21
- ' 进行更新\n\n' +
22
- chalk.bold.red('请始终保持最新版本\n') +
23
- '更新日志: ' +
24
- chalk.green(`${pkg.homepage}#/changelog`)
25
- notifier.notify({ message })
26
- process.exit(1)
27
- }
28
-
29
- const appPkg = require(paths.package)
30
- const appConfig = require('./appConfig')
7
+ const pkg = fs.readJsonSync(paths.resolveOwn('package.json'))
8
+ const appPkg = fs.readJsonSync(paths.package)
31
9
 
32
10
  if (semver.valid(appPkg.version) === null) {
33
11
  console.log(
@@ -73,3 +51,14 @@ if (appPkg.browserslist) {
73
51
  delete appPkg.browserslist
74
52
  fs.writeFileSync(paths.package, JSON.stringify(appPkg, null, 2), 'utf-8')
75
53
  }
54
+
55
+ if (appPkg.eslintConfig) {
56
+ console.log(
57
+ chalk.yellow('package.json 中 eslintConfig 已废弃,请改用 @qse/eslint-config 进行配置')
58
+ )
59
+ console.log(chalk.yellow('npm i eslint @qse/eslint-config -D'))
60
+ console.log()
61
+ console.log(chalk.gray('新建 eslint.config.mjs 文件,内容如下:'))
62
+ console.log(chalk.yellow('import config from "@qse/eslint-config"'))
63
+ console.log(chalk.yellow('export default config'))
64
+ }
@@ -1,28 +1,28 @@
1
- const t = require('@babel/types')
2
- const { parse } = require('@babel/parser')
3
- const generate = require('@babel/generator').default
4
- const traverse = require('@babel/traverse').default
5
- const { format } = require('prettier')
1
+ // @ts-nocheck
2
+ import { parse, traverse, types as t, transformFromAstSync } from '@babel/core'
6
3
 
7
4
  // ver.js 中定义模块的数组
8
5
  const TARGET_IDENTIFIER_NAME = 'project_apiArr'
9
6
  const MODULE_IDENTIFIER_NAME = 'module'
10
7
 
11
- 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 {
12
15
  const { name, version, grayscale } = pkg
13
16
  let ast
14
17
  try {
15
- ast = parse(code)
16
- } catch (error) {
17
- throw new Error(`代码解析错误: ${error.message}`)
18
+ ast = parse(code, { filename: 'ver.js' })
19
+ } catch (error: any) {
20
+ throw new Error(`代码解析错误: ${error.message}`, { cause: error })
18
21
  }
19
22
  const keyName = grayscale ? 'grayscale' : 'main'
20
23
 
21
- /**
22
- * @return {babel.NodePath<t.VariableDeclarator> | undefined}
23
- */
24
- function findTargetDeclarator(ast) {
25
- let res
24
+ function findTargetDeclarator(ast: any): any | undefined {
25
+ let res: any | undefined
26
26
 
27
27
  traverse(ast, {
28
28
  VariableDeclarator(path) {
@@ -38,18 +38,15 @@ function changeDeployVersion(code, pkg) {
38
38
  return res
39
39
  }
40
40
 
41
- /**
42
- * @param {babel.NodePath<t.VariableDeclarator>} path
43
- * @return {babel.NodePath<t.ObjectExpression> | undefined}
44
- */
45
- function findModuleObject(path) {
46
- let res
41
+ function findModuleObject(path: any): any | undefined {
42
+ let res: any | undefined
47
43
 
48
44
  path.traverse({
49
45
  ObjectExpression(path) {
50
46
  if (
51
47
  path.node.properties.some(
52
48
  (node) =>
49
+ t.isObjectProperty(node) &&
53
50
  t.isIdentifier(node.key, { name: MODULE_IDENTIFIER_NAME }) &&
54
51
  t.isLiteral(node.value, { value: name })
55
52
  )
@@ -62,15 +59,14 @@ function changeDeployVersion(code, pkg) {
62
59
  return res
63
60
  }
64
61
 
65
- /**
66
- * @param {babel.NodePath<t.ObjectExpression>} path
67
- */
68
- function modifyModuleVersion(path) {
62
+ function modifyModuleVersion(path: any): void {
69
63
  let hasModify = false
70
64
  path.traverse({
71
65
  Property(path) {
72
- if (path.node.key.name === keyName) {
73
- 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
+ }
74
70
  hasModify = true
75
71
  }
76
72
  },
@@ -80,10 +76,8 @@ function changeDeployVersion(code, pkg) {
80
76
  path.node.properties.push(t.objectProperty(t.identifier(keyName), t.stringLiteral(version)))
81
77
  }
82
78
  }
83
- /**
84
- * @param {babel.NodePath<t.ObjectExpression>} path
85
- */
86
- function deleteModuleComments(path) {
79
+
80
+ function deleteModuleComments(path: any): void {
87
81
  path.traverse({
88
82
  ObjectExpression(path) {
89
83
  delete path.node.leadingComments
@@ -91,19 +85,18 @@ function changeDeployVersion(code, pkg) {
91
85
  })
92
86
  }
93
87
 
94
- /**
95
- * @param {babel.NodePath<t.VariableDeclarator>} path
96
- */
97
- function addModuleToTarget(path) {
98
- const elements = path.node.init.elements
99
- elements.splice(
100
- elements.length - 2,
101
- 0,
102
- t.objectExpression([
103
- t.objectProperty(t.identifier(MODULE_IDENTIFIER_NAME), t.stringLiteral(name)),
104
- t.objectProperty(t.identifier(keyName), t.stringLiteral(version)),
105
- ])
106
- )
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
+ }
107
100
  }
108
101
 
109
102
  const targetPath = findTargetDeclarator(ast)
@@ -117,10 +110,12 @@ function changeDeployVersion(code, pkg) {
117
110
  }
118
111
  deleteModuleComments(targetPath)
119
112
 
120
- return format(generate(ast, { minified: true }).code, {
121
- parser: 'babel',
122
- printWidth: 120,
123
- })
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
124
119
  }
125
120
 
126
- module.exports = changeDeployVersion
121
+ export default changeDeployVersion
@@ -1,29 +1,17 @@
1
- import { Chalk } from 'chalk'
2
- import type { Compiler, Configuration } from 'webpack'
3
- import type { Configuration as DevServerConfiguration, ProxyConfigArray } from 'webpack-dev-server'
1
+ import type { Chalk } from 'chalk'
2
+ import type { Compiler, Configuration as RspackConfiguration, SwcLoaderOptions } from '@rspack/core'
3
+ import type { Configuration as DevServerConfiguration } from '@rspack/dev-server'
4
4
 
5
- export type BabelImportPlugin = [
6
- 'import',
7
- {
8
- libraryName: string
9
- libraryDirectory: string
10
- camel2DashComponentName?: boolean
11
- style?: boolean | 'css' | ((name: string) => string)
12
- },
13
- string
14
- ]
15
- export type BabelConfig = {
16
- presets: any[]
17
- plugins: (string | BabelImportPlugin | any[])[]
18
- }
5
+ type ProxyConfigArray = NonNullable<DevServerConfiguration['proxy']>
19
6
 
20
- export type Config = {
21
- webpack?: (config: Configuration) => Configuration | undefined
7
+ export type Configuration = {
8
+ webpack?: (config: RspackConfiguration) => RspackConfiguration | undefined
22
9
  devServer?: (config: DevServerConfiguration) => DevServerConfiguration | undefined
23
- babel?: (config: BabelConfig, type: 'src' | 'node_modules') => any | undefined
24
10
  /**
25
11
  * webpack alias 配置,会与内置 alias 合并
26
12
  *
13
+ * 会自动读取 tsconfig 里 baseUrl + paths 的配置
14
+ *
27
15
  * @default
28
16
  * { '@': './src' }
29
17
  */
@@ -38,22 +26,10 @@ export type Config = {
38
26
  */
39
27
  pure_funcs?: string[]
40
28
  /**
41
- * 编译 node_modules 下文件
42
- *
43
- * @default true
44
- */
45
- transformNodeModules?: boolean
46
- /**
47
- * 指定压缩工具,esbuild 比 terser 快 20-40 倍,实际压缩率差 10%左右
48
- *
49
- * @default 'esbuild'
50
- */
51
- minify?: boolean | 'terser' | 'esbuild'
52
- /**
53
- * 打包时压缩图片资源
29
+ * 是否压缩代码
54
30
  * @default true
55
31
  */
56
- minifyImage?: boolean
32
+ minify?: boolean
57
33
  /** 自定义全局参数 */
58
34
  define?: Record<string, any>
59
35
  /**
@@ -75,7 +51,7 @@ export type Config = {
75
51
  */
76
52
  mock?: boolean
77
53
  /**
78
- * 开发模式启动后只执行一次的函数,用来展示启动后的提示信息,或者自定义的逻辑
54
+ * 开发模式启动后用来展示启动后的提示信息,或者自定义的逻辑
79
55
  */
80
56
  startup?: (params: {
81
57
  /** 控制台输出内容 */
@@ -92,7 +68,14 @@ export type Config = {
92
68
  * @default false
93
69
  */
94
70
  decorators?: boolean
71
+ /**
72
+ * 与 babel-plugin-import 类似,但是内部是 rspack 重构,libraryDirectory 默认值是 lib
73
+ *
74
+ * @see https://rspack.rs/zh/guide/features/builtin-swc-loader#rspackexperimentsimport
75
+ * @default [{libraryName: 'lodash',libraryDirectory: '',camelToDashComponentName: false}]
76
+ */
77
+ import?: NonNullable<SwcLoaderOptions['rspackExperiments']>['import']
95
78
  }
96
- export function defineConfig(config: Config) {
79
+ export function defineConfig(config: Configuration) {
97
80
  return config
98
81
  }
@@ -1,7 +1,7 @@
1
- const cp = require('child_process')
2
- const exec = (cmd) => {
1
+ import cp from 'child_process'
2
+ const exec = (cmd: string) => {
3
3
  console.log(`> ${cmd}`)
4
4
  return cp.execSync(cmd, { stdio: 'inherit', encoding: 'utf-8' })
5
5
  }
6
6
 
7
- module.exports = exec
7
+ export default exec
@@ -1,8 +1,10 @@
1
- const getWebpackConfig = require('../config/webpackConfig')
2
- const getWebpackDevServerConfig = require('../config/webpackDevServerConfig')
3
- const getOverride = require('./getOverride')
1
+ // @ts-ignore
2
+ import getWebpackConfig from '../config/webpackConfig'
3
+ // @ts-ignore
4
+ import getWebpackDevServerConfig from '../config/webpackDevServerConfig'
5
+ import getOverride from './getOverride'
4
6
 
5
- function getConfig(args) {
7
+ function getConfig(args: any) {
6
8
  const override = getOverride()
7
9
 
8
10
  let webpackConfig = getWebpackConfig(args, override)
@@ -23,4 +25,4 @@ function getConfig(args) {
23
25
  return webpackConfig
24
26
  }
25
27
 
26
- module.exports = getConfig
28
+ export default getConfig
@@ -0,0 +1,32 @@
1
+ import fs from 'fs-extra'
2
+ import paths from '../config/paths'
3
+ import { createRequire } from 'node:module'
4
+ import { type Configuration } from './defineConfig'
5
+ import { resolveModule } from './resolveModule'
6
+
7
+ const require = createRequire(import.meta.url)
8
+
9
+ const defaultOverride: Configuration = {
10
+ minify: true,
11
+ proxy: [],
12
+ extraPostCSSPlugins: [],
13
+ import: [],
14
+ pure_funcs: ['console.log'],
15
+ }
16
+
17
+ let override: Configuration | null = null
18
+
19
+ export default function getOverride(): Configuration {
20
+ if (override) return override
21
+
22
+ override = Object.assign({}, defaultOverride)
23
+
24
+ if (fs.existsSync(paths.override)) {
25
+ const userOverride = resolveModule(require(paths.override))
26
+ if (typeof userOverride !== 'object')
27
+ throw new Error('格式错误,请使用 npx edu g override 生成文件')
28
+ Object.assign(override, userOverride)
29
+ }
30
+
31
+ return override
32
+ }
@@ -0,0 +1,3 @@
1
+ export function resolveModule(mod: any) {
2
+ return mod.default ? mod.default : mod
3
+ }
package/tsconfig.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "esnext",
4
- "module": "esnext",
5
- "moduleResolution": "node",
4
+ "module": "preserve",
5
+ "moduleResolution": "bundler",
6
6
  "importHelpers": true,
7
7
  "jsx": "react",
8
8
  "esModuleInterop": true,
@@ -11,22 +11,10 @@
11
11
  "strict": true,
12
12
  "paths": {
13
13
  "@/*": ["src/*"],
14
- "@@/*": ["src/.umi/*"]
15
14
  },
16
15
  "allowSyntheticDefaultImports": true,
17
16
  "skipLibCheck": true,
18
17
  "declaration": true
19
18
  },
20
- "exclude": [
21
- "node_modules",
22
- "lib",
23
- "es",
24
- "dist",
25
- "typings",
26
- "**/__test__",
27
- "test",
28
- "docs",
29
- "tests",
30
- "static"
31
- ]
19
+ "include": ["src", "scripts"]
32
20
  }
@@ -0,0 +1,5 @@
1
+ import { defineConfig } from 'tsdown'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts', 'src/cli.js'],
5
+ })
package/docs/changelog.md DELETED
@@ -1,5 +0,0 @@
1
- ---
2
- title: 更新日志
3
- ---
4
-
5
- <embed src="../CHANGELOG.md" />
package/docs/debug.md DELETED
@@ -1,17 +0,0 @@
1
- # 代码调试
2
-
3
- ## 使用 `React Developer Tools` 调试
4
-
5
- 1. 安装 `React Developer Tools` 插件
6
- 2. 打开控制台(F12)
7
- 3. 切换到 `Component` 标签页
8
- 4. 选中需要查看的组件,可以看到 `state/props/hooks` 等信息
9
-
10
- ## 使用 vscode 调试代码
11
-
12
- 1. 打开 `JavaScript Debug Terminal` 终端,输入 `npm run start` 命令启动项目。
13
-
14
- ![](https://p0.meituan.net/dpplatform/78a65449d74d1fbd61cc47e98c419a011041253.gif)
15
-
16
- 2. 按住 `ctrl/command` 点击 `http://localhost:port` 打开链接
17
- 3. 代码里打断点,网页点击触发断点