From b36836c493d61ee280137599c040d8354dd0826b Mon Sep 17 00:00:00 2001 From: hrmny <8845940+ForsakenHarmony@users.noreply.github.com> Date: Tue, 16 Jan 2024 21:16:07 +0100 Subject: [PATCH] feat: support custom image loaders in turbopack --- .../next-swc/crates/next-core/src/next_config.rs | 13 ++++++++++++- .../crates/next-core/src/next_import_map.rs | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index 63a202b74af25..50e1adf3acf67 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -1,6 +1,6 @@ use anyhow::{Context, Result}; use indexmap::IndexMap; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value as JsonValue; use turbo_tasks::{trace::TraceRawVcs, Completion, Value, Vc}; use turbo_tasks_fs::json::parse_json_with_source_context; @@ -310,6 +310,8 @@ pub struct ImageConfig { pub image_sizes: Vec, pub path: String, pub loader: ImageLoader, + #[serde(deserialize_with = "empty_string_is_none")] + pub loader_file: Option, pub domains: Vec, pub disable_static_images: bool, #[serde(rename(deserialize = "minimumCacheTTL"))] @@ -322,6 +324,14 @@ pub struct ImageConfig { pub unoptimized: bool, } +fn empty_string_is_none<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let o = Option::::deserialize(deserializer)?; + Ok(o.filter(|s| !s.is_empty())) +} + impl Default for ImageConfig { fn default() -> Self { // https://github.com/vercel/next.js/blob/327634eb/packages/next/shared/lib/image-config.ts#L100-L114 @@ -330,6 +340,7 @@ impl Default for ImageConfig { image_sizes: vec![16, 32, 48, 64, 96, 128, 256, 384], path: "/_next/image".to_string(), loader: ImageLoader::Default, + loader_file: None, domains: vec![], disable_static_images: false, minimum_cache_ttl: 60, diff --git a/packages/next-swc/crates/next-core/src/next_import_map.rs b/packages/next-swc/crates/next-core/src/next_import_map.rs index d77d154aebd92..0af80ec23650a 100644 --- a/packages/next-swc/crates/next-core/src/next_import_map.rs +++ b/packages/next-swc/crates/next-core/src/next_import_map.rs @@ -521,6 +521,21 @@ async fn insert_next_server_special_aliases( external_if_node(project_path, "next/dist/compiled/@opentelemetry/api"), ); + let image_config = next_config.image_config().await?; + if let Some(loader_file) = image_config.loader_file.as_deref() { + import_map.insert_exact_alias( + "next/dist/shared/lib/image-loader", + request_to_import_mapping(project_path, loader_file), + ); + + if runtime == NextRuntime::Edge { + import_map.insert_exact_alias( + "next/dist/esm/shared/lib/image-loader", + request_to_import_mapping(project_path, loader_file), + ); + } + } + match ty { ServerContextType::Pages { pages_dir } | ServerContextType::PagesApi { pages_dir } => { insert_alias_to_alternatives(