rspack_plugin_runtime 0.100.1

rspack runtime plugin
Documentation
use rspack_core::{
  ChunkGroupOrderKey, ChunkUkey, Compilation, CompilationAdditionalChunkRuntimeRequirements,
  CompilationAdditionalTreeRuntimeRequirements, Plugin, RuntimeGlobals, RuntimeModule,
};
use rspack_error::Result;
use rspack_hook::{plugin, plugin_hook};

use crate::runtime_module::{
  ChunkPrefetchStartupRuntimeModule, ChunkPrefetchTriggerRuntimeModule,
  ChunkPreloadTriggerRuntimeModule,
};

#[plugin]
#[derive(Debug, Default)]
pub struct ChunkPrefetchPreloadPlugin;

#[plugin_hook(CompilationAdditionalChunkRuntimeRequirements for ChunkPrefetchPreloadPlugin)]
async fn additional_chunk_runtime_requirements(
  &self,
  compilation: &Compilation,
  chunk_ukey: &ChunkUkey,
  _runtime_requirements: &mut RuntimeGlobals,
  runtime_modules: &mut Vec<Box<dyn RuntimeModule>>,
) -> Result<()> {
  let chunk = compilation
    .build_chunk_graph_artifact
    .chunk_by_ukey
    .expect_get(chunk_ukey);
  if compilation
    .build_chunk_graph_artifact
    .chunk_graph
    .get_number_of_entry_modules(chunk_ukey)
    == 0
  {
    return Ok(());
  }

  if let Some(startup_child_chunks) =
    chunk.get_children_of_type_in_order(&ChunkGroupOrderKey::Prefetch, compilation, false)
  {
    runtime_modules.push(Box::new(ChunkPrefetchStartupRuntimeModule::new(
      &compilation.runtime_template,
      startup_child_chunks,
    )));
  }
  Ok(())
}

#[plugin_hook(CompilationAdditionalTreeRuntimeRequirements for ChunkPrefetchPreloadPlugin)]
async fn additional_tree_runtime_requirements(
  &self,
  compilation: &Compilation,
  chunk_ukey: &ChunkUkey,
  _runtime_requirements: &mut RuntimeGlobals,
  runtime_modules: &mut Vec<Box<dyn RuntimeModule>>,
) -> Result<()> {
  let chunk = compilation
    .build_chunk_graph_artifact
    .chunk_by_ukey
    .expect_get(chunk_ukey);
  let chunk_filter = |_: &ChunkUkey, __: &Compilation| true;
  let mut chunk_map = chunk.get_child_ids_by_orders_map(false, compilation, &chunk_filter);

  if let Some(prefetch_map) = chunk_map.remove(&ChunkGroupOrderKey::Prefetch) {
    runtime_modules.push(Box::new(ChunkPrefetchTriggerRuntimeModule::new(
      &compilation.runtime_template,
      prefetch_map,
    )));
  }

  if let Some(preload_map) = chunk_map.remove(&ChunkGroupOrderKey::Preload) {
    runtime_modules.push(Box::new(ChunkPreloadTriggerRuntimeModule::new(
      &compilation.runtime_template,
      preload_map,
    )));
  }

  Ok(())
}

impl Plugin for ChunkPrefetchPreloadPlugin {
  fn name(&self) -> &'static str {
    "ChunkPrefetchPreloadPlugin"
  }

  fn apply(&self, ctx: &mut rspack_core::ApplyContext<'_>) -> Result<()> {
    ctx
      .compilation_hooks
      .additional_tree_runtime_requirements
      .tap(additional_tree_runtime_requirements::new(self));
    ctx
      .compilation_hooks
      .additional_chunk_runtime_requirements
      .tap(additional_chunk_runtime_requirements::new(self));
    Ok(())
  }
}