mod plugin;
pub use plugin::ReactRefreshLoaderPlugin;
use rspack_cacheable::{cacheable, cacheable_dyn};
use rspack_core::RunnerContext;
use rspack_error::Result;
use rspack_loader_runner::{Identifier, Loader, LoaderContext};
#[cacheable]
pub struct ReactRefreshLoader {
identifier: Identifier,
}
impl Default for ReactRefreshLoader {
fn default() -> Self {
Self {
identifier: REACT_REFRESH_LOADER_IDENTIFIER.into(),
}
}
}
impl ReactRefreshLoader {
pub fn with_identifier(mut self, identifier: Identifier) -> Self {
debug_assert!(identifier.starts_with(REACT_REFRESH_LOADER_IDENTIFIER));
self.identifier = identifier;
self
}
}
#[cacheable_dyn]
#[async_trait::async_trait]
impl Loader<RunnerContext> for ReactRefreshLoader {
fn identifier(&self) -> Identifier {
self.identifier
}
async fn run(&self, loader_context: &mut LoaderContext<RunnerContext>) -> Result<()> {
let Some(content) = loader_context.take_content() else {
return Ok(());
};
let supports_arrow_function = loader_context
.context
.options
.output
.environment
.supports_arrow_function();
let mut source = content.try_into_string()?;
if supports_arrow_function {
source += r#"
function $RefreshSig$() { return $ReactRefreshRuntime$.createSignatureFunctionForTransform() }
function $RefreshReg$(type, id) { $ReactRefreshRuntime$.register(type, __webpack_module__.id + "_" + id) }
Promise.resolve().then(() => { $ReactRefreshRuntime$.refresh(__webpack_module__.id, __webpack_module__.hot) });
"#;
} else {
source += r#"
function $RefreshSig$() { return $ReactRefreshRuntime$.createSignatureFunctionForTransform() }
function $RefreshReg$(type, id) { $ReactRefreshRuntime$.register(type, __webpack_module__.id + "_" + id) }
Promise.resolve().then(function() { $ReactRefreshRuntime$.refresh(__webpack_module__.id, __webpack_module__.hot) });
"#;
}
let sm = loader_context.take_source_map();
let additional_data = loader_context.take_additional_data();
loader_context.finish_with((source, sm, additional_data));
Ok(())
}
}
pub const REACT_REFRESH_LOADER_IDENTIFIER: &str = "builtin:react-refresh-loader";