@qse/edu-scripts 1.15.0 → 2.0.1
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 +4 -489
- package/asset/rspack-dev-server-client.js +534 -0
- package/{src/asset → asset}/template/edu-scripts.override.js.tpl +2 -2
- package/{lib/asset → asset}/template/tailwind.config.js.tpl +1 -1
- package/babel.config.json +6 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +1432 -0
- package/dist/index.d.mts +83 -0
- package/dist/index.mjs +13 -0
- package/eslint.config.mjs +3 -0
- package/{jest.config.js → jest.config.mjs} +8 -4
- package/package.json +67 -67
- package/pnpm-workspace.yaml +2 -0
- package/src/{auto-refactor.js → auto-refactor.ts} +51 -59
- package/src/{build.js → build.ts} +22 -16
- package/src/{cli.js → cli.ts} +26 -21
- package/src/{commit-dist.js → commit-dist.ts} +28 -21
- package/src/config/paths.ts +52 -0
- package/src/config/plugins/mock-server/{index.js → index.ts} +30 -41
- package/src/config/plugins/{postcss-safe-area.js → postcss-safe-area.ts} +4 -2
- package/src/config/{webpackConfig.js → webpackConfig.ts} +157 -126
- package/src/config/{webpackDevServerConfig.js → webpackDevServerConfig.ts} +18 -18
- package/src/{deploy.js → deploy.ts} +36 -25
- package/src/{generator.js → generator.ts} +5 -14
- package/src/start.ts +52 -0
- package/src/utils/FileSizeReporter.ts +166 -0
- package/src/utils/{appConfig.js → appConfig.ts} +5 -4
- package/src/utils/{beforeStart.js → beforeStart.ts} +19 -7
- package/src/utils/{changeDeployVersion.js → changeDeployVersion.ts} +43 -48
- package/src/utils/defineConfig.ts +19 -36
- package/src/utils/esm-register.ts +6 -0
- package/src/utils/{exec.js → exec.ts} +3 -3
- package/src/utils/{getConfig.js → getConfig.ts} +7 -5
- package/src/utils/getOverride.ts +32 -0
- package/src/utils/resolveModule.ts +3 -0
- package/tsconfig.json +3 -15
- package/tsdown.config.ts +5 -0
- package/docs/changelog.md +0 -5
- package/docs/debug.md +0 -17
- package/docs/deploy.md +0 -54
- package/docs/faq.md +0 -144
- package/docs/feat.md +0 -167
- package/docs/grayscale.md +0 -31
- package/docs/index.md +0 -5
- package/docs/mode.md +0 -42
- package/docs/override.md +0 -193
- package/docs/refactor-react-16.md +0 -37
- package/docs/refactor.md +0 -67
- package/docs/static.md +0 -24
- package/lib/asset/template/edu-scripts.override.js.tpl +0 -7
- package/lib/auto-refactor.js +0 -151
- package/lib/build.js +0 -59
- package/lib/cli.js +0 -66
- package/lib/commit-dist.js +0 -79
- package/lib/config/babel.dependencies.js +0 -79
- package/lib/config/babel.js +0 -107
- package/lib/config/paths.js +0 -36
- package/lib/config/plugins/babel-plugin-add-webpack-chunk-name.js +0 -31
- package/lib/config/plugins/mock-server/defineMock.d.ts +0 -6
- package/lib/config/plugins/mock-server/defineMock.js +0 -31
- package/lib/config/plugins/mock-server/index.js +0 -122
- package/lib/config/plugins/postcss-safe-area.js +0 -19
- package/lib/config/plugins/ws-utils-createSocketURL.js +0 -118
- package/lib/config/webpackConfig.js +0 -462
- package/lib/config/webpackDevServerConfig.js +0 -72
- package/lib/deploy.js +0 -143
- package/lib/generator.js +0 -50
- package/lib/index.d.ts +0 -2
- package/lib/index.js +0 -32
- package/lib/start.js +0 -36
- package/lib/utils/FileSizeReporter.js +0 -107
- package/lib/utils/appConfig.js +0 -32
- package/lib/utils/beforeStart.js +0 -50
- package/lib/utils/changeDeployVersion.js +0 -89
- package/lib/utils/defineConfig.d.ts +0 -93
- package/lib/utils/defineConfig.js +0 -31
- package/lib/utils/exec.js +0 -7
- package/lib/utils/getConfig.js +0 -20
- package/lib/utils/getOverride.js +0 -61
- package/src/asset/dll/libcommon3-manifest.json +0 -181
- package/src/asset/template/edu-app-env.d.ts.tpl +0 -20
- package/src/asset/template/tailwind.config.js.tpl +0 -11
- package/src/asset/template/tsconfig.json.tpl +0 -24
- package/src/config/babel.dependencies.js +0 -66
- package/src/config/babel.js +0 -94
- package/src/config/paths.js +0 -38
- package/src/config/plugins/babel-plugin-add-webpack-chunk-name.js +0 -55
- package/src/config/plugins/ws-utils-createSocketURL.js +0 -140
- package/src/start.js +0 -44
- package/src/utils/FileSizeReporter.js +0 -151
- package/src/utils/getOverride.js +0 -48
- /package/{lib/asset → asset}/dll/libcommon3-manifest.json +0 -0
- /package/{lib/asset → asset}/template/edu-app-env.d.ts.tpl +0 -0
- /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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
36
|
+
export default appConfig
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
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'
|
|
6
|
+
|
|
7
|
+
const pkg = fs.readJsonSync(paths.resolveOwn('package.json'))
|
|
8
|
+
const appPkg = fs.readJsonSync(paths.package)
|
|
8
9
|
|
|
9
10
|
if (semver.valid(appPkg.version) === null) {
|
|
10
11
|
console.log(
|
|
@@ -50,3 +51,14 @@ if (appPkg.browserslist) {
|
|
|
50
51
|
delete appPkg.browserslist
|
|
51
52
|
fs.writeFileSync(paths.package, JSON.stringify(appPkg, null, 2), 'utf-8')
|
|
52
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
|
-
|
|
2
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
73
|
-
path.node.value
|
|
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
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
|
|
121
|
+
export default changeDeployVersion
|
|
@@ -1,29 +1,17 @@
|
|
|
1
|
-
import { Chalk } from 'chalk'
|
|
2
|
-
import type { Compiler, Configuration } from '
|
|
3
|
-
import type { Configuration as DevServerConfiguration
|
|
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
|
-
|
|
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
|
|
21
|
-
webpack?: (config:
|
|
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
|
-
*
|
|
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
|
-
|
|
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:
|
|
79
|
+
export function defineConfig(config: Configuration) {
|
|
97
80
|
return config
|
|
98
81
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
7
|
+
export default exec
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
|
|
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
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "esnext",
|
|
4
|
-
"module": "
|
|
5
|
-
"moduleResolution": "
|
|
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
|
-
"
|
|
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
|
}
|
package/tsdown.config.ts
ADDED
package/docs/changelog.md
DELETED
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
|
-

|
|
15
|
-
|
|
16
|
-
2. 按住 `ctrl/command` 点击 `http://localhost:port` 打开链接
|
|
17
|
-
3. 代码里打断点,网页点击触发断点
|