mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
feat(cli): allow using iOS device tun address for dev server (#10456)
- Changes the IP prompt to also show IPV6 address ending with ::2 (usually device's address) - Adds --host option on ios dev to force the host - Also makes it work with our own dev server impl (builtin)
This commit is contained in:
committed by
GitHub
parent
7ba67b4aca
commit
786f188923
@@ -11,8 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "../../tooling/api/dist",
|
||||
"@zerodevx/svelte-json-view": "1.0.9",
|
||||
"internal-ip": "^7.0.0"
|
||||
"@zerodevx/svelte-json-view": "1.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/codicon": "^1.1.49",
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import Unocss from 'unocss/vite'
|
||||
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
||||
import { internalIpV4Sync } from 'internal-ip'
|
||||
|
||||
const host = process.env.TAURI_DEV_HOST
|
||||
|
||||
@@ -27,13 +26,13 @@ export default defineConfig({
|
||||
clearScreen: false,
|
||||
// tauri expects a fixed port, fail if that port is not available
|
||||
server: {
|
||||
host: host ? '0.0.0.0' : false,
|
||||
host: host || false,
|
||||
port: 1420,
|
||||
strictPort: true,
|
||||
hmr: host
|
||||
? {
|
||||
protocol: 'ws',
|
||||
host: internalIpV4Sync(),
|
||||
host: host,
|
||||
port: 1430
|
||||
}
|
||||
: undefined,
|
||||
|
||||
@@ -1015,13 +1015,6 @@ 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@^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 "^5.0.0"
|
||||
|
||||
defu@^6.1.4:
|
||||
version "6.1.4"
|
||||
resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479"
|
||||
@@ -1098,7 +1091,7 @@ estree-walker@^3.0.0, estree-walker@^3.0.3:
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.0"
|
||||
|
||||
execa@^5.0.0, execa@^5.1.1:
|
||||
execa@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
|
||||
@@ -1190,26 +1183,6 @@ 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==
|
||||
|
||||
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:
|
||||
default-gateway "^6.0.3"
|
||||
ipaddr.js "^2.0.1"
|
||||
is-ip "^3.1.0"
|
||||
p-event "^4.2.0"
|
||||
|
||||
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==
|
||||
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
@@ -1229,13 +1202,6 @@ is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
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 "^4.0.0"
|
||||
|
||||
is-number@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
|
||||
@@ -1413,18 +1379,6 @@ onetime@^5.1.2:
|
||||
dependencies:
|
||||
mimic-fn "^2.1.0"
|
||||
|
||||
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:
|
||||
p-timeout "^3.1.0"
|
||||
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
|
||||
@@ -1439,13 +1393,6 @@ p-locate@^5.0.0:
|
||||
dependencies:
|
||||
p-limit "^3.0.2"
|
||||
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
|
||||
@@ -21,7 +21,7 @@ use tauri_utils::platform::Target;
|
||||
|
||||
use std::{
|
||||
env::set_current_dir,
|
||||
net::Ipv4Addr,
|
||||
net::{IpAddr, Ipv4Addr},
|
||||
process::{exit, Command, Stdio},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
@@ -82,6 +82,9 @@ pub struct Options {
|
||||
/// Specify port for the built-in dev server for static files. Defaults to 1430.
|
||||
#[clap(long, env = "TAURI_CLI_PORT")]
|
||||
pub port: Option<u16>,
|
||||
|
||||
#[clap(skip)]
|
||||
pub host: Option<IpAddr>,
|
||||
}
|
||||
|
||||
pub fn command(options: Options) -> Result<()> {
|
||||
@@ -249,8 +252,11 @@ pub fn setup(interface: &AppInterface, options: &mut Options, config: ConfigHand
|
||||
if path.exists() {
|
||||
let path = path.canonicalize()?;
|
||||
|
||||
let server_url =
|
||||
builtin_dev_server::start(path, Ipv4Addr::new(127, 0, 0, 1).into(), options.port)?;
|
||||
let ip = options
|
||||
.host
|
||||
.unwrap_or_else(|| Ipv4Addr::new(127, 0, 0, 1).into());
|
||||
|
||||
let server_url = builtin_dev_server::start(path, ip, options.port)?;
|
||||
let server_url = format!("http://{server_url}");
|
||||
dev_url = Some(server_url.parse().unwrap());
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ impl From<Options> for DevOptions {
|
||||
no_dev_server: options.no_dev_server,
|
||||
port: options.port,
|
||||
release_mode: options.release_mode,
|
||||
host: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ use cargo_mobile2::{
|
||||
|
||||
use std::{
|
||||
env::set_current_dir,
|
||||
net::{IpAddr, Ipv4Addr},
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||
sync::OnceLock,
|
||||
};
|
||||
|
||||
@@ -76,6 +76,7 @@ pub struct Options {
|
||||
#[clap(long)]
|
||||
pub force_ip_prompt: bool,
|
||||
/// Use the public network address for the development server.
|
||||
/// If an actual address it provided, it is used instead of prompting to pick one.
|
||||
///
|
||||
/// This option is particularly useful along the `--open` flag when you intend on running on a physical device.
|
||||
///
|
||||
@@ -87,7 +88,7 @@ pub struct Options {
|
||||
/// 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,
|
||||
pub host: Option<Option<IpAddr>>,
|
||||
/// Disable the built-in dev server for static files.
|
||||
#[clap(long)]
|
||||
pub no_dev_server: bool,
|
||||
@@ -110,6 +111,7 @@ impl From<Options> for DevOptions {
|
||||
no_dev_server: options.no_dev_server,
|
||||
no_dev_server_wait: options.no_dev_server_wait,
|
||||
port: options.port,
|
||||
host: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,7 +206,8 @@ fn local_ip_address(force: bool) -> &'static IpAddr {
|
||||
.map(|(_, ipaddr)| ipaddr)
|
||||
.filter(|ipaddr| match ipaddr {
|
||||
IpAddr::V4(i) => i != &Ipv4Addr::LOCALHOST,
|
||||
_ => false,
|
||||
IpAddr::V6(i) => i.to_string().ends_with("::2"),
|
||||
|
||||
})
|
||||
.collect();
|
||||
match addresses.len() {
|
||||
@@ -239,8 +242,8 @@ fn local_ip_address(force: bool) -> &'static IpAddr {
|
||||
|
||||
fn use_network_address_for_dev_url(
|
||||
config: &ConfigHandle,
|
||||
config_extension: &mut Option<ConfigValue>,
|
||||
force_ip_prompt: bool,
|
||||
options: &mut Options,
|
||||
dev_options: &mut DevOptions,
|
||||
) -> crate::Result<()> {
|
||||
let mut dev_url = config
|
||||
.lock()
|
||||
@@ -251,7 +254,7 @@ fn use_network_address_for_dev_url(
|
||||
.dev_url
|
||||
.clone();
|
||||
|
||||
if let Some(url) = &mut dev_url {
|
||||
let ip = if let Some(url) = &mut dev_url {
|
||||
let localhost = match url.host() {
|
||||
Some(url::Host::Domain(d)) => d == "localhost",
|
||||
Some(url::Host::Ipv4(i)) => {
|
||||
@@ -261,15 +264,23 @@ fn use_network_address_for_dev_url(
|
||||
};
|
||||
|
||||
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"
|
||||
let ip = options
|
||||
.host
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_else(|| *local_ip_address(options.force_ip_prompt));
|
||||
log::info!(
|
||||
"Replacing devUrl host with {ip}. {}.",
|
||||
"If your frontend is not listening on that address, try configuring your development server to use the `TAURI_DEV_HOST` environment variable or 0.0.0.0 as host"
|
||||
);
|
||||
url.set_host(Some(&ip)).unwrap();
|
||||
|
||||
if let Some(c) = config_extension {
|
||||
*url = url::Url::parse(&format!(
|
||||
"{}://{}{}",
|
||||
url.scheme(),
|
||||
SocketAddr::new(ip, url.port_or_known_default().unwrap()),
|
||||
url.path()
|
||||
))?;
|
||||
|
||||
if let Some(c) = &mut options.config {
|
||||
if let Some(build) = c
|
||||
.0
|
||||
.as_object_mut()
|
||||
@@ -282,11 +293,34 @@ fn use_network_address_for_dev_url(
|
||||
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
|
||||
})));
|
||||
options
|
||||
.config
|
||||
.replace(crate::ConfigValue(serde_json::json!({
|
||||
"build": build
|
||||
})));
|
||||
}
|
||||
reload_config(config_extension.as_ref().map(|c| &c.0))?;
|
||||
reload_config(options.config.as_ref().map(|c| &c.0))?;
|
||||
|
||||
Some(ip)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else if !dev_options.no_dev_server {
|
||||
let ip = options
|
||||
.host
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_else(|| *local_ip_address(options.force_ip_prompt));
|
||||
dev_options.host.replace(ip.clone());
|
||||
Some(ip)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(ip) = ip {
|
||||
std::env::set_var("TAURI_DEV_HOST", ip.to_string());
|
||||
if ip.is_ipv6() {
|
||||
// in this case we can't ping the server for some reason
|
||||
dev_options.no_dev_server_wait = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,14 +340,13 @@ fn run_dev(
|
||||
noise_level: NoiseLevel,
|
||||
) -> Result<()> {
|
||||
// when running on an actual device we must use the network IP
|
||||
if options.host
|
||||
if options.host.is_some()
|
||||
|| 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)?;
|
||||
use_network_address_for_dev_url(&tauri_config, &mut options, &mut dev_options)?;
|
||||
}
|
||||
|
||||
crate::dev::setup(&interface, &mut dev_options, tauri_config.clone())?;
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^1.0.1",
|
||||
"internal-ip": "^7.0.0",
|
||||
"svelte": "^3.49.0",
|
||||
"vite": "^3.0.2",
|
||||
"@tauri-apps/cli": "^2.0.0-alpha.17"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import { internalIpV4Sync } from 'internal-ip';
|
||||
|
||||
const host = process.env.TAURI_DEV_HOST;
|
||||
|
||||
@@ -13,12 +12,12 @@ export default defineConfig({
|
||||
clearScreen: false,
|
||||
// tauri expects a fixed port, fail if that port is not available
|
||||
server: {
|
||||
host: host ? "0.0.0.0" : false,
|
||||
host: host || false,
|
||||
port: 1420,
|
||||
strictPort: true,
|
||||
hmr: host ? {
|
||||
protocol: 'ws',
|
||||
host: internalIpV4Sync(),
|
||||
host,
|
||||
port: 1421
|
||||
} : undefined,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user