@flun/node-mobile-app 4.0.4 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,348 +1,347 @@
|
|
|
1
|
-
# Android 构建指南
|
|
2
|
-
|
|
3
|
-
本文档是 [README.md](./README.md) 的**深度附件**;日常使用(`test` / `build`)不需要看——CLI 自动处理;
|
|
4
|
-
|
|
5
|
-
本文档只讲四件事,都是 README 没细说的:
|
|
6
|
-
1. **环境准备**(JDK / SDK / NDK / adb / 原生模块编译)
|
|
7
|
-
2. **libnode.so**(v18 vs v22、预编译仓库、替换、full-icu 验证)
|
|
8
|
-
3. **Express 版本选择**(踩坑清单)
|
|
9
|
-
4. **调试与缓存排查**(logcat 命令、手动清缓存兜底)
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## 一、环境准备
|
|
14
|
-
|
|
15
|
-
### 1.1 JDK 17(必须)
|
|
16
|
-
|
|
17
|
-
Android Gradle Plugin 不支持 JDK 18+;
|
|
18
|
-
|
|
19
|
-
下载:[Adoptium JDK 17](https://adoptium.net/temurin/releases/?version=17)
|
|
20
|
-
|
|
21
|
-
**CLI 不读 `JAVA_HOME`**,直接用系统 PATH 里的 `java`;确保 `java -version` 输出是 17;
|
|
22
|
-
|
|
23
|
-
### 1.2 Android SDK
|
|
24
|
-
|
|
25
|
-
CLI 自动查找,顺序:
|
|
26
|
-
|
|
27
|
-
1. `mobileAppConfig.js` 的 `android.sdkPath`
|
|
28
|
-
2. 环境变量 `ANDROID_HOME` / `ANDROID_SDK_ROOT`
|
|
29
|
-
3. 常见默认路径(Windows:`%LOCALAPPDATA%\Android\Sdk`)
|
|
30
|
-
|
|
31
|
-
**必需组件**:
|
|
32
|
-
|
|
33
|
-
| 组件 | 版本
|
|
34
|
-
| -------------- |
|
|
35
|
-
| SDK Platform |
|
|
36
|
-
| Build-Tools |
|
|
37
|
-
| Platform-Tools |
|
|
38
|
-
| NDK |
|
|
39
|
-
|
|
40
|
-
### 1.3 adb
|
|
41
|
-
|
|
42
|
-
查找顺序同 SDK;常用命令:
|
|
43
|
-
|
|
44
|
-
```powershell
|
|
45
|
-
$adb = "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe"
|
|
46
|
-
& $adb devices
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 1.4 原生模块编译(自动检测)
|
|
50
|
-
|
|
51
|
-
CLI 会扫描 `<buildDir>/nodejs-assets/nodejs-project/node_modules/` 下是否有 `binding.gyp` 文件(原生模块的标志),自动写:
|
|
52
|
-
|
|
53
|
-
```
|
|
54
|
-
<buildDir>/nodejs-assets/BUILD_NATIVE_MODULES.txt # 1=有原生模块,0=无
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
- **检测到原生模块**(如 `bcrypt`、`sqlite3`):写 `1`,并设环境变量 `NODEJS_MOBILE_BUILD_NATIVE_MODULES=1`,`npm install` 时自动重编
|
|
58
|
-
- **未检测到**:写 `0`,跳过编译
|
|
59
|
-
|
|
60
|
-
**用户无需手动配置**;检测结果会纳入依赖哈希,装/卸原生模块时会自动触发重装重编;
|
|
61
|
-
|
|
62
|
-
**手动强制重编**:换过 `libnode.so` 但依赖没变、需要重新编译原生模块时:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
# Linux / macOS
|
|
66
|
-
NODE_MOBILE_FORCE_REBUILD=1 npx node-mobile-app test
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
```powershell
|
|
70
|
-
# Windows
|
|
71
|
-
$env:NODE_MOBILE_FORCE_REBUILD=1; npx node-mobile-app test
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## 二、libnode.so
|
|
79
|
-
|
|
80
|
-
`nodejs-mobile-react-native` 用它提供 Node.js 运行时;**是否带 full-icu** 决定能跑哪个 Express 版本;
|
|
81
|
-
|
|
82
|
-
### 2.0 预编译二进制怎么来的
|
|
83
|
-
|
|
84
|
-
从 `@flun/nodejs-mobile-react-native` 1.0.1 起,`libnode.so` **不在 npm 包里**,安装时由 postinstall 脚本从 Gitee / GitHub Release 自动下载:
|
|
85
|
-
|
|
86
|
-
- **下载源**:Gitee 优先,失败自动回退 GitHub
|
|
87
|
-
- **下载内容**:`android-libnode.zip
|
|
88
|
-
- **覆盖目标**:`node_modules/@flun/nodejs-mobile-react-native/android/libnode/`
|
|
89
|
-
- **幂等**:已装版本匹配则跳过,不重复下载
|
|
90
|
-
- **失败处理**:全部源失败时打印下载链接,不中断 npm 安装
|
|
91
|
-
|
|
92
|
-
环境变量(按需):
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
NODE_MOBILE_PREBUILT_VERSION=v22.23.2 # 覆盖默认版本
|
|
96
|
-
NODE_MOBILE_PREBUILT_SKIP=1 # 跳过全部下载
|
|
97
|
-
NODE_MOBILE_PREBUILT_ANDROID_SKIP=1 # 只跳过 Android
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
**用户不需要手动下载和替换**——除非要换成自编译的版本,见 2.2;
|
|
101
|
-
|
|
102
|
-
### 2.1
|
|
103
|
-
|
|
104
|
-
路径:
|
|
105
|
-
|
|
106
|
-
```
|
|
107
|
-
<你的项目>/node_modules/@flun/nodejs-mobile-react-native/android/libnode/bin/<架构>/libnode.so
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
|
133
|
-
|
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
{
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
{
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
| `app.get('
|
|
224
|
-
| `app.get('/:id
|
|
225
|
-
| `app.
|
|
226
|
-
| `
|
|
227
|
-
| `res.
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
npm ls
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
- **误区
|
|
256
|
-
- **误区
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
& $adb shell am
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
NODEJS-MOBILE:
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
& $adb logcat -
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
Remove-Item -Recurse -Force D:\你的项目\node_modules\@flun\nodejs-mobile-react-native\android
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" reverse
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
- `
|
|
339
|
-
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
- [
|
|
347
|
-
- [
|
|
348
|
-
- [libnode.so 预编译仓库](https://github.com/OpenFlun/nodejs-mobile)([Gitee](https://gitee.com/OpenFlun/nodejs-mobile))
|
|
1
|
+
# Android 构建指南
|
|
2
|
+
|
|
3
|
+
本文档是 [README.md](./README.md) 的**深度附件**;日常使用(`test` / `build`)不需要看——CLI 自动处理;
|
|
4
|
+
|
|
5
|
+
本文档只讲四件事,都是 README 没细说的:
|
|
6
|
+
1. **环境准备**(JDK / SDK / NDK / adb / 原生模块编译)
|
|
7
|
+
2. **libnode.so**(v18 vs v22、预编译仓库、替换、full-icu 验证)
|
|
8
|
+
3. **Express 版本选择**(踩坑清单)
|
|
9
|
+
4. **调试与缓存排查**(logcat 命令、手动清缓存兜底)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 一、环境准备
|
|
14
|
+
|
|
15
|
+
### 1.1 JDK 17(必须)
|
|
16
|
+
|
|
17
|
+
Android Gradle Plugin 不支持 JDK 18+;
|
|
18
|
+
|
|
19
|
+
下载:[Adoptium JDK 17](https://adoptium.net/temurin/releases/?version=17)
|
|
20
|
+
|
|
21
|
+
**CLI 不读 `JAVA_HOME`**,直接用系统 PATH 里的 `java`;确保 `java -version` 输出是 17;
|
|
22
|
+
|
|
23
|
+
### 1.2 Android SDK
|
|
24
|
+
|
|
25
|
+
CLI 自动查找,顺序:
|
|
26
|
+
|
|
27
|
+
1. `mobileAppConfig.js` 的 `android.sdkPath`
|
|
28
|
+
2. 环境变量 `ANDROID_HOME` / `ANDROID_SDK_ROOT`
|
|
29
|
+
3. 常见默认路径(Windows:`%LOCALAPPDATA%\Android\Sdk`)
|
|
30
|
+
|
|
31
|
+
**必需组件**:
|
|
32
|
+
|
|
33
|
+
| 组件 | 版本 |
|
|
34
|
+
| -------------- | ------------------------------------------------------------------------- |
|
|
35
|
+
| SDK Platform | 与 `mobileAppConfig.js` 的 `android.compileSdkVersion` 一致的 Platform |
|
|
36
|
+
| Build-Tools | 与 `mobileAppConfig.js` 的 `android.buildToolsVersion` 一致 |
|
|
37
|
+
| Platform-Tools | 含 adb 的较新版本 |
|
|
38
|
+
| NDK | 与模板 `android/build.gradle` 的 `ndkVersion` 一致(libnode.so 编译依赖) |
|
|
39
|
+
|
|
40
|
+
### 1.3 adb
|
|
41
|
+
|
|
42
|
+
查找顺序同 SDK;常用命令:
|
|
43
|
+
|
|
44
|
+
```powershell
|
|
45
|
+
$adb = "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe"
|
|
46
|
+
& $adb devices
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 1.4 原生模块编译(自动检测)
|
|
50
|
+
|
|
51
|
+
CLI 会扫描 `<buildDir>/nodejs-assets/nodejs-project/node_modules/` 下是否有 `binding.gyp` 文件(原生模块的标志),自动写:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
<buildDir>/nodejs-assets/BUILD_NATIVE_MODULES.txt # 1=有原生模块,0=无
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **检测到原生模块**(如 `bcrypt`、`sqlite3`):写 `1`,并设环境变量 `NODEJS_MOBILE_BUILD_NATIVE_MODULES=1`,`npm install` 时自动重编
|
|
58
|
+
- **未检测到**:写 `0`,跳过编译
|
|
59
|
+
|
|
60
|
+
**用户无需手动配置**;检测结果会纳入依赖哈希,装/卸原生模块时会自动触发重装重编;
|
|
61
|
+
|
|
62
|
+
**手动强制重编**:换过 `libnode.so` 但依赖没变、需要重新编译原生模块时:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Linux / macOS
|
|
66
|
+
NODE_MOBILE_FORCE_REBUILD=1 npx node-mobile-app test
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
# Windows
|
|
71
|
+
$env:NODE_MOBILE_FORCE_REBUILD=1; npx node-mobile-app test
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Windows 编译原生模块的前置条件**:需 Android SDK 中的 NDK(提供交叉编译工具链与 `make.exe`)与 Git for Windows(提供 `sh` / `sed` / `rm` 等 GNU 工具,`nodejs-mobile-gyp` 会从注册表或常见路径自动定位);二者缺失时编译阶段报错;Linux / macOS 使用系统自带的同类工具,无需额外安装;
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 二、libnode.so
|
|
79
|
+
|
|
80
|
+
`nodejs-mobile-react-native` 用它提供 Node.js 运行时;**是否带 full-icu** 决定能跑哪个 Express 版本;
|
|
81
|
+
|
|
82
|
+
### 2.0 预编译二进制怎么来的
|
|
83
|
+
|
|
84
|
+
从 `@flun/nodejs-mobile-react-native` 1.0.1 起,`libnode.so` **不在 npm 包里**,安装时由 postinstall 脚本从 Gitee / GitHub Release 自动下载:
|
|
85
|
+
|
|
86
|
+
- **下载源**:Gitee 优先,失败自动回退 GitHub
|
|
87
|
+
- **下载内容**:`android-libnode.zip`(双架构约 88 MB),含 `bin/` + `include/`;具体大小以实际下载为准;
|
|
88
|
+
- **覆盖目标**:`node_modules/@flun/nodejs-mobile-react-native/android/libnode/`
|
|
89
|
+
- **幂等**:已装版本匹配则跳过,不重复下载
|
|
90
|
+
- **失败处理**:全部源失败时打印下载链接,不中断 npm 安装
|
|
91
|
+
|
|
92
|
+
环境变量(按需):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
NODE_MOBILE_PREBUILT_VERSION=v22.23.2 # 覆盖默认版本
|
|
96
|
+
NODE_MOBILE_PREBUILT_SKIP=1 # 跳过全部下载
|
|
97
|
+
NODE_MOBILE_PREBUILT_ANDROID_SKIP=1 # 只跳过 Android
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**用户不需要手动下载和替换**——除非要换成自编译的版本,见 2.2;
|
|
101
|
+
|
|
102
|
+
### 2.1 自动下载的预编译产物
|
|
103
|
+
|
|
104
|
+
路径:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
<你的项目>/node_modules/@flun/nodejs-mobile-react-native/android/libnode/bin/<架构>/libnode.so
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
以下为 v18 产物的实测大小;其它版本的体积以实际下载为准:
|
|
111
|
+
|
|
112
|
+
| 架构 | 大小 |
|
|
113
|
+
| ----------- | ------- |
|
|
114
|
+
| arm64-v8a | 59.6 MB |
|
|
115
|
+
| armeabi-v7a | 56 MB |
|
|
116
|
+
| x86_64 | 62.3 MB |
|
|
117
|
+
|
|
118
|
+
**版本特性**:v18 产物使用 `--with-intl=none`,不含 ICU,不能用 `\p{...}` / `\P{...}` Unicode 正则,必须配 Express 4;v22 起产物带 full-icu,可用 Unicode 正则与 Express 5;下载版本由 `package.json` 的 `prebuiltAssets.version` 决定;
|
|
119
|
+
|
|
120
|
+
### 2.2 替换为自编译产物
|
|
121
|
+
|
|
122
|
+
自动下载的产物若不含 full-icu(见 2.3 的 `strings` 验证),且需跑 Express 5 或使用 Unicode 正则,替换为自编译的 full-icu 版本;
|
|
123
|
+
|
|
124
|
+
**预编译产物仓库**:
|
|
125
|
+
|
|
126
|
+
- GitHub:https://github.com/OpenFlun/nodejs-mobile
|
|
127
|
+
- Gitee(国内):https://gitee.com/OpenFlun/nodejs-mobile
|
|
128
|
+
|
|
129
|
+
**架构支持(按版本)**:
|
|
130
|
+
|
|
131
|
+
| 架构 | v18 | v22 |
|
|
132
|
+
| ----------- | --- | --- |
|
|
133
|
+
| arm64-v8a | ✓ | ✓ |
|
|
134
|
+
| x86_64 | ✓ | ✓ |
|
|
135
|
+
| armeabi-v7a | ✓ | ✗ |
|
|
136
|
+
|
|
137
|
+
架构支持随产物版本变化;具体以 Releases 页面各版本的产物说明为准;
|
|
138
|
+
|
|
139
|
+
**替换步骤**:
|
|
140
|
+
|
|
141
|
+
1. 下载 `android-libnode.zip`(含 `bin/` + `include/`)
|
|
142
|
+
2. **整体替换** `你的项目/node_modules/@flun/nodejs-mobile-react-native/android/libnode/`
|
|
143
|
+
3. `mobileAppConfig.js` 的 `android.abiFilters` 只写该产物实际包含的架构(见解压后的 `libnode/bin/` 目录)
|
|
144
|
+
4. 跑 `npx node-mobile-app test` 或 `build`
|
|
145
|
+
|
|
146
|
+
CLI 指纹机制检测到 `libnode.so` 变化后,会清 `.cxx` / `android/build` / `app/build`,并清 `nodejs-assets` 与依赖快照,触发重装、重编、重优化——**无需手动清缓存**;
|
|
147
|
+
|
|
148
|
+
**完整自编译流程**见 `自定义libnode指南.md`;
|
|
149
|
+
|
|
150
|
+
### 2.3 验证是否带 full-icu
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Linux / macOS / WSL / Git Bash
|
|
154
|
+
strings libnode.so | grep -c icudt78l
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- 输出几千(约 4300)→ 带 full-icu
|
|
158
|
+
- 输出 0 → 不带
|
|
159
|
+
|
|
160
|
+
**体积对照**(实测,strip 后):
|
|
161
|
+
|
|
162
|
+
| 版本 | arm64-v8a | x86_64 |
|
|
163
|
+
| ---------------------- | --------- | -------- |
|
|
164
|
+
| v18(官方,无 ICU) | 59.6 MB | 62.3 MB |
|
|
165
|
+
| v22(自编译,full-icu) | 112.4 MB | 117.2 MB |
|
|
166
|
+
|
|
167
|
+
体积差异约 50 MB,来自三部分:Node v22 核心引擎 + full-icu 数据(约 25–30 MB)+ V8 版本升级;**不是编译出错**;
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 三、Express 版本选择(踩坑清单)
|
|
172
|
+
|
|
173
|
+
**选错版本会在 Node 进程启动时崩溃**,且错误信息极具误导性(如 `number 116 is not a function`);
|
|
174
|
+
|
|
175
|
+
### 3.1 版本对照
|
|
176
|
+
|
|
177
|
+
| libnode.so | Node.js | ICU | Express |
|
|
178
|
+
| --------------------- | ------- | --- | ---------------------- |
|
|
179
|
+
| 官方 v18 | v18 | 无 | **4.x**(如 `4.22.2`) |
|
|
180
|
+
| 自编译 v22 + full-icu | v22 | 有 | **5.x**(如 `5.2.1`) |
|
|
181
|
+
|
|
182
|
+
### 3.2 场景 A(v18 + Express 4)
|
|
183
|
+
|
|
184
|
+
`nodejs-project/package.json`:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"dependencies": {
|
|
189
|
+
"express": "4.22.2"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
依赖里如有 `\P{ASCII}` 等 Unicode 正则,改写成 ASCII 等价:
|
|
195
|
+
|
|
196
|
+
| 原写法 | ASCII 写法 |
|
|
197
|
+
| ----------- | -------------- |
|
|
198
|
+
| `\P{ASCII}` | `[^\x00-\x7F]` |
|
|
199
|
+
|
|
200
|
+
### 3.3 场景 B(v22 + full-icu + Express 5)
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"dependencies": {
|
|
205
|
+
"express": "5.2.1"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**三个前提**:
|
|
211
|
+
|
|
212
|
+
1. `libnode.so` 确实带 full-icu(用 `strings` 验证过)
|
|
213
|
+
2. **不要**用 `@alloc/path-to-regexp` 替换原版——它的 `exports` 只有 `import` 条件,CJS 下 `require()` 报 `No "exports" main defined`
|
|
214
|
+
3. **不要**加任何 `overrides` 强制替换 `path-to-regexp`
|
|
215
|
+
|
|
216
|
+
### 3.4 Express 5 路由语法迁移
|
|
217
|
+
|
|
218
|
+
`app.get('*')` 会抛 `TypeError: Missing parameter name`:
|
|
219
|
+
|
|
220
|
+
| Express 4 | Express 5 |
|
|
221
|
+
| ---------------------------- | --------------------------------- |
|
|
222
|
+
| `app.get('*', handler)` | `app.get('/{*splat}', handler)` |
|
|
223
|
+
| `app.get('/:id?', handler)` | `app.get('/user{/:id}', handler)` |
|
|
224
|
+
| `app.get('/:id(\\d+)', ...)` | 中间件校验 `req.params.id` |
|
|
225
|
+
| `app.del('/x', handler)` | `app.delete('/x', handler)` |
|
|
226
|
+
| `res.json(obj, 200)` | `res.status(200).json(obj)` |
|
|
227
|
+
| `res.send(200, body)` | `res.status(200).send(body)` |
|
|
228
|
+
|
|
229
|
+
### 3.5 验证依赖树
|
|
230
|
+
|
|
231
|
+
```powershell
|
|
232
|
+
cd node-mobile-app-build\nodejs-assets\nodejs-project
|
|
233
|
+
npm ls express --all
|
|
234
|
+
npm ls path-to-regexp --all
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**期望(场景 B)**:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
express@5.2.1
|
|
241
|
+
└─┬ router@2.2.0
|
|
242
|
+
└── path-to-regexp@8.4.2
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
如出现 `@alloc/path-to-regexp`,说明 `package-lock.json` 里有残留 `overrides`;**彻底清理**:
|
|
246
|
+
|
|
247
|
+
```powershell
|
|
248
|
+
Remove-Item -Recurse -Force node_modules, package-lock.json
|
|
249
|
+
npm install
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 3.6 三个常见误区
|
|
253
|
+
|
|
254
|
+
- **误区 1**:以为 `@alloc/path-to-regexp` 能解决 ESM 问题 → 它的 `exports` 也是纯 `import`,`require()` 依然失败
|
|
255
|
+
- **误区 2**:只改路由语法就想让 Express 5 跑 → 若 `libnode.so` 无 full-icu,加载 `path-to-regexp@8` 时仍崩
|
|
256
|
+
- **误区 3**:用 `overrides` 强制替换 `path-to-regexp` → 破坏依赖链,且 `package-lock.json` 会残留解析结果,删掉 `overrides` 也不生效
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## 四、调试与缓存排查
|
|
261
|
+
|
|
262
|
+
### 4.1 抓 Node.js 日志
|
|
263
|
+
|
|
264
|
+
```powershell
|
|
265
|
+
$adb = "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe"
|
|
266
|
+
|
|
267
|
+
# 清空
|
|
268
|
+
& $adb logcat -c
|
|
269
|
+
|
|
270
|
+
# 重启 App
|
|
271
|
+
& $adb shell am force-stop com.me.myapp
|
|
272
|
+
& $adb shell am start -n com.me.myapp/.MainActivity
|
|
273
|
+
|
|
274
|
+
# 抓关键日志
|
|
275
|
+
& $adb logcat -d | Select-String 'NODEJS-MOBILE|ReactNativeJS'
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**正常日志**:
|
|
279
|
+
```
|
|
280
|
+
NODEJS-MOBILE: [node-mobile-app] server URL: http://127.0.0.1:3000
|
|
281
|
+
NODEJS-MOBILE: Express started on port 3000
|
|
282
|
+
ReactNativeJS: Node started on http://127.0.0.1:3000
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**失败日志**:
|
|
286
|
+
```
|
|
287
|
+
NODEJS-MOBILE: [node-mobile-app] failed: Node 服务 5 秒内未启动 -- 请检查 ./server.js 是否调用了 listen()
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**崩溃日志**:
|
|
291
|
+
|
|
292
|
+
```powershell
|
|
293
|
+
& $adb logcat -c
|
|
294
|
+
& $adb logcat | Select-String 'FATAL|AndroidRuntime|NODEJS-MOBILE'
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### 4.2 手动清缓存(兜底)
|
|
298
|
+
|
|
299
|
+
**正常情况不需要**——CLI 指纹机制自动清;以下仅当指纹判断失效(如手动改过 `node-mobile-app-build/` 内文件)时用:
|
|
300
|
+
|
|
301
|
+
```powershell
|
|
302
|
+
# 最彻底:删整个 RN 工程
|
|
303
|
+
Remove-Item -Recurse -Force D:\你的项目\node-mobile-app-build
|
|
304
|
+
|
|
305
|
+
# 或删插件 CMake 缓存
|
|
306
|
+
Remove-Item -Recurse -Force D:\你的项目\node_modules\@flun\nodejs-mobile-react-native\android\.cxx
|
|
307
|
+
Remove-Item -Recurse -Force D:\你的项目\node_modules\@flun\nodejs-mobile-react-native\android\build
|
|
308
|
+
|
|
309
|
+
# 或删指纹文件(下次跑 = 全新构建)
|
|
310
|
+
Remove-Item -Force D:\你的项目\node-mobile-app-build\.build-fingerprint.json
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
或直接:
|
|
314
|
+
|
|
315
|
+
```powershell
|
|
316
|
+
npx node-mobile-app clean
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### 4.3 手动端口转发(`test` 会自动做)
|
|
320
|
+
|
|
321
|
+
```powershell
|
|
322
|
+
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" reverse tcp:8081 tcp:8081
|
|
323
|
+
& "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe" reverse --list
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### 4.4 模拟器(x86_64)
|
|
327
|
+
|
|
328
|
+
```powershell
|
|
329
|
+
# 列出 AVD
|
|
330
|
+
& "$env:LOCALAPPDATA\Android\Sdk\emulator\emulator.exe" -list-avds
|
|
331
|
+
|
|
332
|
+
# 启动
|
|
333
|
+
& "$env:LOCALAPPDATA\Android\Sdk\emulator\emulator.exe" -avd Pixel_7_API_34
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**三个必须**:
|
|
337
|
+
- `mobileAppConfig.js` 的 `abiFilters` 含 `x86_64`
|
|
338
|
+
- `libnode/bin/x86_64/libnode.so` 存在
|
|
339
|
+
- 模拟器镜像是 **x86_64 架构**
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## 相关文档
|
|
344
|
+
|
|
345
|
+
- [README.md](./README.md) —— 快速开始、配置字段、命令
|
|
346
|
+
- [自定义libnode指南.md](./自定义libnode指南.md) —— 自编译 v22 + full-icu 完整流程
|
|
347
|
+
- [libnode.so 预编译仓库](https://github.com/OpenFlun/nodejs-mobile)([Gitee](https://gitee.com/OpenFlun/nodejs-mobile))
|