perf: 精简打包体积,砍掉从未被使用的 Piper 引擎和渲染层专用依赖
排查确认两处真实浪费: 1. resources/tts/piper/ 里除 espeak-ng-data 外的所有文件(Piper 神经 语音模型、二进制、自带 onnxruntime、phonemize 库、tashkeel 阿拉伯语 音标模型,合计 ~113M)从未被实际调用——detectBackend() 第一优先级 永远命中 VITS(小雅),Piper 引擎分支代码走不到,只有它 bundle 里的 espeak-ng-data 目录被 VITS 借用当 sherpa-onnx 校验的 dataDir。 systemTts.ts 新增 findPiperEspeakDataDir(),VITS 分支改为只依赖这一 个子目录,不再要求 Piper 引擎的 bin/model/config 存在。 2. electron-builder.config.ts 的 files 补充排除 onnxruntime-web( @huggingface/transformers 的硬依赖但项目强制走 onnxruntime-node, 完全未用)、naive-ui/date-fns/highlight.js/lodash 系(只在 src/renderer/ 被引用,electron-vite build 时已被 Vite 打包进 out/renderer/*.js,主进程不需要原始 node_modules),约省 227M。 两项合计预计单包体积从 ~789M 降到 ~560M 左右,待真机重新打包安装、 实际听一次语音播报确认功能未受影响。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
b512857629
commit
d512ad41f9
@ -28,7 +28,22 @@ const config: Configuration = {
|
||||
},
|
||||
// resources/icon.png 单独列出:src/main/index.ts 用相对路径 __dirname/../../resources/icon.png
|
||||
// 定位窗口图标(打包后 __dirname 是 <app>/out/main),必须让它落在 <app>/resources/ 下
|
||||
files: ['out/**/*', 'resources/icon.png'],
|
||||
//
|
||||
// 排除项:这几个包只在 src/renderer/ 被引用,electron-vite build 时已经被 Vite
|
||||
// 静态打包进 out/renderer/*.js,主进程运行时不会去 node_modules 里 require 它们;
|
||||
// onnxruntime-web 是 @huggingface/transformers 的硬依赖但项目强制走 onnxruntime-node,
|
||||
// 从未被使用。排除后单包体积减少约 227M(naive-ui/date-fns/highlight.js/lodash 系
|
||||
// 渲染层已打包、onnxruntime-web 完全未用,详见排查记录)。
|
||||
files: [
|
||||
'out/**/*',
|
||||
'resources/icon.png',
|
||||
'!node_modules/onnxruntime-web/**',
|
||||
'!node_modules/naive-ui/**',
|
||||
'!node_modules/date-fns/**',
|
||||
'!node_modules/highlight.js/**',
|
||||
'!node_modules/lodash/**',
|
||||
'!node_modules/lodash-es/**'
|
||||
],
|
||||
asarUnpack: [
|
||||
'node_modules/@lancedb/**',
|
||||
'node_modules/apache-arrow/**',
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,487 +0,0 @@
|
||||
{
|
||||
"audio": {
|
||||
"sample_rate": 22050,
|
||||
"quality": "medium"
|
||||
},
|
||||
"espeak": {
|
||||
"voice": "cmn"
|
||||
},
|
||||
"inference": {
|
||||
"noise_scale": 0.667,
|
||||
"length_scale": 1,
|
||||
"noise_w": 0.8
|
||||
},
|
||||
"phoneme_type": "espeak",
|
||||
"phoneme_map": {},
|
||||
"phoneme_id_map": {
|
||||
"_": [
|
||||
0
|
||||
],
|
||||
"^": [
|
||||
1
|
||||
],
|
||||
"$": [
|
||||
2
|
||||
],
|
||||
" ": [
|
||||
3
|
||||
],
|
||||
"!": [
|
||||
4
|
||||
],
|
||||
"'": [
|
||||
5
|
||||
],
|
||||
"(": [
|
||||
6
|
||||
],
|
||||
")": [
|
||||
7
|
||||
],
|
||||
",": [
|
||||
8
|
||||
],
|
||||
"-": [
|
||||
9
|
||||
],
|
||||
".": [
|
||||
10
|
||||
],
|
||||
":": [
|
||||
11
|
||||
],
|
||||
";": [
|
||||
12
|
||||
],
|
||||
"?": [
|
||||
13
|
||||
],
|
||||
"a": [
|
||||
14
|
||||
],
|
||||
"b": [
|
||||
15
|
||||
],
|
||||
"c": [
|
||||
16
|
||||
],
|
||||
"d": [
|
||||
17
|
||||
],
|
||||
"e": [
|
||||
18
|
||||
],
|
||||
"f": [
|
||||
19
|
||||
],
|
||||
"h": [
|
||||
20
|
||||
],
|
||||
"i": [
|
||||
21
|
||||
],
|
||||
"j": [
|
||||
22
|
||||
],
|
||||
"k": [
|
||||
23
|
||||
],
|
||||
"l": [
|
||||
24
|
||||
],
|
||||
"m": [
|
||||
25
|
||||
],
|
||||
"n": [
|
||||
26
|
||||
],
|
||||
"o": [
|
||||
27
|
||||
],
|
||||
"p": [
|
||||
28
|
||||
],
|
||||
"q": [
|
||||
29
|
||||
],
|
||||
"r": [
|
||||
30
|
||||
],
|
||||
"s": [
|
||||
31
|
||||
],
|
||||
"t": [
|
||||
32
|
||||
],
|
||||
"u": [
|
||||
33
|
||||
],
|
||||
"v": [
|
||||
34
|
||||
],
|
||||
"w": [
|
||||
35
|
||||
],
|
||||
"x": [
|
||||
36
|
||||
],
|
||||
"y": [
|
||||
37
|
||||
],
|
||||
"z": [
|
||||
38
|
||||
],
|
||||
"æ": [
|
||||
39
|
||||
],
|
||||
"ç": [
|
||||
40
|
||||
],
|
||||
"ð": [
|
||||
41
|
||||
],
|
||||
"ø": [
|
||||
42
|
||||
],
|
||||
"ħ": [
|
||||
43
|
||||
],
|
||||
"ŋ": [
|
||||
44
|
||||
],
|
||||
"œ": [
|
||||
45
|
||||
],
|
||||
"ǀ": [
|
||||
46
|
||||
],
|
||||
"ǁ": [
|
||||
47
|
||||
],
|
||||
"ǂ": [
|
||||
48
|
||||
],
|
||||
"ǃ": [
|
||||
49
|
||||
],
|
||||
"ɐ": [
|
||||
50
|
||||
],
|
||||
"ɑ": [
|
||||
51
|
||||
],
|
||||
"ɒ": [
|
||||
52
|
||||
],
|
||||
"ɓ": [
|
||||
53
|
||||
],
|
||||
"ɔ": [
|
||||
54
|
||||
],
|
||||
"ɕ": [
|
||||
55
|
||||
],
|
||||
"ɖ": [
|
||||
56
|
||||
],
|
||||
"ɗ": [
|
||||
57
|
||||
],
|
||||
"ɘ": [
|
||||
58
|
||||
],
|
||||
"ə": [
|
||||
59
|
||||
],
|
||||
"ɚ": [
|
||||
60
|
||||
],
|
||||
"ɛ": [
|
||||
61
|
||||
],
|
||||
"ɜ": [
|
||||
62
|
||||
],
|
||||
"ɞ": [
|
||||
63
|
||||
],
|
||||
"ɟ": [
|
||||
64
|
||||
],
|
||||
"ɠ": [
|
||||
65
|
||||
],
|
||||
"ɡ": [
|
||||
66
|
||||
],
|
||||
"ɢ": [
|
||||
67
|
||||
],
|
||||
"ɣ": [
|
||||
68
|
||||
],
|
||||
"ɤ": [
|
||||
69
|
||||
],
|
||||
"ɥ": [
|
||||
70
|
||||
],
|
||||
"ɦ": [
|
||||
71
|
||||
],
|
||||
"ɧ": [
|
||||
72
|
||||
],
|
||||
"ɨ": [
|
||||
73
|
||||
],
|
||||
"ɪ": [
|
||||
74
|
||||
],
|
||||
"ɫ": [
|
||||
75
|
||||
],
|
||||
"ɬ": [
|
||||
76
|
||||
],
|
||||
"ɭ": [
|
||||
77
|
||||
],
|
||||
"ɮ": [
|
||||
78
|
||||
],
|
||||
"ɯ": [
|
||||
79
|
||||
],
|
||||
"ɰ": [
|
||||
80
|
||||
],
|
||||
"ɱ": [
|
||||
81
|
||||
],
|
||||
"ɲ": [
|
||||
82
|
||||
],
|
||||
"ɳ": [
|
||||
83
|
||||
],
|
||||
"ɴ": [
|
||||
84
|
||||
],
|
||||
"ɵ": [
|
||||
85
|
||||
],
|
||||
"ɶ": [
|
||||
86
|
||||
],
|
||||
"ɸ": [
|
||||
87
|
||||
],
|
||||
"ɹ": [
|
||||
88
|
||||
],
|
||||
"ɺ": [
|
||||
89
|
||||
],
|
||||
"ɻ": [
|
||||
90
|
||||
],
|
||||
"ɽ": [
|
||||
91
|
||||
],
|
||||
"ɾ": [
|
||||
92
|
||||
],
|
||||
"ʀ": [
|
||||
93
|
||||
],
|
||||
"ʁ": [
|
||||
94
|
||||
],
|
||||
"ʂ": [
|
||||
95
|
||||
],
|
||||
"ʃ": [
|
||||
96
|
||||
],
|
||||
"ʄ": [
|
||||
97
|
||||
],
|
||||
"ʈ": [
|
||||
98
|
||||
],
|
||||
"ʉ": [
|
||||
99
|
||||
],
|
||||
"ʊ": [
|
||||
100
|
||||
],
|
||||
"ʋ": [
|
||||
101
|
||||
],
|
||||
"ʌ": [
|
||||
102
|
||||
],
|
||||
"ʍ": [
|
||||
103
|
||||
],
|
||||
"ʎ": [
|
||||
104
|
||||
],
|
||||
"ʏ": [
|
||||
105
|
||||
],
|
||||
"ʐ": [
|
||||
106
|
||||
],
|
||||
"ʑ": [
|
||||
107
|
||||
],
|
||||
"ʒ": [
|
||||
108
|
||||
],
|
||||
"ʔ": [
|
||||
109
|
||||
],
|
||||
"ʕ": [
|
||||
110
|
||||
],
|
||||
"ʘ": [
|
||||
111
|
||||
],
|
||||
"ʙ": [
|
||||
112
|
||||
],
|
||||
"ʛ": [
|
||||
113
|
||||
],
|
||||
"ʜ": [
|
||||
114
|
||||
],
|
||||
"ʝ": [
|
||||
115
|
||||
],
|
||||
"ʟ": [
|
||||
116
|
||||
],
|
||||
"ʡ": [
|
||||
117
|
||||
],
|
||||
"ʢ": [
|
||||
118
|
||||
],
|
||||
"ʲ": [
|
||||
119
|
||||
],
|
||||
"ˈ": [
|
||||
120
|
||||
],
|
||||
"ˌ": [
|
||||
121
|
||||
],
|
||||
"ː": [
|
||||
122
|
||||
],
|
||||
"ˑ": [
|
||||
123
|
||||
],
|
||||
"˞": [
|
||||
124
|
||||
],
|
||||
"β": [
|
||||
125
|
||||
],
|
||||
"θ": [
|
||||
126
|
||||
],
|
||||
"χ": [
|
||||
127
|
||||
],
|
||||
"ᵻ": [
|
||||
128
|
||||
],
|
||||
"ⱱ": [
|
||||
129
|
||||
],
|
||||
"0": [
|
||||
130
|
||||
],
|
||||
"1": [
|
||||
131
|
||||
],
|
||||
"2": [
|
||||
132
|
||||
],
|
||||
"3": [
|
||||
133
|
||||
],
|
||||
"4": [
|
||||
134
|
||||
],
|
||||
"5": [
|
||||
135
|
||||
],
|
||||
"6": [
|
||||
136
|
||||
],
|
||||
"7": [
|
||||
137
|
||||
],
|
||||
"8": [
|
||||
138
|
||||
],
|
||||
"9": [
|
||||
139
|
||||
],
|
||||
"̧": [
|
||||
140
|
||||
],
|
||||
"̃": [
|
||||
141
|
||||
],
|
||||
"̪": [
|
||||
142
|
||||
],
|
||||
"̯": [
|
||||
143
|
||||
],
|
||||
"̩": [
|
||||
144
|
||||
],
|
||||
"ʰ": [
|
||||
145
|
||||
],
|
||||
"ˤ": [
|
||||
146
|
||||
],
|
||||
"ε": [
|
||||
147
|
||||
],
|
||||
"↓": [
|
||||
148
|
||||
],
|
||||
"#": [
|
||||
149
|
||||
],
|
||||
"\"": [
|
||||
150
|
||||
],
|
||||
"↑": [
|
||||
151
|
||||
]
|
||||
},
|
||||
"num_symbols": 256,
|
||||
"num_speakers": 1,
|
||||
"speaker_id_map": {},
|
||||
"piper_version": "1.0.0",
|
||||
"language": {
|
||||
"code": "zh_CN",
|
||||
"family": "zh",
|
||||
"region": "CN",
|
||||
"name_native": "简体中文",
|
||||
"name_english": "Chinese",
|
||||
"country_english": "China"
|
||||
},
|
||||
"dataset": "huayan"
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -122,6 +122,25 @@ function findBundledVits(): string | null {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* VITS(小雅)的 sherpa-onnx 校验要求指定一个 espeak-ng-data 目录,历史上直接复用
|
||||
* Piper bundle 里的那份数据。Piper 自己的引擎(模型/二进制/onnxruntime/phonemize)
|
||||
* 在有 VITS 时永远不会被实际调用(detectBackend 第一优先级永远命中 VITS),
|
||||
* 所以只保留 piper/espeak-ng-data 这一个子目录,不要求整套 Piper 引擎存在。
|
||||
*/
|
||||
function findPiperEspeakDataDir(): string | null {
|
||||
const candidates = [
|
||||
join(process.resourcesPath, 'tts', 'piper'),
|
||||
join(__dirname, '..', '..', 'resources', 'tts', 'piper'),
|
||||
process.env.TTS_BUNDLE_DIR ? join(process.env.TTS_BUNDLE_DIR, 'piper') : ''
|
||||
].filter(Boolean)
|
||||
|
||||
for (const dir of candidates) {
|
||||
if (existsSync(join(dir, 'espeak-ng-data'))) return dir
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function findBundledEspeakNg(): string | null {
|
||||
const candidates = [
|
||||
join(process.resourcesPath, 'tts', 'espeak-ng'),
|
||||
@ -303,15 +322,13 @@ function detectBackend(): Promise<Backend | null> {
|
||||
if (detectedBackendPromise) return detectedBackendPromise
|
||||
detectedBackendPromise = (async () => {
|
||||
// 1. 优先使用内嵌 sherpa-onnx VITS 小雅模型(BZNSYP 标准普通话)。
|
||||
// 依赖 Piper bundle 里的 espeak-ng-data 作为 dataDir(sherpa-onnx 校验需要)。
|
||||
// 依赖 Piper bundle 里的 espeak-ng-data 作为 dataDir(sherpa-onnx 校验需要),
|
||||
// 不需要 Piper 引擎本身(bin/model/config),见 findPiperEspeakDataDir 注释。
|
||||
const bundledVits = findBundledVits()
|
||||
const piperForData = findBundledPiper()
|
||||
if (bundledVits && piperForData) {
|
||||
const piperDataDir = findPiperEspeakDataDir()
|
||||
if (bundledVits && piperDataDir) {
|
||||
bundledVitsDir = bundledVits
|
||||
bundledPiperBin = piperForData.bin
|
||||
bundledPiperDir = piperForData.dir
|
||||
bundledPiperModel = piperForData.model
|
||||
bundledPiperConfig = piperForData.config
|
||||
bundledPiperDir = piperDataDir
|
||||
detectedBackend = 'bundled-vits'
|
||||
console.log('[systemTts] detected backend:', detectedBackend, 'at', bundledVitsDir)
|
||||
return detectedBackend
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user