rspack_plugin_wasm 0.102.4

rspack wasm plugin
Documentation
use std::fmt::Debug;

use rspack_core::{
  ChunkUkey, Compilation, CompilationParams, CompilationRenderManifest, CompilerCompilation,
  DependencyType, ManifestAssetType, ModuleType, ParserAndGenerator, Plugin, RenderManifestEntry,
  SourceType,
};
use rspack_error::{Diagnostic, Result};
use rspack_hook::{plugin, plugin_hook};

use crate::parser_and_generator::{AsyncWasmParserAndGenerator, CodeGenerationDataWasmFilename};

#[plugin]
#[derive(Debug, Default)]
pub struct AsyncWasmPlugin {}

#[plugin_hook(CompilerCompilation for AsyncWasmPlugin)]
async fn compilation(
  &self,
  compilation: &mut Compilation,
  params: &mut CompilationParams,
) -> Result<()> {
  compilation.set_dependency_factory(
    DependencyType::WasmImport,
    params.normal_module_factory.clone(),
  );
  compilation.set_dependency_factory(
    DependencyType::WasmExportImported,
    params.normal_module_factory.clone(),
  );
  Ok(())
}

#[plugin_hook(CompilationRenderManifest for AsyncWasmPlugin)]
async fn render_manifest(
  &self,
  compilation: &Compilation,
  chunk_ukey: &ChunkUkey,
  manifest: &mut Vec<RenderManifestEntry>,
  _diagnostics: &mut Vec<Diagnostic>,
) -> Result<()> {
  let chunk = compilation
    .build_chunk_graph_artifact
    .chunk_by_ukey
    .expect_get(chunk_ukey);
  let module_graph = &compilation.get_module_graph();

  let ordered_modules = compilation
    .build_chunk_graph_artifact
    .chunk_graph
    .get_chunk_modules(chunk_ukey, module_graph);

  for m in ordered_modules {
    if m.module_type() != &ModuleType::WasmAsync {
      continue;
    }
    let Some(source) = compilation
      .code_generation_results
      .get(&m.identifier(), Some(chunk.runtime()))
      .get(&SourceType::Wasm)
    else {
      continue;
    };

    let filename_data = compilation
      .code_generation_results
      .get(&m.identifier(), Some(chunk.runtime()))
      .data()
      .get::<CodeGenerationDataWasmFilename>()
      .expect("should have filename for async wasm module");
    let asset_info = filename_data
      .asset_info
      .clone()
      .with_asset_type(ManifestAssetType::Wasm);
    manifest.push(RenderManifestEntry {
      source: source.clone(),
      filename: filename_data.filename.clone(),
      has_filename: true,
      info: asset_info,
      auxiliary: false,
    })
  }

  Ok(())
}

impl Plugin for AsyncWasmPlugin {
  fn name(&self) -> &'static str {
    "rspack.AsyncWebAssemblyModulesPlugin"
  }

  fn apply(&self, ctx: &mut rspack_core::ApplyContext<'_>) -> Result<()> {
    ctx.compiler_hooks.compilation.tap(compilation::new(self));
    ctx
      .compilation_hooks
      .render_manifest
      .tap(render_manifest::new(self));

    ctx.register_parser_and_generator_builder(
      ModuleType::WasmAsync,
      Box::new(move |_| Box::new(AsyncWasmParserAndGenerator) as Box<dyn ParserAndGenerator>),
    );

    Ok(())
  }
}