Skip to content

dx eject for IOS and Andriod #4274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/src/build/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ fn find_wasm_symbol_offsets<'a, R: ReadRef<'a>>(

/// Find all assets in the given file, hash them, and write them back to the file.
/// Then return an `AssetManifest` containing all the assets found in the file.
pub(crate) fn extract_assets_from_file(path: impl AsRef<Path>) -> Result<AssetManifest> {
pub fn extract_assets_from_file(path: impl AsRef<Path>) -> Result<AssetManifest> {
let path = path.as_ref();
let mut file = std::fs::File::options().write(true).read(true).open(path)?;
let mut file_contents = Vec::new();
Expand Down
106 changes: 106 additions & 0 deletions packages/cli/src/build/ejected_assets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use std::path::{Path, PathBuf};

/// Utility struct for working with ejected assets
pub struct EjectedAssets {
project_dir: PathBuf,
}

impl EjectedAssets {
/// Create a new EjectedAssets instance with a specific project directory
pub fn with_project_dir(project_dir: PathBuf) -> Self {
Self { project_dir }
}

/// Get the ejected path for an asset if it exists
pub fn get_ejected_path(&self, asset_path: &str) -> Option<PathBuf> {
self.resolve_asset_path(asset_path)
}

/// Resolve the asset path
pub fn resolve_asset_path(&self, asset_path: &str) -> Option<PathBuf> {
if asset_path.contains("android") {
if let Some(android_dir) = Self::android_assets_dir(&self.project_dir) {
let relative_path = asset_path.split('/').last()?;
let ejected_path = android_dir.join(relative_path);
if ejected_path.exists() {
tracing::info!(dx_src = ?crate::logging::TraceSrc::Dev, "Using ejected Android asset: {}", ejected_path.display());
return Some(ejected_path);
}
}
} else if asset_path.contains("ios") {
if let Some(ios_dir) = Self::ios_assets_dir(&self.project_dir) {
let relative_path = asset_path.split('/').last()?;
let ejected_path = ios_dir.join(relative_path);
if ejected_path.exists() {
tracing::info!(dx_src = ?crate::logging::TraceSrc::Dev, "Using ejected iOS asset: {}", ejected_path.display());
return Some(ejected_path);
}
}
}

tracing::info!(dx_src = ?crate::logging::TraceSrc::Dev, "Using internal asset: {}", asset_path);

None
}

/// Check if there are ejected assets in the project directory
pub fn has_ejected_assets(project_dir: &Path) -> bool {
Self::android_assets_dir(project_dir).is_some() || Self::ios_assets_dir(project_dir).is_some()
}

/// Check if there are ejected Android assets in the project directory
pub fn android_assets_dir(project_dir: &Path) -> Option<PathBuf> {
// First check for root-level android folder
let android_dir_root = project_dir.join("android");
if android_dir_root.exists() && android_dir_root.is_dir() {
return Some(android_dir_root);
}

// Fall back to assets/android for backward compatibility
let android_dir = project_dir.join("assets").join("android");
if android_dir.exists() && android_dir.is_dir() {
Some(android_dir)
} else {
None
}
}

/// Check if there are ejected iOS assets in the project directory
pub fn ios_assets_dir(project_dir: &Path) -> Option<PathBuf> {
// First check for root-level ios folder
let ios_dir_root = project_dir.join("ios");
if ios_dir_root.exists() && ios_dir_root.is_dir() {
return Some(ios_dir_root);
}

// Fall back to assets/ios for backward compatibility
let ios_dir = project_dir.join("assets").join("ios");
if ios_dir.exists() && ios_dir.is_dir() {
Some(ios_dir)
} else {
None
}
}

/// Get the ejected assets directory for a specific platform
///
/// # Arguments
///
/// * `project_dir` - The project directory
/// * `platform` - The platform name ("android" or "ios")
pub fn platform_assets_dir(project_dir: &Path, platform: &str) -> Option<PathBuf> {
// First check for root-level platform folder
let platform_dir_root = project_dir.join(platform);
if platform_dir_root.exists() && platform_dir_root.is_dir() {
return Some(platform_dir_root);
}

// Fall back to assets/platform for backward compatibility
let platform_dir = project_dir.join("assets").join(platform);
if platform_dir.exists() && platform_dir.is_dir() {
Some(platform_dir)
} else {
None
}
}
}
4 changes: 3 additions & 1 deletion packages/cli/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
mod assets;
mod builder;
mod context;
pub mod ejected_assets;
mod patch;
mod pre_render;
mod request;
mod tools;

pub(crate) use assets::*;
pub(crate) use builder::*;
pub(crate) use context::*;
pub(crate) use ejected_assets::EjectedAssets;
pub(crate) use patch::*;
pub(crate) use pre_render::*;
pub(crate) use request::*;
pub(crate) use tools::*;
pub use assets::extract_assets_from_file;
Loading