Kaynağa Gözat

refactor!: use localhost for development on Android devices and emulators or iOS simulators (#10437)

* feat(cli): use localhost on mobile!

* change cargo-mobile2

* use public network address on iOS device :(

* add change file

* actually breaking

* pin cargo-mobile2

* rename env var
Lucas Fernandes Nogueira 1 yıl önce
ebeveyn
işleme
7ba67b4aca

+ 9 - 0
.changes/dev-url-localhost-mobile.md

@@ -0,0 +1,9 @@
+---
+"tauri-cli": patch:breaking
+"@tauri-apps/cli": patch:breaking
+---
+
+`ios dev` and `android dev` now uses localhost for the development server unless running on an iOS device,
+which still requires connecting to the public network address. To conditionally check this on your frontend
+framework's configuration you can check for the existence of the `TAURI_DEV_HOST`
+environment variable instead of checking if the target is iOS or Android (previous recommendation).

+ 2 - 2
examples/api/package.json

@@ -11,14 +11,14 @@
   },
   "dependencies": {
     "@tauri-apps/api": "../../tooling/api/dist",
-    "@zerodevx/svelte-json-view": "1.0.9"
+    "@zerodevx/svelte-json-view": "1.0.9",
+    "internal-ip": "^7.0.0"
   },
   "devDependencies": {
     "@iconify-json/codicon": "^1.1.49",
     "@iconify-json/ph": "^1.1.13",
     "@sveltejs/vite-plugin-svelte": "^3.1.1",
     "@unocss/extractor-svelte": "^0.61.0",
-    "internal-ip": "^8.0.0",
     "svelte": "^4.2.18",
     "unocss": "^0.61.0",
     "vite": "^5.3.2"

+ 4 - 4
examples/api/vite.config.js

@@ -7,7 +7,7 @@ import Unocss from 'unocss/vite'
 import { svelte } from '@sveltejs/vite-plugin-svelte'
 import { internalIpV4Sync } from 'internal-ip'
 
-const mobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM)
+const host = process.env.TAURI_DEV_HOST
 
 // https://vitejs.dev/config/
 export default defineConfig({
@@ -27,13 +27,13 @@ export default defineConfig({
   clearScreen: false,
   // tauri expects a fixed port, fail if that port is not available
   server: {
-    host: mobile ? '0.0.0.0' : false,
+    host: host ? '0.0.0.0' : false,
     port: 1420,
     strictPort: true,
-    hmr: mobile
+    hmr: host
       ? {
           protocol: 'ws',
-          host: mobile ? internalIpV4Sync() : 'localhost',
+          host: internalIpV4Sync(),
           port: 1430
         }
       : undefined,

+ 45 - 153
examples/api/yarn.lock

@@ -624,7 +624,7 @@
     vitefu "^0.2.5"
 
 "@tauri-apps/api@../../tooling/api/dist":
-  version "2.0.0-beta.13"
+  version "2.0.0-beta.15"
 
 "@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0", "@types/estree@^1.0.1":
   version "1.0.5"
@@ -943,30 +943,6 @@ chokidar@^3.6.0:
   optionalDependencies:
     fsevents "~2.3.2"
 
-cidr-regex@4.0.3:
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-4.0.3.tgz#07b52c9762d1ff546a50740e92fc2b5b13a6d871"
-  integrity sha512-HOwDIy/rhKeMf6uOzxtv7FAbrz8zPjmVKfSpM+U7/bNBXC5rtOyr758jxcptiSx6ZZn5LOhPJT5WWxPAGDV8dw==
-  dependencies:
-    ip-regex "^5.0.0"
-
-cidr-tools@^6.4.1:
-  version "6.4.2"
-  resolved "https://registry.yarnpkg.com/cidr-tools/-/cidr-tools-6.4.2.tgz#c47fa24128497d7482f446e883c5e69befa33030"
-  integrity sha512-KZC8t2ipCqU2M+ISmTxRDGu9bku5MRU3V1cWyGEFJTZEzRhGvBJvVsbpZO5UAu12fExRFihtYGXAlgFFpmK9jw==
-  dependencies:
-    cidr-regex "4.0.3"
-    ip-bigint "7.3.0"
-    ip-regex "5.0.0"
-    string-natural-compare "3.0.1"
-
-clone-regexp@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-3.0.0.tgz#c6dd5c6b85482306778f3dc4ac2bb967079069c2"
-  integrity sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==
-  dependencies:
-    is-regexp "^3.0.0"
-
 code-red@^1.0.3:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/code-red/-/code-red-1.0.4.tgz#59ba5c9d1d320a4ef795bc10a28bd42bfebe3e35"
@@ -1005,11 +981,6 @@ consola@^3.2.3:
   resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f"
   integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==
 
-convert-hrtime@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-5.0.0.tgz#f2131236d4598b95de856926a67100a0a97e9fa3"
-  integrity sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==
-
 convert-source-map@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
@@ -1044,12 +1015,12 @@ deepmerge@^4.3.1:
   resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
   integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
 
-default-gateway@^7.2.2:
-  version "7.2.2"
-  resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-7.2.2.tgz#85e6d88fde0f58703bab7744ed9d5330fa6b3f6c"
-  integrity sha512-AD7TrdNNPXRZIGw63dw+lnGmT4v7ggZC5NHNJgAYWm5njrwoze1q5JSAW9YuLy2tjnoLUG/r8FEB93MCh9QJPg==
+default-gateway@^6.0.3:
+  version "6.0.3"
+  resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71"
+  integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==
   dependencies:
-    execa "^7.1.1"
+    execa "^5.0.0"
 
 defu@^6.1.4:
   version "6.1.4"
@@ -1127,7 +1098,7 @@ estree-walker@^3.0.0, estree-walker@^3.0.3:
   dependencies:
     "@types/estree" "^1.0.0"
 
-execa@^5.1.1:
+execa@^5.0.0, execa@^5.1.1:
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
   integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
@@ -1142,21 +1113,6 @@ execa@^5.1.1:
     signal-exit "^3.0.3"
     strip-final-newline "^2.0.0"
 
-execa@^7.1.1:
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9"
-  integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==
-  dependencies:
-    cross-spawn "^7.0.3"
-    get-stream "^6.0.1"
-    human-signals "^4.3.0"
-    is-stream "^3.0.0"
-    merge-stream "^2.0.0"
-    npm-run-path "^5.1.0"
-    onetime "^6.0.0"
-    signal-exit "^3.0.7"
-    strip-final-newline "^3.0.0"
-
 fast-glob@^3.3.2:
   version "3.3.2"
   resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
@@ -1195,17 +1151,12 @@ fsevents@~2.3.2, fsevents@~2.3.3:
   resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
   integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
 
-function-timeout@^0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/function-timeout/-/function-timeout-0.1.1.tgz#6bf71d3d24c894d43b2bec312cabb8c5add2e9da"
-  integrity sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==
-
 gensync@^1.0.0-beta.2:
   version "1.0.0-beta.2"
   resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
   integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
 
-get-stream@^6.0.0, get-stream@^6.0.1:
+get-stream@^6.0.0:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
   integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
@@ -1239,30 +1190,25 @@ human-signals@^2.1.0:
   resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
   integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
 
-human-signals@^4.3.0:
-  version "4.3.1"
-  resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2"
-  integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==
-
-internal-ip@^8.0.0:
-  version "8.0.0"
-  resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-8.0.0.tgz#9c998de890def7571d81e4366179e89c63d197fe"
-  integrity sha512-e6c3zxr9COnnc29PIz9LffmALOt0XhIJdR7f83DyHcQksL3B40KGmU3Sr1lrHja3i7Zyqo+AbwKZ+nZiMvg/OA==
+internal-ip@^7.0.0:
+  version "7.0.0"
+  resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-7.0.0.tgz#5b1c6a9d7e188aa73a1b69717daf50c8d8ed774f"
+  integrity sha512-qE4TeD4brqC45Vq/+VASeMiS1KRyfBkR6HT2sh9pZVVCzSjPkaCEfKFU+dL0PRv7NHJtvoKN2r82G6wTfzorkw==
   dependencies:
-    cidr-tools "^6.4.1"
-    default-gateway "^7.2.2"
-    is-ip "^5.0.0"
-    p-event "^5.0.1"
+    default-gateway "^6.0.3"
+    ipaddr.js "^2.0.1"
+    is-ip "^3.1.0"
+    p-event "^4.2.0"
 
-ip-bigint@7.3.0:
-  version "7.3.0"
-  resolved "https://registry.yarnpkg.com/ip-bigint/-/ip-bigint-7.3.0.tgz#31cdcc86134ac0d461780330bbbcff46ffa3117b"
-  integrity sha512-2qVAe0Q9+Y+5nGvmogwK9y4kefD5Ks5l/IG0Jo1lhU9gIF34jifhqrwXwzkIl+LC594Q6SyAlngs4p890xsXVw==
+ip-regex@^4.0.0:
+  version "4.3.0"
+  resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
+  integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
 
-ip-regex@5.0.0, ip-regex@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-5.0.0.tgz#cd313b2ae9c80c07bd3851e12bf4fa4dc5480632"
-  integrity sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==
+ipaddr.js@^2.0.1:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8"
+  integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==
 
 is-binary-path@~2.1.0:
   version "2.1.0"
@@ -1283,13 +1229,12 @@ is-glob@^4.0.1, is-glob@~4.0.1:
   dependencies:
     is-extglob "^2.1.1"
 
-is-ip@^5.0.0:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-5.0.1.tgz#bec44442c823e591aa6f4d6fb9081d6a9be17e44"
-  integrity sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==
+is-ip@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8"
+  integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==
   dependencies:
-    ip-regex "^5.0.0"
-    super-regex "^0.2.0"
+    ip-regex "^4.0.0"
 
 is-number@^7.0.0:
   version "7.0.0"
@@ -1303,21 +1248,11 @@ is-reference@^3.0.0, is-reference@^3.0.1:
   dependencies:
     "@types/estree" "*"
 
-is-regexp@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-3.1.0.tgz#0235eab9cda5b83f96ac4a263d8c32c9d5ad7422"
-  integrity sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==
-
 is-stream@^2.0.0:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
   integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
 
-is-stream@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac"
-  integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
-
 isexe@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -1415,11 +1350,6 @@ mimic-fn@^2.1.0:
   resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
   integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
 
-mimic-fn@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc"
-  integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
-
 mlly@^1.4.2, mlly@^1.6.1, mlly@^1.7.0:
   version "1.7.1"
   resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.1.tgz#e0336429bb0731b6a8e887b438cbdae522c8f32f"
@@ -1467,13 +1397,6 @@ npm-run-path@^4.0.1:
   dependencies:
     path-key "^3.0.0"
 
-npm-run-path@^5.1.0:
-  version "5.3.0"
-  resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f"
-  integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==
-  dependencies:
-    path-key "^4.0.0"
-
 ofetch@^1.3.4:
   version "1.3.4"
   resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.3.4.tgz#7ea65ced3c592ec2b9906975ae3fe1d26a56f635"
@@ -1490,19 +1413,17 @@ onetime@^5.1.2:
   dependencies:
     mimic-fn "^2.1.0"
 
-onetime@^6.0.0:
-  version "6.0.0"
-  resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4"
-  integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
+p-event@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5"
+  integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==
   dependencies:
-    mimic-fn "^4.0.0"
+    p-timeout "^3.1.0"
 
-p-event@^5.0.1:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/p-event/-/p-event-5.0.1.tgz#614624ec02ae7f4f13d09a721c90586184af5b0c"
-  integrity sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==
-  dependencies:
-    p-timeout "^5.0.2"
+p-finally@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
+  integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
 
 p-limit@^3.0.2:
   version "3.1.0"
@@ -1518,10 +1439,12 @@ p-locate@^5.0.0:
   dependencies:
     p-limit "^3.0.2"
 
-p-timeout@^5.0.2:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-5.1.0.tgz#b3c691cf4415138ce2d9cfe071dba11f0fee085b"
-  integrity sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==
+p-timeout@^3.1.0:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe"
+  integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==
+  dependencies:
+    p-finally "^1.0.0"
 
 path-exists@^4.0.0:
   version "4.0.0"
@@ -1533,11 +1456,6 @@ path-key@^3.0.0, path-key@^3.1.0:
   resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
   integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
 
-path-key@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18"
-  integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
-
 pathe@^1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec"
@@ -1651,7 +1569,7 @@ shebang-regex@^3.0.0:
   resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
   integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
 
-signal-exit@^3.0.3, signal-exit@^3.0.7:
+signal-exit@^3.0.3:
   version "3.0.7"
   resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
   integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
@@ -1670,30 +1588,11 @@ source-map-js@^1.0.1, source-map-js@^1.2.0:
   resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
   integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
 
-string-natural-compare@3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
-  integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
-
 strip-final-newline@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
   integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
 
-strip-final-newline@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd"
-  integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
-
-super-regex@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/super-regex/-/super-regex-0.2.0.tgz#dc1e071e55cdcf56930eb6271f73653a655b2642"
-  integrity sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==
-  dependencies:
-    clone-regexp "^3.0.0"
-    function-timeout "^0.1.0"
-    time-span "^5.1.0"
-
 supports-color@^5.3.0:
   version "5.5.0"
   resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@@ -1726,13 +1625,6 @@ svelte@^4.2.18:
     magic-string "^0.30.4"
     periscopic "^3.1.0"
 
-time-span@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/time-span/-/time-span-5.1.0.tgz#80c76cf5a0ca28e0842d3f10a4e99034ce94b90d"
-  integrity sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==
-  dependencies:
-    convert-hrtime "^5.0.0"
-
 to-fast-properties@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"

+ 2 - 2
tooling/cli/Cargo.lock

@@ -498,9 +498,9 @@ dependencies = [
 
 [[package]]
 name = "cargo-mobile2"
-version = "0.12.2"
+version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e97b88fcfd9ecf65a09ecc40fa8bd4a4f0118bbd9867e3c3f8766422c12a956a"
+checksum = "06f70f6ff0db884929c9b3b7825031607e2800e40ce1569e8f9c6a58bd82eae8"
 dependencies = [
  "colored",
  "core-foundation",

+ 1 - 1
tooling/cli/Cargo.toml

@@ -39,7 +39,7 @@ name = "cargo-tauri"
 path = "src/main.rs"
 
 [dependencies]
-cargo-mobile2 = { version = "0.12.1", default-features = false }
+cargo-mobile2 = { version = "0.13", default-features = false }
 jsonrpsee = { version = "0.22", features = [ "server" ] }
 jsonrpsee-core = "0.22"
 jsonrpsee-client-transport = { version = "0.22", features = [ "ws" ] }

+ 7 - 88
tooling/cli/src/dev.rs

@@ -21,7 +21,7 @@ use tauri_utils::platform::Target;
 
 use std::{
   env::set_current_dir,
-  net::{IpAddr, Ipv4Addr},
+  net::Ipv4Addr,
   process::{exit, Command, Stdio},
   sync::{
     atomic::{AtomicBool, Ordering},
@@ -75,9 +75,6 @@ pub struct Options {
   /// Disable the file watcher.
   #[clap(long)]
   pub no_watch: bool,
-  /// Force prompting for an IP to use to connect to the dev server on mobile.
-  #[clap(long)]
-  pub force_ip_prompt: bool,
 
   /// Disable the built-in dev server for static files.
   #[clap(long)]
@@ -109,7 +106,7 @@ fn command_internal(mut options: Options) -> Result<()> {
     options.target.clone(),
   )?;
 
-  setup(&interface, &mut options, config, false)?;
+  setup(&interface, &mut options, config)?;
 
   let exit_on_panic = options.exit_on_panic;
   let no_watch = options.no_watch;
@@ -118,67 +115,10 @@ fn command_internal(mut options: Options) -> Result<()> {
   })
 }
 
-pub fn local_ip_address(force: bool) -> &'static IpAddr {
-  static LOCAL_IP: OnceLock<IpAddr> = OnceLock::new();
-  LOCAL_IP.get_or_init(|| {
-    let prompt_for_ip = || {
-      let addresses: Vec<IpAddr> = local_ip_address::list_afinet_netifas()
-        .expect("failed to list networks")
-        .into_iter()
-        .map(|(_, ipaddr)| ipaddr)
-        .filter(|ipaddr| match ipaddr {
-          IpAddr::V4(i) => i != &Ipv4Addr::LOCALHOST,
-          _ => false,
-        })
-        .collect();
-      match addresses.len() {
-        0 => panic!("No external IP detected."),
-        1 => {
-          let ipaddr = addresses.first().unwrap();
-          *ipaddr
-        }
-        _ => {
-          let selected = dialoguer::Select::with_theme(&dialoguer::theme::ColorfulTheme::default())
-            .with_prompt(
-              "Failed to detect external IP, What IP should we use to access your development server?",
-            )
-            .items(&addresses)
-            .default(0)
-            .interact()
-            .expect("failed to select external IP");
-          *addresses.get(selected).unwrap()
-        }
-      }
-    };
-
-    let ip = if force {
-      prompt_for_ip()
-    } else {
-      local_ip_address::local_ip().unwrap_or_else(|_| prompt_for_ip())
-    };
-    log::info!("Using {ip} to access the development server.");
-    ip
-  })
-}
-
-pub fn setup(
-  interface: &AppInterface,
-  options: &mut Options,
-  config: ConfigHandle,
-  mobile: bool,
-) -> Result<()> {
+pub fn setup(interface: &AppInterface, options: &mut Options, config: ConfigHandle) -> Result<()> {
   let tauri_path = tauri_dir();
   set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;
 
-  let mut dev_url = config
-    .lock()
-    .unwrap()
-    .as_ref()
-    .unwrap()
-    .build
-    .dev_url
-    .clone();
-
   if let Some(before_dev) = config
     .lock()
     .unwrap()
@@ -196,25 +136,7 @@ pub fn setup(
       }
     };
     let cwd = script_cwd.unwrap_or_else(|| app_dir().clone());
-    if let Some(mut before_dev) = script {
-      if before_dev.contains("$HOST") {
-        if mobile {
-          let local_ip_address = local_ip_address(options.force_ip_prompt).to_string();
-          before_dev = before_dev.replace("$HOST", &local_ip_address);
-          if let Some(url) = &mut dev_url {
-            url.set_host(Some(&local_ip_address))?;
-          }
-        } else {
-          before_dev = before_dev.replace(
-            "$HOST",
-            if let Some(url) = &dev_url {
-              url.host_str().unwrap_or("127.0.0.1")
-            } else {
-              "127.0.0.1"
-            },
-          );
-        }
-      }
+    if let Some(before_dev) = script {
       log::info!(action = "Running"; "BeforeDevCommand (`{}`)", before_dev);
       let mut env = command_env(true);
       env.extend(interface.env());
@@ -326,12 +248,9 @@ pub fn setup(
     if let Some(FrontendDist::Directory(path)) = &frontend_dist {
       if path.exists() {
         let path = path.canonicalize()?;
-        let ip = if mobile {
-          *local_ip_address(options.force_ip_prompt)
-        } else {
-          Ipv4Addr::new(127, 0, 0, 1).into()
-        };
-        let server_url = builtin_dev_server::start(path, ip, options.port)?;
+
+        let server_url =
+          builtin_dev_server::start(path, Ipv4Addr::new(127, 0, 0, 1).into(), options.port)?;
         let server_url = format!("http://{server_url}");
         dev_url = Some(server_url.parse().unwrap());
 

+ 17 - 13
tooling/cli/src/mobile/android/dev.rs

@@ -4,7 +4,7 @@
 
 use super::{
   configure_cargo, delete_codegen_vars, device_prompt, ensure_init, env, get_app, get_config,
-  inject_assets, open_and_wait, setup_dev_config, MobileTarget,
+  inject_assets, open_and_wait, MobileTarget,
 };
 use crate::{
   dev::Options as DevOptions,
@@ -22,6 +22,7 @@ use clap::{ArgAction, Parser};
 use anyhow::Context;
 use cargo_mobile2::{
   android::{
+    adb,
     config::{Config as AndroidConfig, Metadata as AndroidMetadata},
     device::Device,
     env::Env,
@@ -63,9 +64,6 @@ pub struct Options {
   pub open: bool,
   /// Runs on the given device name
   pub device: Option<String>,
-  /// Force prompting for an IP to use to connect to the dev server on mobile.
-  #[clap(long)]
-  pub force_ip_prompt: bool,
   /// Disable the built-in dev server for static files.
   #[clap(long)]
   pub no_dev_server: bool,
@@ -87,7 +85,6 @@ impl From<Options> for DevOptions {
       no_dev_server_wait: options.no_dev_server_wait,
       no_dev_server: options.no_dev_server,
       port: options.port,
-      force_ip_prompt: options.force_ip_prompt,
       release_mode: options.release_mode,
     }
   }
@@ -166,7 +163,7 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
 #[allow(clippy::too_many_arguments)]
 fn run_dev(
   mut interface: AppInterface,
-  mut options: Options,
+  options: Options,
   mut dev_options: DevOptions,
   tauri_config: ConfigHandle,
   device: Option<Device>,
@@ -176,13 +173,7 @@ fn run_dev(
   metadata: &AndroidMetadata,
   noise_level: NoiseLevel,
 ) -> Result<()> {
-  setup_dev_config(
-    MobileTarget::Android,
-    &mut options.config,
-    options.force_ip_prompt,
-  )?;
-
-  crate::dev::setup(&interface, &mut dev_options, tauri_config.clone(), true)?;
+  crate::dev::setup(&interface, &mut dev_options, tauri_config.clone())?;
 
   let interface_options = InterfaceOptions {
     debug: !dev_options.release_mode,
@@ -216,6 +207,19 @@ fn run_dev(
     },
   )?;
 
+  let dev_url = tauri_config
+    .lock()
+    .unwrap()
+    .as_ref()
+    .unwrap()
+    .build
+    .dev_url
+    .clone();
+  if let Some(port) = dev_url.and_then(|url| url.port_or_known_default()) {
+    let forward = format!("tcp:{port}");
+    adb::adb(&env, ["reverse", &forward, &forward]).run()?;
+  }
+
   let open = options.open;
   let exit_on_panic = options.exit_on_panic;
   let no_watch = options.no_watch;

+ 1 - 1
tooling/cli/src/mobile/android/mod.rs

@@ -29,7 +29,7 @@ use sublime_fuzzy::best_match;
 use super::{
   ensure_init, get_app,
   init::{command as init_command, configure_cargo},
-  log_finished, read_options, setup_dev_config, CliOptions, OptionsHandle, Target as MobileTarget,
+  log_finished, read_options, CliOptions, OptionsHandle, Target as MobileTarget,
   MIN_DEVICE_MATCH_SCORE,
 };
 use crate::{helpers::config::Config as TauriConfig, Result};

+ 142 - 12
tooling/cli/src/mobile/ios/dev.rs

@@ -4,13 +4,13 @@
 
 use super::{
   configure_cargo, device_prompt, ensure_init, env, get_app, get_config, inject_assets,
-  merge_plist, open_and_wait, setup_dev_config, MobileTarget,
+  merge_plist, open_and_wait, MobileTarget,
 };
 use crate::{
   dev::Options as DevOptions,
   helpers::{
     app_paths::tauri_dir,
-    config::{get as get_tauri_config, ConfigHandle},
+    config::{get as get_tauri_config, reload as reload_config, ConfigHandle},
     flock,
   },
   interface::{AppInterface, AppSettings, Interface, MobileOptions, Options as InterfaceOptions},
@@ -21,18 +21,32 @@ use clap::{ArgAction, Parser};
 
 use anyhow::Context;
 use cargo_mobile2::{
-  apple::{config::Config as AppleConfig, device::Device},
+  apple::{
+    config::Config as AppleConfig,
+    device::{Device, DeviceKind},
+  },
   config::app::App,
   env::Env,
   opts::{NoiseLevel, Profile},
 };
 
-use std::env::set_current_dir;
+use std::{
+  env::set_current_dir,
+  net::{IpAddr, Ipv4Addr},
+  sync::OnceLock,
+};
 
 #[derive(Debug, Clone, Parser)]
 #[clap(
   about = "Run your app in development mode on iOS",
-  long_about = "Run your app in development mode on iOS with hot-reloading for the Rust code. It makes use of the `build.devUrl` property from your `tauri.conf.json` file. It also runs your `build.beforeDevCommand` which usually starts your frontend devServer."
+  long_about = "Run your app in development mode on iOS with hot-reloading for the Rust code.
+It makes use of the `build.devUrl` property from your `tauri.conf.json` file.
+It also runs your `build.beforeDevCommand` which usually starts your frontend devServer.
+
+When connected to a physical iOS device, the public network address must be used instead of `localhost`
+for the devUrl property. Tauri makes that change automatically, but your dev server might need
+a different configuration to listen on the public address. You can check the `TAURI_DEV_HOST`
+environment variable to determine whether the public network should be used or not."
 )]
 pub struct Options {
   /// List of cargo features to activate
@@ -61,6 +75,19 @@ pub struct Options {
   /// Force prompting for an IP to use to connect to the dev server on mobile.
   #[clap(long)]
   pub force_ip_prompt: bool,
+  /// Use the public network address for the development server.
+  ///
+  /// This option is particularly useful along the `--open` flag when you intend on running on a physical device.
+  ///
+  /// This replaces the devUrl configuration value to match the public network address host,
+  /// it is your responsability to set up your development server to listen on this address
+  /// by using 0.0.0.0 as host for instance.
+  ///
+  /// When this is set or when running on an iOS device the CLI sets the `TAURI_DEV_HOST`
+  /// environment variable so you can check this on your framework's configuration to expose the development server
+  /// on the public network address.
+  #[clap(long)]
+  pub host: bool,
   /// Disable the built-in dev server for static files.
   #[clap(long)]
   pub no_dev_server: bool,
@@ -83,7 +110,6 @@ impl From<Options> for DevOptions {
       no_dev_server: options.no_dev_server,
       no_dev_server_wait: options.no_dev_server_wait,
       port: options.port,
-      force_ip_prompt: options.force_ip_prompt,
     }
   }
 }
@@ -168,6 +194,105 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
   )
 }
 
+fn local_ip_address(force: bool) -> &'static IpAddr {
+  static LOCAL_IP: OnceLock<IpAddr> = OnceLock::new();
+  LOCAL_IP.get_or_init(|| {
+    let prompt_for_ip = || {
+      let addresses: Vec<IpAddr> = local_ip_address::list_afinet_netifas()
+        .expect("failed to list networks")
+        .into_iter()
+        .map(|(_, ipaddr)| ipaddr)
+        .filter(|ipaddr| match ipaddr {
+          IpAddr::V4(i) => i != &Ipv4Addr::LOCALHOST,
+          _ => false,
+        })
+        .collect();
+      match addresses.len() {
+        0 => panic!("No external IP detected."),
+        1 => {
+          let ipaddr = addresses.first().unwrap();
+          *ipaddr
+        }
+        _ => {
+          let selected = dialoguer::Select::with_theme(&dialoguer::theme::ColorfulTheme::default())
+            .with_prompt(
+              "Failed to detect external IP, What IP should we use to access your development server?",
+            )
+            .items(&addresses)
+            .default(0)
+            .interact()
+            .expect("failed to select external IP");
+          *addresses.get(selected).unwrap()
+        }
+      }
+    };
+
+    let ip = if force {
+      prompt_for_ip()
+    } else {
+      local_ip_address::local_ip().unwrap_or_else(|_| prompt_for_ip())
+    };
+    log::info!("Using {ip} to access the development server.");
+    ip
+  })
+}
+
+fn use_network_address_for_dev_url(
+  config: &ConfigHandle,
+  config_extension: &mut Option<ConfigValue>,
+  force_ip_prompt: bool,
+) -> crate::Result<()> {
+  let mut dev_url = config
+    .lock()
+    .unwrap()
+    .as_ref()
+    .unwrap()
+    .build
+    .dev_url
+    .clone();
+
+  if let Some(url) = &mut dev_url {
+    let localhost = match url.host() {
+      Some(url::Host::Domain(d)) => d == "localhost",
+      Some(url::Host::Ipv4(i)) => {
+        i == std::net::Ipv4Addr::LOCALHOST || i == std::net::Ipv4Addr::UNSPECIFIED
+      }
+      _ => false,
+    };
+
+    if localhost {
+      let ip = local_ip_address(force_ip_prompt).to_string();
+      println!(
+        "Replacing devUrl host with {ip}. {}. {}.",
+        "If your frontend is not listening on that address, try configuring your development server to use 0.0.0.0 as host",
+        "When this is required, Tauri sets the TAURI_DEV_HOST environment variable"
+      );
+      url.set_host(Some(&ip)).unwrap();
+
+      if let Some(c) = config_extension {
+        if let Some(build) = c
+          .0
+          .as_object_mut()
+          .and_then(|root| root.get_mut("build"))
+          .and_then(|build| build.as_object_mut())
+        {
+          build.insert("devUrl".into(), url.to_string().into());
+        }
+      } else {
+        let mut build = serde_json::Map::new();
+        build.insert("devUrl".into(), url.to_string().into());
+
+        config_extension.replace(crate::ConfigValue(serde_json::json!({
+          "build": build
+        })));
+      }
+      reload_config(config_extension.as_ref().map(|c| &c.0))?;
+    }
+  }
+
+  Ok(())
+}
+
 #[allow(clippy::too_many_arguments)]
 fn run_dev(
   mut interface: AppInterface,
@@ -180,13 +305,18 @@ fn run_dev(
   config: &AppleConfig,
   noise_level: NoiseLevel,
 ) -> Result<()> {
-  setup_dev_config(
-    MobileTarget::Ios,
-    &mut options.config,
-    options.force_ip_prompt,
-  )?;
+  // when running on an actual device we must use the network IP
+  if options.host
+    || device
+      .as_ref()
+      .map(|device| !matches!(device.kind(), DeviceKind::Simulator))
+      .unwrap_or(false)
+  {
+    std::env::set_var("TAURI_DEV_HOST", "true");
+    use_network_address_for_dev_url(&tauri_config, &mut options.config, options.force_ip_prompt)?;
+  }
 
-  crate::dev::setup(&interface, &mut dev_options, tauri_config.clone(), true)?;
+  crate::dev::setup(&interface, &mut dev_options, tauri_config.clone())?;
 
   let app_settings = interface.app_settings();
   let bin_path = app_settings.app_binary_path(&InterfaceOptions {

+ 1 - 1
tooling/cli/src/mobile/ios/mod.rs

@@ -24,7 +24,7 @@ use sublime_fuzzy::best_match;
 use super::{
   ensure_init, env, get_app,
   init::{command as init_command, configure_cargo},
-  log_finished, read_options, setup_dev_config, CliOptions, OptionsHandle, Target as MobileTarget,
+  log_finished, read_options, CliOptions, OptionsHandle, Target as MobileTarget,
   MIN_DEVICE_MATCH_SCORE,
 };
 use crate::{

+ 1 - 58
tooling/cli/src/mobile/mod.rs

@@ -3,12 +3,8 @@
 // SPDX-License-Identifier: MIT
 
 use crate::{
-  helpers::{
-    app_paths::tauri_dir,
-    config::{get as get_config, reload as reload_config, Config as TauriConfig},
-  },
+  helpers::{app_paths::tauri_dir, config::Config as TauriConfig},
   interface::{AppInterface, AppSettings, DevProcess, Interface, Options as InterfaceOptions},
-  ConfigValue,
 };
 use anyhow::{bail, Result};
 use heck::ToSnekCase;
@@ -152,59 +148,6 @@ impl Default for CliOptions {
   }
 }
 
-fn setup_dev_config(
-  target: Target,
-  config_extension: &mut Option<ConfigValue>,
-  force_ip_prompt: bool,
-) -> crate::Result<()> {
-  let config = get_config(
-    target.platform_target(),
-    config_extension.as_ref().map(|c| &c.0),
-  )?;
-
-  let mut dev_url = config
-    .lock()
-    .unwrap()
-    .as_ref()
-    .unwrap()
-    .build
-    .dev_url
-    .clone();
-
-  if let Some(url) = &mut dev_url {
-    let localhost = match url.host() {
-      Some(url::Host::Domain(d)) => d == "localhost",
-      Some(url::Host::Ipv4(i)) => {
-        i == std::net::Ipv4Addr::LOCALHOST || i == std::net::Ipv4Addr::UNSPECIFIED
-      }
-      _ => false,
-    };
-    if localhost {
-      let ip = crate::dev::local_ip_address(force_ip_prompt);
-      url.set_host(Some(&ip.to_string())).unwrap();
-      if let Some(c) = config_extension {
-        if let Some(build) = c
-          .0
-          .as_object_mut()
-          .and_then(|root| root.get_mut("build"))
-          .and_then(|build| build.as_object_mut())
-        {
-          build.insert("devUrl".into(), url.to_string().into());
-        }
-      } else {
-        config_extension.replace(crate::ConfigValue(serde_json::json!({
-          "build": {
-            "devUrl": url
-          }
-        })));
-      }
-      reload_config(config_extension.as_ref().map(|c| &c.0))?;
-    }
-  }
-
-  Ok(())
-}
-
 fn env_vars() -> HashMap<String, OsString> {
   let mut vars = HashMap::new();
   vars.insert("RUST_LOG_STYLE".into(), "always".into());

+ 4 - 4
tooling/cli/templates/plugin/__example-api/tauri-app/vite.config.js

@@ -1,8 +1,8 @@
 import { defineConfig } from "vite";
 import { svelte } from "@sveltejs/vite-plugin-svelte";
-import { internalIpV4Sync } from 'internal-ip'
+import { internalIpV4Sync } from 'internal-ip';
 
-const mobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM);
+const host = process.env.TAURI_DEV_HOST;
 
 // https://vitejs.dev/config/
 export default defineConfig({
@@ -13,10 +13,10 @@ export default defineConfig({
   clearScreen: false,
   // tauri expects a fixed port, fail if that port is not available
   server: {
-    host: mobile ? "0.0.0.0" : false,
+    host: host ? "0.0.0.0" : false,
     port: 1420,
     strictPort: true,
-    hmr: mobile ? {
+    hmr: host ? {
       protocol: 'ws',
       host: internalIpV4Sync(),
       port: 1421