@flun/node-mobile-app 4.0.5 → 4.0.7

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 (49) hide show
  1. package/Android /346/236/204/345/273/272/346/214/207/345/215/227.md" +84 -76
  2. package/CHANGELOG.md +9 -9
  3. package/LICENSE +9 -4
  4. package/README.md +206 -113
  5. package/bin/cli.js +9 -9
  6. package/cli-assets/server.js +7 -4
  7. package/mobileAppConfig.js +32 -32
  8. package/package.json +5 -5
  9. package/scripts/copy-files.js +1 -1
  10. package/src/commands/build.js +9 -4
  11. package/src/commands/clean.js +3 -2
  12. package/src/commands/test.js +13 -9
  13. package/src/config.js +3 -3
  14. package/src/copy.js +41 -36
  15. package/src/fingerprint.js +4 -3
  16. package/src/generate.js +5 -3
  17. package/src/install.js +38 -27
  18. package/src/optimize-node-modules.js +10 -5
  19. package/src/patcher.js +37 -32
  20. package/src/platform-ios.js +6 -6
  21. package/src/utils.js +26 -22
  22. package/template/App.tsx +4 -4
  23. package/template/Gemfile +1 -1
  24. package/template/android/app/build.gradle +1 -1
  25. package/template/android/app/proguard-rules.pro +1 -1
  26. package/template/android/app/src/main/java/com/myapp/MainActivity.kt +1 -1
  27. package/template/android/app/src/main/java/com/myapp/MainApplication.kt +1 -1
  28. package/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +6 -3
  29. package/template/android/app/src/main/res/raw/keep.xml +1 -1
  30. package/template/android/app/src/main/res/values/strings.xml +1 -1
  31. package/template/android/app/src/main/res/values/styles.xml +1 -1
  32. package/template/android/build.gradle +1 -1
  33. package/template/android/gradle.properties +1 -1
  34. package/template/android/gradlew +3 -2
  35. package/template/android/gradlew.bat +3 -2
  36. package/template/android/settings.gradle +1 -1
  37. package/template/app.json +1 -1
  38. package/template/index.js +2 -2
  39. package/template/ios/.xcode.env +1 -1
  40. package/template/ios/MyApp/Images.xcassets/AppIcon.appiconset/Contents.json +1 -1
  41. package/template/ios/MyApp/Images.xcassets/Contents.json +1 -1
  42. package/template/ios/MyApp/Info.plist +1 -1
  43. package/template/ios/MyApp/LaunchScreen.storyboard +30 -12
  44. package/template/ios/MyApp/PrivacyInfo.xcprivacy +1 -1
  45. package/template/ios/MyApp.xcodeproj/project.pbxproj +34 -15
  46. package/template/ios/MyApp.xcodeproj/xcshareddata/xcschemes/MyApp.xcscheme +1 -1
  47. package/template/ios/Podfile +1 -1
  48. package/template/package.json +1 -1
  49. package//350/207/252/345/256/232/344/271/211libnode/346/214/207/345/215/227.md +131 -98
package/src/utils.js CHANGED
@@ -36,7 +36,7 @@ const ensureDir = dir => {
36
36
  readJson = file => JSON.parse(fs.readFileSync(file, 'utf-8')),
37
37
  writeJson = (file, obj) => fs.writeFileSync(file, JSON.stringify(obj, null, 2) + '\n', 'utf-8'),
38
38
  /**
39
- * 内容不同才写文件,避免不必要的 mtime 变化触发下游(Gradle/Metro)重编
39
+ * 内容不同才写文件,避免不必要的 mtime 变化触发下游(Gradle/Metro)重编
40
40
  * 返回 true 表示写入了,false 表示内容相同跳过
41
41
  */
42
42
  writeIfChanged = (file, content) => {
@@ -62,17 +62,17 @@ const ensureDir = dir => {
62
62
  fs.copyFileSync(src, dst);
63
63
  return true;
64
64
  },
65
- // 把单个参数转成适合 Windows cmd.exe 的形式:含空白或 shell 元字符时加双引号。
65
+ // 把单个参数转成适合 Windows cmd.exe 的形式:含空白或 shell 元字符时加双引号;
66
66
  quoteShellArg = (s) => {
67
67
  const str = String(s);
68
68
  if (str === '') return '""';
69
69
  return /[\s"&|<>^()]/.test(str) ? '"' + str.replace(/"/g, '""') + '"' : str;
70
70
  },
71
71
  /**
72
- * 统一的子进程启动:
73
- * - Windows:.cmd / .bat 需经 shell;把命令与参数拼成单字符串,
74
- * 避免 spawnSync(bin, args, { shell: true }) 触发 DEP0190。
75
- * - 其它平台:不用 shell,参数交由 Node 转义。
72
+ * 统一的子进程启动:
73
+ * - Windows:.cmd / .bat 需经 shell;把命令与参数拼成单字符串,
74
+ * 避免 spawnSync(bin, args, { shell: true }) 触发 DEP0190;
75
+ * - 其它平台:不用 shell,参数交由 Node 转义;
76
76
  */
77
77
  spawnCmd = (bin, args, baseOpts = {}) => {
78
78
  if (process.platform === 'win32') {
@@ -82,7 +82,7 @@ const ensureDir = dir => {
82
82
  return spawnSync(bin, args, { ...baseOpts, shell: false });
83
83
  },
84
84
  /**
85
- * 异步 spawn:参数同 spawnCmd,返回 ChildProcess
85
+ * 异步 spawn:参数同 spawnCmd,返回 ChildProcess
86
86
  * @param {string} bin 命令
87
87
  * @param {string[]} args 参数
88
88
  * @param {object} [baseOpts] spawn 选项
@@ -96,7 +96,7 @@ const ensureDir = dir => {
96
96
  return spawn(bin, args, { ...baseOpts, shell: false });
97
97
  },
98
98
  /**
99
- * 执行命令:默认实时输出(inherit);quiet=true 时捕获输出,成功静默、失败才打印
99
+ * 执行命令:默认实时输出(inherit);quiet=true 时捕获输出,成功静默、失败才打印
100
100
  */
101
101
  run = (bin, args, opts = {}) => {
102
102
  const { quiet, ...restOpts } = opts;
@@ -124,7 +124,7 @@ const ensureDir = dir => {
124
124
  return r;
125
125
  },
126
126
  /**
127
- * 执行命令:实时输出,仅首行加缩进前缀,其余行原样
127
+ * 执行命令:实时输出,仅首行加缩进前缀,其余行原样
128
128
  * @param {string} bin 命令
129
129
  * @param {string[]} args 参数
130
130
  * @param {object} [opts] spawn 选项 + prefix
@@ -148,7 +148,7 @@ const ensureDir = dir => {
148
148
  child.on('close', code => code === 0 ? resolve() : reject(new Error(`${bin} ${args.join(' ')} 退出码 ${code}`)));
149
149
  }),
150
150
  /**
151
- * 定位 adb(配置 > 环境变量 > 默认路径 > PATH)
151
+ * 定位 adb(配置 > 环境变量 > 默认路径 > PATH)
152
152
  */
153
153
  findAdb = config => {
154
154
  // 1. 用户显式配置的路径优先
@@ -165,7 +165,7 @@ const ensureDir = dir => {
165
165
  if (fs.existsSync(p)) return p;
166
166
  }
167
167
  }
168
- // 3. 默认路径猜测(Windows / macOS / Linux)
168
+ // 3. 默认路径猜测(Windows / macOS / Linux)
169
169
  const home = process.env.USERPROFILE || process.env.HOME || '', localAppData = process.env.LOCALAPPDATA || '',
170
170
  candidates = [
171
171
  path.join(localAppData, 'Android', 'Sdk', 'platform-tools', 'adb.exe'),
@@ -176,10 +176,10 @@ const ensureDir = dir => {
176
176
  return 'adb';
177
177
  },
178
178
  /**
179
- * 定位 hermesc(Hermes 编译器,用于把 JS bundle 编成字节码)
179
+ * 定位 hermesc(Hermes 编译器,用于把 JS bundle 编成字节码)
180
180
  */
181
181
  /**
182
- * 读取安装状态标志(记录上次由本工具安装的包与变体)
182
+ * 读取安装状态标志(记录上次由本工具安装的包与变体)
183
183
  * @param {string} buildDir 构建目录
184
184
  * @returns {{appId:string, variant:'debug'|'release'}|null} 状态或 null
185
185
  */
@@ -189,19 +189,22 @@ const ensureDir = dir => {
189
189
  try { return JSON.parse(fs.readFileSync(f, 'utf-8')); } catch { return null; }
190
190
  },
191
191
  /**
192
- * 写入安装状态标志(安装成功后调用)
192
+ * 写入安装状态标志(安装成功后调用)
193
193
  * @param {string} buildDir 构建目录
194
194
  * @param {object} state 状态
195
195
  * @returns {void}
196
196
  */
197
197
  writeInstallState = (buildDir, state) => {
198
- try { ensureDir(buildDir), fs.writeFileSync(path.join(buildDir, '.install-state.json'), JSON.stringify(state, null, 2)); } catch { }
198
+ try {
199
+ ensureDir(buildDir),
200
+ fs.writeFileSync(path.join(buildDir, '.install-state.json'), JSON.stringify(state, null, 2));
201
+ } catch { }
199
202
  },
200
203
  /**
201
204
  * 查询设备上已安装包的 DEBUGGABLE 标志
202
205
  * @param {string} adb adb 路径
203
206
  * @param {string} appId 包名
204
- * @returns {'debug'|'release'|null} 变体或 null(未安装)
207
+ * @returns {'debug'|'release'|null} 变体或 null(未安装)
205
208
  */
206
209
  getInstalledVariant = (adb, appId, serial) => {
207
210
  const pre = serial ? ['-s', serial] : [],
@@ -210,12 +213,12 @@ const ensureDir = dir => {
210
213
  return /\bDEBUGGABLE\b/.test(r.stdout) ? 'debug' : 'release';
211
214
  },
212
215
  /**
213
- * 确保待装包可覆盖安装:标志不一致或变体不符时卸载已装包
216
+ * 确保待装包可覆盖安装:标志不一致或变体不符时卸载已装包
214
217
  * @param {string} adb adb 路径
215
218
  * @param {string} appId 包名
216
219
  * @param {'debug'|'release'} want 待装变体
217
220
  * @param {string} buildDir 构建目录
218
- * @param {string} [serial] 设备序列号(多设备时指定)
221
+ * @param {string} [serial] 设备序列号(多设备时指定)
219
222
  * @returns {void}
220
223
  */
221
224
  ensureInstallable = (adb, appId, want, buildDir, serial) => {
@@ -235,7 +238,7 @@ const ensureDir = dir => {
235
238
  return fs.existsSync(p) ? p : null;
236
239
  },
237
240
  /**
238
- * 文件名安全化:去除文件系统非法字符(/ \ : * ? " < > |)
241
+ * 文件名安全化:去除文件系统非法字符(/ \ : * ? " < > |)
239
242
  * 空结果回退 'app'
240
243
  */
241
244
  sanitizeFileName = s => {
@@ -243,7 +246,7 @@ const ensureDir = dir => {
243
246
  return cleaned || 'app';
244
247
  },
245
248
  /**
246
- * 生成 ESLint flat config 源码(替代 @react-native/eslint-config/flat)
249
+ * 生成 ESLint flat config 源码(替代 @react-native/eslint-config/flat)
247
250
  */
248
251
  buildEslintConfigSource = () => `import js from '@eslint/js';
249
252
  import tsParser from '@typescript-eslint/parser';
@@ -272,6 +275,7 @@ import chalk from 'chalk';
272
275
  rules: tsPlugin.configs.recommended.rules }, prettier];`;
273
276
 
274
277
  export {
275
- ensureDir, removeDir, isExcluded, copyDir, readJson, writeJson, writeIfChanged, copyFileIfChanged, spawnCmdAsync, run, runQuiet, runStream,
276
- runSilent, findAdb, readInstallState, writeInstallState, getInstalledVariant, ensureInstallable, findHermesc, sanitizeFileName, buildEslintConfigSource
278
+ ensureDir, removeDir, isExcluded, copyDir, readJson, writeJson, writeIfChanged, copyFileIfChanged, spawnCmdAsync, run,
279
+ runQuiet, runStream, runSilent, findAdb, readInstallState, writeInstallState, getInstalledVariant, ensureInstallable,
280
+ findHermesc, sanitizeFileName, buildEslintConfigSource
277
281
  };
package/template/App.tsx CHANGED
@@ -4,9 +4,9 @@ import { WebView } from 'react-native-webview';
4
4
  import * as NodeMobile from '@flun/nodejs-mobile-react-native';
5
5
  import runtime from './mobileApp.runtime';
6
6
 
7
- // 背景色解析:支持以下三种配置
7
+ // 背景色解析:支持以下三种配置
8
8
  // '#ffffff' / 'white' 等字符串 → 固定色
9
- // 'system' → 跟随系统(内部用默认浅/深色)
9
+ // 'system' → 跟随系统(内部用默认浅/深色)
10
10
  // { light: '#fff', dark: '#000' } → 按系统主题切换
11
11
  const resolveBgColor = (bg: string | { light: string; dark: string }, theme: string | null | undefined): string => {
12
12
  if (typeof bg === 'object' && bg !== null)
@@ -58,7 +58,7 @@ const resolveBgColor = (bg: string | { light: string; dark: string }, theme: str
58
58
  return () => NodeMobile.channel.removeListener('message', listener);
59
59
  }, []);
60
60
 
61
- // 失败:显示错误页(用户看提示,开发者点开看详情)
61
+ // 失败:显示错误页(用户看提示,开发者点开看详情)
62
62
  if (failedReason) {
63
63
  return (
64
64
  <View style={styles.errorContainer}>
@@ -77,7 +77,7 @@ const resolveBgColor = (bg: string | { light: string; dark: string }, theme: str
77
77
  );
78
78
  }
79
79
 
80
- // 尚未就绪:loading
80
+ // 尚未就绪:loading
81
81
  if (!url) {
82
82
  if (!runtime.showLoading) return <View style={styles.fill} />;
83
83
  return (
package/template/Gemfile CHANGED
@@ -14,4 +14,4 @@ gem 'bigdecimal'
14
14
  gem 'logger'
15
15
  gem 'benchmark'
16
16
  gem 'mutex_m'
17
- gem 'nkf'
17
+ gem 'nkf'
@@ -124,4 +124,4 @@ dependencies {
124
124
  } else {
125
125
  implementation jscFlavor
126
126
  }
127
- }
127
+ }
@@ -7,4 +7,4 @@
7
7
  # For more details, see
8
8
  # http://developer.android.com/guide/developing/tools/proguard.html
9
9
 
10
- # Add any project specific keep options here:
10
+ # Add any project specific keep options here:
@@ -19,4 +19,4 @@ class MainActivity : ReactActivity() {
19
19
  */
20
20
  override fun createReactActivityDelegate(): ReactActivityDelegate =
21
21
  DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
22
- }
22
+ }
@@ -24,4 +24,4 @@ class MainApplication : Application(), ReactApplication {
24
24
  super.onCreate()
25
25
  loadReactNative(this)
26
26
  }
27
- }
27
+ }
@@ -24,9 +24,12 @@
24
24
  <!--
25
25
  This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
26
26
  The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
27
- NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
27
+ NullPointerException:tempt to invoke virtual method
28
+ 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(
29
+ android.content.res.Resources)'
28
30
 
29
- <item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
31
+ <item android:state_pressed="false" android:state_focused="false"
32
+ android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
30
33
 
31
34
  For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
32
35
  -->
@@ -34,4 +37,4 @@
34
37
  <item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
35
38
  </selector>
36
39
 
37
- </inset>
40
+ </inset>
@@ -1 +1 @@
1
- <resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_close,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_alerttriangle,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_loader,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronleft,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronright" />
1
+ <resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_close,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_alerttriangle,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_loader,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronleft,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronright" />
@@ -1,3 +1,3 @@
1
1
  <resources>
2
2
  <string name="app_name">MyApp</string>
3
- </resources>
3
+ </resources>
@@ -6,4 +6,4 @@
6
6
  <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
7
7
  </style>
8
8
 
9
- </resources>
9
+ </resources>
@@ -20,4 +20,4 @@ buildscript {
20
20
  }
21
21
  }
22
22
 
23
- apply plugin: "com.facebook.react.rootproject"
23
+ apply plugin: "com.facebook.react.rootproject"
@@ -48,4 +48,4 @@ edgeToEdgeEnabled=true
48
48
  android.builtInKotlin=false
49
49
  android.newDsl=false
50
50
  # 允许非 ASCII 路径(如中文路径)构建;AGP 默认拒绝
51
- android.overridePathCheck=true
51
+ android.overridePathCheck=true
@@ -57,7 +57,8 @@
57
57
  # Darwin, MinGW, and NonStop.
58
58
  #
59
59
  # (3) This script is generated from the Groovy template
60
- # https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
60
+ # https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/
61
+ # platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61
62
  # within the Gradle project.
62
63
  #
63
64
  # You can find Gradle at https://github.com/gradle/gradle/.
@@ -245,4 +246,4 @@ eval "set -- $(
245
246
  tr '\n' ' '
246
247
  )" '"$@"'
247
248
 
248
- exec "$JAVACMD" "$@"
249
+ exec "$JAVACMD" "$@"
@@ -78,7 +78,8 @@ goto fail
78
78
 
79
79
 
80
80
  @rem Execute Gradle
81
- "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
81
+ "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% ^
82
+ "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
82
83
 
83
84
  :end
84
85
  @rem End local scope for the variables with windows NT shell
@@ -95,4 +96,4 @@ exit /b %EXIT_CODE%
95
96
  :mainEnd
96
97
  if "%OS%"=="Windows_NT" endlocal
97
98
 
98
- :omega
99
+ :omega
@@ -12,4 +12,4 @@ plugins { id("com.facebook.react.settings") }
12
12
  extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
13
13
  rootProject.name = 'MyApp'
14
14
  include ':app'
15
- includeBuild('../../node_modules/@react-native/gradle-plugin')
15
+ includeBuild('../../node_modules/@react-native/gradle-plugin')
package/template/app.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "name": "MyApp",
3
3
  "displayName": "MyApp"
4
- }
4
+ }
package/template/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * React Native 应用入口
3
- * 挂载根组件 App(见 App.tsx)到 AppRegistry,
4
- * 组件名取自 app.json 的 name(由 CLI 根据 appName 自动生成)
3
+ * 挂载根组件 App(见 App.tsx)到 AppRegistry,
4
+ * 组件名取自 app.json 的 name(由 CLI 根据 appName 自动生成)
5
5
  *
6
6
  * 用户一般不需要修改这个文件
7
7
  */
@@ -8,4 +8,4 @@
8
8
  # Customize the NODE_BINARY variable here.
9
9
  # For example, to use nvm with brew, add the following line
10
10
  # . "$(brew --prefix nvm)/nvm.sh" --no-use
11
- export NODE_BINARY=$(command -v node)
11
+ export NODE_BINARY=$(command -v node)
@@ -50,4 +50,4 @@
50
50
  "author" : "xcode",
51
51
  "version" : 1
52
52
  }
53
- }
53
+ }
@@ -3,4 +3,4 @@
3
3
  "version" : 1,
4
4
  "author" : "xcode"
5
5
  }
6
- }
6
+ }
@@ -71,4 +71,4 @@
71
71
  <key>UIViewControllerBasedStatusBarAppearance</key>
72
72
  <false/>
73
73
  </dict>
74
- </plist>
74
+ </plist>
@@ -1,5 +1,7 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
2
+ <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702"
3
+ targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES"
4
+ useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3
5
  <device id="retina4_7" orientation="portrait" appearance="light"/>
4
6
  <dependencies>
5
7
  <deployment identifier="iOS"/>
@@ -16,32 +18,48 @@
16
18
  <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
17
19
  <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18
20
  <subviews>
19
- <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MyApp" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
21
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left"
22
+ horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MyApp"
23
+ textAlignment="center" lineBreakMode="middleTruncation"
24
+ baselineAdjustment="alignBaselines" minimumFontSize="18"
25
+ translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
20
26
  <rect key="frame" x="0.0" y="202" width="375" height="43"/>
21
27
  <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
22
28
  <nil key="highlightedColor"/>
23
29
  </label>
24
- <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
30
+ <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left"
31
+ horizontalHuggingPriority="251" verticalHuggingPriority="251"
32
+ text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation"
33
+ baselineAdjustment="alignBaselines" minimumFontSize="9"
34
+ translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
25
35
  <rect key="frame" x="0.0" y="626" width="375" height="21"/>
26
36
  <fontDescription key="fontDescription" type="system" pointSize="17"/>
27
37
  <nil key="highlightedColor"/>
28
38
  </label>
29
39
  </subviews>
30
- <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
40
+ <color key="backgroundColor" systemColor="systemBackgroundColor"
41
+ cocoaTouchSystemColor="whiteColor"/>
31
42
  <constraints>
32
- <constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="MN2-I3-ftu" secondAttribute="bottom" constant="20" id="OZV-Vh-mqD"/>
33
- <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb" secondAttribute="centerX" id="Q3B-4B-g5h"/>
34
- <constraint firstItem="MN2-I3-ftu" firstAttribute="centerX" secondItem="Bcu-3y-fUS" secondAttribute="centerX" id="akx-eg-2ui"/>
35
- <constraint firstItem="MN2-I3-ftu" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" id="i1E-0Y-4RG"/>
36
- <constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
37
- <constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS" secondAttribute="leading" symbolic="YES" id="x7j-FC-K8j"/>
43
+ <constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="MN2-I3-ftu"
44
+ secondAttribute="bottom" constant="20" id="OZV-Vh-mqD"/>
45
+ <constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb"
46
+ secondAttribute="centerX" id="Q3B-4B-g5h"/>
47
+ <constraint firstItem="MN2-I3-ftu" firstAttribute="centerX" secondItem="Bcu-3y-fUS"
48
+ secondAttribute="centerX" id="akx-eg-2ui"/>
49
+ <constraint firstItem="MN2-I3-ftu" firstAttribute="leading" secondItem="Bcu-3y-fUS"
50
+ secondAttribute="leading" id="i1E-0Y-4RG"/>
51
+ <constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3"
52
+ secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
53
+ <constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS"
54
+ secondAttribute="leading" symbolic="YES" id="x7j-FC-K8j"/>
38
55
  </constraints>
39
56
  <viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
40
57
  </view>
41
58
  </viewController>
42
- <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
59
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder"
60
+ sceneMemberID="firstResponder"/>
43
61
  </objects>
44
62
  <point key="canvasLocation" x="52.173913043478265" y="375"/>
45
63
  </scene>
46
64
  </scenes>
47
- </document>
65
+ </document>
@@ -34,4 +34,4 @@
34
34
  <key>NSPrivacyTracking</key>
35
35
  <false/>
36
36
  </dict>
37
- </plist>
37
+ </plist>
@@ -7,23 +7,42 @@
7
7
  objects = {
8
8
 
9
9
  /* Begin PBXBuildFile section */
10
- 0C80B921A6F3F58F76C31292 /* libPods-MyApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-MyApp.a */; };
11
- 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
12
- 761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
13
- 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
10
+ 0C80B921A6F3F58F76C31292 /* libPods-MyApp.a in Frameworks */ = {isa = PBXBuildFile;
11
+ fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-MyApp.a */; };
12
+ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile;
13
+ fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
14
+ 761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile;
15
+ fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
16
+ 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile;
17
+ fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
14
18
  /* End PBXBuildFile section */
15
19
 
16
20
  /* Begin PBXFileReference section */
17
- 13B07F961A680F5B00A75B9A /* MyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MyApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
18
- 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = MyApp/Images.xcassets; sourceTree = "<group>"; };
19
- 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = MyApp/Info.plist; sourceTree = "<group>"; };
20
- 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = MyApp/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
21
- 3B4392A12AC88292D35C810B /* Pods-MyApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MyApp.debug.xcconfig"; path = "Target Support Files/Pods-MyApp/Pods-MyApp.debug.xcconfig"; sourceTree = "<group>"; };
22
- 5709B34CF0A7D63546082F79 /* Pods-MyApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MyApp.release.xcconfig"; path = "Target Support Files/Pods-MyApp/Pods-MyApp.release.xcconfig"; sourceTree = "<group>"; };
23
- 5DCACB8F33CDC322A6C60F78 /* libPods-MyApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MyApp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
24
- 761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = MyApp/AppDelegate.swift; sourceTree = "<group>"; };
25
- 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = MyApp/LaunchScreen.storyboard; sourceTree = "<group>"; };
26
- ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
21
+ 13B07F961A680F5B00A75B9A /* MyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application;
22
+ includeInIndex = 0; path = MyApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
23
+ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog;
24
+ name = Images.xcassets; path = MyApp/Images.xcassets; sourceTree = "<group>"; };
25
+ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4;
26
+ lastKnownFileType = text.plist.xml; name = Info.plist; path = MyApp/Info.plist; sourceTree = "<group>"; };
27
+ 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4;
28
+ lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = MyApp/PrivacyInfo.xcprivacy;
29
+ sourceTree = "<group>"; };
30
+ 3B4392A12AC88292D35C810B /* Pods-MyApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1;
31
+ lastKnownFileType = text.xcconfig; name = "Pods-MyApp.debug.xcconfig";
32
+ path = "Target Support Files/Pods-MyApp/Pods-MyApp.debug.xcconfig"; sourceTree = "<group>"; };
33
+ 5709B34CF0A7D63546082F79 /* Pods-MyApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1;
34
+ lastKnownFileType = text.xcconfig; name = "Pods-MyApp.release.xcconfig";
35
+ path = "Target Support Files/Pods-MyApp/Pods-MyApp.release.xcconfig"; sourceTree = "<group>"; };
36
+ 5DCACB8F33CDC322A6C60F78 /* libPods-MyApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar;
37
+ includeInIndex = 0; path = "libPods-MyApp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
38
+ 761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift;
39
+ name = AppDelegate.swift; path = MyApp/AppDelegate.swift; sourceTree = "<group>"; };
40
+ 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4;
41
+ lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = MyApp/LaunchScreen.storyboard;
42
+ sourceTree = "<group>"; };
43
+ ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference;
44
+ lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework;
45
+ path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
27
46
  /* End PBXFileReference section */
28
47
 
29
48
  /* Begin PBXFrameworksBuildPhase section */
@@ -472,4 +491,4 @@
472
491
  /* End XCConfigurationList section */
473
492
  };
474
493
  rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
475
- }
494
+ }
@@ -85,4 +85,4 @@
85
85
  buildConfiguration = "Release"
86
86
  revealArchiveInOrganizer = "YES">
87
87
  </ArchiveAction>
88
- </Scheme>
88
+ </Scheme>
@@ -31,4 +31,4 @@ target 'MyApp' do
31
31
  # :ccache_enabled => true
32
32
  )
33
33
  end
34
- end
34
+ end
@@ -3,7 +3,7 @@
3
3
  "version": "1.0.0",
4
4
  "private": true,
5
5
  "type": "module",
6
- "_comment": "dependencies 的版本号由 @flun/node-mobile-app 在 copyTemplate 阶段从主包 package.json 同步;此处 \"*\" 仅为占位,请勿依赖此文件里的值。",
6
+ "_comment": "版本号由 @flun/node-mobile-app 在 copyTemplate 阶段从主包同步;此处 \"*\" 仅为占位;",
7
7
  "dependencies": {
8
8
  "react": "*",
9
9
  "react-native": "*",