@flun/node-mobile-app 2.0.2 → 2.0.4

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,4 +1,21 @@
1
1
  # Changelog
2
+ ## [2.0.4] - 2026-09-27 21:50
3
+ ### 更新
4
+ - 依赖包 '@flun/nodejs-mobile-react-native' 更新为 v2.0.2;
5
+ - 优化了 'README.md' 和 'server.js' 一些细节;
6
+
7
+ ## [2.0.3] - 2026-09-25 21:33
8
+ ### 修复
9
+
10
+ - **`template/metro.config.js` 排除配置更新**:原来的 `blacklistRE` 在 Metro 0.86+ 已完全移除,`metro-config/src/defaults/exclusionList.js` 的深层导入路径在 Metro 0.83 起也不再暴露,会导致新版本 RN 项目加载 Metro 配置失败。改为:
11
+ - `blacklistRE` -> `blockList`
12
+ - 导入路径改为 `metro-config/private/defaults/exclusionList`(不带 `.js` 后缀,经 `.default` 取值)
13
+ - 正则改为 `/[/\\]nodejs-assets[/\\].*/` 形式,避免字符串转义在跨平台下出错
14
+
15
+ ### 更新
16
+ - 更新 `@flun/nodejs-mobile-react-native` 依赖;
17
+
18
+ ---
2
19
  ## [2.0.2] - 2026-09-23 20:25
3
20
 
4
21
  ### 修复
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  **核心理念**:你的的 Node 项目保持不变,CLI 负责搬运、编译、打包。所有定制集中在 `mobileAppConfig.js` 一个文件。
6
6
 
7
7
  - GitHub:https://github.com/OpenFlun/node-mobile-app
8
- - Gitee(国内镜像):https://gitee.com/OpenFlun/node-mobile-app
8
+ - Gitee(中国):https://gitee.com/OpenFlun/node-mobile-app
9
9
 
10
10
  ---
11
11
 
@@ -20,14 +20,15 @@
20
20
 
21
21
  ---
22
22
 
23
- ## 环境要求
23
+ ## 环境要求(最低)
24
24
 
25
25
  | 项 | 要求 |
26
26
  | ------------ | ------------------------------------------------------------------- |
27
- | Node.js | >= 18.20.4 |
27
+ | Node.js | 需满足 `package.json` 的 `engines.node` 字段 |
28
28
  | Android 构建 | JDK **17**、Android SDK(minSdk 29 / targetSdk 36 / compileSdk 37) |
29
29
  | iOS 构建 | macOS + Xcode + CocoaPods |
30
30
  | 可选 | watchman(提升 Metro 文件监听性能) |
31
+ | Windows 额外 | Visual Studio + Git for Windows(仅编译原生模块时需要,见下方说明) |
31
32
 
32
33
  **JDK 必须是 17**,Android Gradle Plugin 目前不支持更高版本。
33
34
 
@@ -63,9 +64,6 @@
63
64
  ├── template/ # RN 工程模板(运行时复制到你的项目的 node-mobile-app-build/)
64
65
  │ ├── android/ # Android 原生工程
65
66
  │ ├── ios/ # iOS 原生工程
66
- │ ├── @types/
67
- │ │ └── nodejs-mobile-react-native/
68
- │ │ └── index.d.ts # nodejs-mobile 类型声明
69
67
  │ ├── App.tsx # RN 主界面(WebView + Node 桥接 + 错误页)
70
68
  │ ├── index.js # RN 入口(注册根组件)
71
69
  │ ├── app.json # RN 应用名(CLI 会覆盖)
@@ -130,10 +128,7 @@
130
128
  }
131
129
  ```
132
130
 
133
- > 如果你信任所有安装包,也可以直接在项目 `.npmrc` 中设置 `allow-scripts = false`(表示关闭脚本拦截,所有脚本均允许执行),或删除 `ignore-script`字段;
134
-
135
131
  ---
136
-
137
132
  ## 安装
138
133
 
139
134
  ```bash
@@ -322,15 +317,16 @@ CLI **自动识别 `server.js` 实际监听的协议和端口**——拦截 `net
322
317
 
323
318
  ## Android / iOS 差异
324
319
 
325
- | 项 | Android | iOS |
326
- | ------------ | --------------------------------- | ------------------------------------------------------ |
327
- | 构建环境 | Windows / macOS / Linux | **仅 macOS** |
328
- | Node.js 版本 | v18(官方)/ v22+(自编译) | **v18**(官方;v22 需自编译 `NodeMobile.xcframework`) |
329
- | Express 版本 | v18 用 4.x,v22 + full-icu 用 5.x | **v18 必须用 4.x** |
330
- | `test` 离线 | ✓(内置 bundle) | ✓(需 `FORCE_BUNDLING=1`) |
331
- | 图标尺寸 | 5 个密度(48~192) | 9 个尺寸(40~1024) |
320
+ | 项 | Android | iOS |
321
+ | ------------ | ---------------------------------------------------------- | ----------------------------------------- |
322
+ | 构建环境 | Windows / macOS / Linux | **仅 macOS** |
323
+ | 运行时版本 | 官方提供多个版本,可用 `NODE_MOBILE_PREBUILT_VERSION` 切换 | **当前为 v18.20.4**,更高版本后续逐步适配 |
324
+ | Express 版本 | 产物带 full-icu,4.x / 5.x 均可用 | 当前产物不带 full-icu,**必须用 4.x** |
325
+ | full-icu | 自 v22.23.2 产物起支持 | 暂无 |
326
+ | `test` 离线 | ✓(内置 bundle) | ✓(需 `FORCE_BUNDLING=1`) |
327
+ | 图标尺寸 | 5 个密度(48~192) | 9 个尺寸(40~1024) |
332
328
 
333
- **iOS Node 版本限制**:`nodejs-mobile` 官方为 iOS 提供的二进制停留在 v18。v22 需自行编译 `NodeMobile.xcframework`,流程与 Android 自编译 `libnode.so` 类似(见 `自定义libnode指南.md`)。
329
+ **iOS 运行时版本**:当前 iOS 官方产物为 v18.20.4,更高版本仍在逐步适配。如需提前使用更高版本,可克隆 [nodejs-mobile 仓库](https://github.com/OpenFlun/nodejs-mobile) 自行编译 `NodeMobile.xcframework`,流程与 Android 自编译 `libnode.so` 类似(见 `自定义libnode指南.md`)。
334
330
 
335
331
  ---
336
332
 
@@ -355,6 +351,7 @@ CLI **自动识别 `server.js` 实际监听的协议和端口**——拦截 `net
355
351
  └── nodejs-project/ # 你的 Node 项目副本
356
352
  ├── server.js # 你的源码
357
353
  ├── main.js # CLI 生成,桥接代码
354
+ │── 你允许的其它生产文件/目录...
358
355
  ├── package.json # 只保留 dependencies
359
356
  └── node_modules/ # 你的生产依赖
360
357
  ```
@@ -393,8 +390,8 @@ adb logcat | grep -E "NODEJS-MOBILE|ReactNativeJS"
393
390
 
394
391
  ### Q:Express 版本怎么选?
395
392
 
396
- - **`libnode.so` 不带 full-icu(官方 v18)** → **必须用 Express 4**(如 `4.22.2`)
397
- - **`libnode.so` 带 full-icu(自编译 v22)** → 可以用 Express 5(如 `5.2.1`)
393
+ - **Android**:内置完整 ICU(full-icu)→ 可以用 Express 5
394
+ - **iOS**:暂无 ICU → 必须用 Express 4
398
395
 
399
396
  Express 5 的路由语法与 4 不同(如 `app.get('*')` 要改成 `app.get('/{*splat}')`),迁移时留意。
400
397
 
@@ -402,12 +399,12 @@ Express 5 的路由语法与 4 不同(如 `app.get('*')` 要改成 `app.get('/
402
399
 
403
400
  从 `@flun/nodejs-mobile-react-native` 1.0.1 起,两套预编译二进制**不在 npm 包里**,改为 postinstall 阶段自动从 Gitee / GitHub Release 下载:
404
401
 
405
- | 资源 | 大小 | 目标位置 |
406
- | -------------------------------- | -------- | --------------------------------------------------------------------------- |
407
- | `android-libnode.zip` | 约 52 MB | `node_modules/@flun/nodejs-mobile-react-native/android/libnode/` |
408
- | `ios-nodemobile.zip`(仅 macOS) | 约 47 MB | `node_modules/@flun/nodejs-mobile-react-native/ios/NodeMobile.xcframework/` |
402
+ | 资源 | 目标位置 |
403
+ | -------------------------------- | --------------------------------------------------------------------------- |
404
+ | `android-libnode.zip` | `node_modules/@flun/nodejs-mobile-react-native/android/libnode/` |
405
+ | `ios-nodemobile.zip`(仅 macOS) | `node_modules/@flun/nodejs-mobile-react-native/ios/NodeMobile.xcframework/` |
409
406
 
410
- - 默认下载 v18.20.4 官方二进制
407
+ - 默认下载版本以 `@flun/nodejs-mobile-react-native` 的 `package.json` 中 `prebuiltAssets.version` 字段为准
411
408
  - Gitee 优先,失败自动回退 GitHub
412
409
  - 已装版本匹配则跳过,不重复下
413
410
  - 全部源失败时打印下载链接,**不中断 npm 安装**
@@ -415,14 +412,14 @@ Express 5 的路由语法与 4 不同(如 `app.get('*')` 要改成 `app.get('/
415
412
  环境变量:
416
413
 
417
414
  ```bash
418
- NODE_MOBILE_PREBUILT_VERSION=v22.23.2 # 覆盖默认版本
415
+ NODE_MOBILE_PREBUILT_VERSION=<版本号> # 覆盖默认版本(须为该包 Release 中实际存在的 tag)
419
416
  NODE_MOBILE_PREBUILT_SKIP=1 # 跳过全部下载
420
417
  NODE_MOBILE_PREBUILT_IOS_SKIP=1 # 只跳过 iOS
421
418
  ```
422
419
 
423
420
  ### Q:如何替换成自定义编译的 `libnode.so`?
424
421
 
425
- 如果你自编译了带 full-icu 的 v22(或其它版本)`libnode.so`,可手动覆盖自动下载的产物:
422
+ 如果你自编译了 `libnode.so`(如需要特定 Node 版本或自定义 ICU),可手动覆盖自动下载的产物:
426
423
 
427
424
  1. 把编译好的 `libnode.so` 覆盖到 `android/libnode/bin/<架构>/`(**只放你实际编译的架构**)
428
425
  2. 如果 `mobileAppConfig.js` 的 `android.abiFilters` 与 libnode 支持的架构不一致,同步调整
@@ -430,7 +427,7 @@ NODE_MOBILE_PREBUILT_IOS_SKIP=1 # 只跳过 iOS
430
427
 
431
428
  **CLI 会自动处理缓存**:指纹机制检测到 `libnode.so` 或 `abiFilters` 变化,自动清理 `.cxx` / `android/build` / `app/build`,全量重编。**你的无需手动清任何缓存**。
432
429
 
433
- 详细流程(自编译 v22 + full-icu)见 `自定义libnode指南.md`。
430
+ 详细流程见 `自定义libnode指南.md`。
434
431
 
435
432
  ### Q:iOS 提示 `fallbackSourceURL does not override`?
436
433
 
@@ -441,10 +438,10 @@ RN 0.87 的 API 若变动,`AppDelegate.swift` 里的 fallback 可能不生效
441
438
  ## 相关文档
442
439
 
443
440
  - [Android 构建指南.md](./Android%20构建指南.md) —— Android 环境配置、踩坑清单
444
- - [自定义libnode指南.md](./自定义libnode指南.md) —— 自编译 v22 `libnode.so` 的完整流程
441
+ - [自定义libnode指南.md](./自定义libnode指南.md) —— 自编译 `libnode.so` 的完整流程
445
442
 
446
443
  ---
447
444
 
448
445
  ## 许可
449
446
 
450
- ISC
447
+ ISC
@@ -34,4 +34,4 @@ const PORT = 3000,
34
34
  res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }), res.end(html);
35
35
  });
36
36
 
37
- server.listen(PORT, '0.0.0.0', () => console.log(`Express started on port ${PORT}`));
37
+ server.listen(PORT, '0.0.0.0', () => console.log(`Server started on port ${PORT}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flun/node-mobile-app",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "将 Node.js 项目一键打包为 Android / iOS 移动应用,运行时由 @flun/nodejs-mobile-react-native 提供,无需修改你的 Node 代码;",
5
5
  "author": "flun <open@flun.top>",
6
6
  "keywords": [
@@ -62,7 +62,7 @@
62
62
  "eslint-plugin-react": "^7.37.5",
63
63
  "eslint-plugin-react-hooks": "^7.1.1",
64
64
  "eslint-plugin-react-native": "^5.0.0",
65
- "@flun/nodejs-mobile-react-native": "^1.0.3"
65
+ "@flun/nodejs-mobile-react-native": "^2.0.2"
66
66
  },
67
67
  "allowScripts": {
68
68
  "node": true,
@@ -81,7 +81,7 @@
81
81
  },
82
82
  "license": "ISC",
83
83
  "engines": {
84
- "node": ">= 18.20.4"
84
+ "node": ">= 18"
85
85
  },
86
86
  "bin": {
87
87
  "node-mobile-app": "./bin/cli.js"
@@ -1,18 +1,18 @@
1
1
  import { getDefaultConfig, mergeConfig } from '@react-native/metro-config';
2
+ import exclusionListModule from 'metro-config/private/defaults/exclusionList';
2
3
  import { dirname, resolve } from 'path';
3
4
  import { fileURLToPath } from 'url';
4
5
 
6
+ const exclusionList = exclusionListModule.default;
5
7
  const __filename = fileURLToPath(import.meta.url), __dirname = dirname(__filename), workspaceRoot = resolve(__dirname, '..'),
6
- /**
7
- * Metro 配置
8
- * RN 工程位于 <userProject>/node-mobile-app-build/
9
- * 依赖装在 <userProject>/node_modules/(上一级)
10
- *
11
- * watchFolders 只监听必要位置,避免递归整个用户项目(性能灾难)
12
- */
13
8
  config = {
14
9
  watchFolders: [__dirname, resolve(workspaceRoot, 'node_modules')],
15
- resolver: { nodeModulesPaths: [resolve(__dirname, 'node_modules'), resolve(workspaceRoot, 'node_modules')] }
10
+ resolver: {
11
+ nodeModulesPaths: [resolve(__dirname, 'node_modules'), resolve(workspaceRoot, 'node_modules')],
12
+ blockList: exclusionList([
13
+ /[/\\]nodejs-assets[/\\].*/,
14
+ ]),
15
+ }
16
16
  };
17
17
 
18
18
  export default mergeConfig(getDefaultConfig(__dirname), config);
@@ -416,8 +416,8 @@ x86_64 在 x64 主机上**无交叉编译问题**,与 arm64 流程一致。`an
416
416
  | `number 116 is not a function` | `libnode.so` 无 full-icu | 重新用 `--with-intl=full-icu` 编译,或回退 Express 4 |
417
417
  | `\p{...}` 正则报错 | 同上 | 同上 |
418
418
  | `No "exports" main defined` | 用了 `@alloc/path-to-regexp` | 撤销 `overrides`,清 `node_modules` + `package-lock.json` 重装 |
419
- | `Cannot find module 'rn-bridge'` | Node 20+ 不再把链接绑定暴露给 `require()` | 需修改 Node.js `lib/internal/modules/cjs/loader.js`,从 `NODE_PATH` 加载 `rn-bridge` 的 JS 包装 |
420
- | `require('rn-bridge')` 返回原生绑定 | `loader.js` 补丁未生效 | 确认 `rn-bridge.cpp` 保持 `NODE_MODULE_LINKED` 注册宏 |
419
+ | `Cannot find module 'rn-bridge'` | Node 20+ 不再把链接绑定暴露给 `require()` | 需修改 Node.js `lib/internal/modules/cjs/loader.js`,从 `NODE_PATH` 按目录加载 `rn-bridge`(入口由该目录 `package.json` 的 `main` 决定) |
420
+ | 启动即崩:`pthread_mutex_lock called on a destroyed mutex` + `Fatal signal 6 (SIGABRT)`;`require('rn-bridge')` 返回的对象无 `channel` 属性 | v22 loader 补丁按 `rn-bridge/index.js` 硬编码定位,而插件入口因 `type: module` 已改名(如 `index.cjs`),匹配失败 → Node 回退到 `process._linkedBinding('rn_bridge')` 拿裸 binding | 使用按**目录** `rn-bridge` 定位的 loader 补丁(入口由该目录 `package.json` 的 `main` 字段解析) |
421
421
  | JNI 编译报 `undefined symbol: v8::Exception::Error` | 插件旧头文件(v18 时代)与 v22 `libnode.so` ABI 不匹配 | **用 `android-libnode.zip` 整目录替换**,其 `include/node/` 是 v22 官方 headers |
422
422
  | `NODE_MODULE_VERSION` 不匹配 | 原生模块未重编 | `NODE_MOBILE_FORCE_REBUILD=1` 后重跑 CLI |
423
423
  | Windows 下 `Unsupported operating system for nodejs-mobile native builds` | 插件硬编码只支持 macOS/Linux | 官方 v22 产物已含 Windows 支持(`windows-x86_64` + `host_os=win32`) |