rspack_plugin_runtime 0.101.2

rspack runtime plugin
Documentation
use rspack_core::{
  Compilation, OutputOptions, PathData, RuntimeCodeTemplate, RuntimeGlobals, RuntimeModule,
  RuntimeModuleGenerateContext, RuntimeModuleStage, RuntimeTemplate, SourceType,
  get_js_chunk_filename_template, get_undo_path, impl_runtime_module,
};

static AUTO_PUBLIC_PATH_TEMPLATE: &str = include_str!("runtime/auto_public_path.ejs");

#[impl_runtime_module]
#[derive(Debug)]
pub struct AutoPublicPathRuntimeModule {}

impl AutoPublicPathRuntimeModule {
  pub fn new(runtime_template: &RuntimeTemplate) -> Self {
    Self::with_default(runtime_template)
  }
}

#[async_trait::async_trait]
impl RuntimeModule for AutoPublicPathRuntimeModule {
  fn stage(&self) -> RuntimeModuleStage {
    RuntimeModuleStage::Attach
  }

  fn template(&self) -> Vec<(String, String)> {
    vec![(self.id().to_string(), AUTO_PUBLIC_PATH_TEMPLATE.to_string())]
  }

  async fn generate(
    &self,
    context: &RuntimeModuleGenerateContext<'_>,
  ) -> rspack_error::Result<String> {
    let compilation = context.compilation;
    let runtime_template = context.runtime_template;
    let chunk = self.chunk().expect("The chunk should be attached");
    let chunk = compilation
      .build_chunk_graph_artifact
      .chunk_by_ukey
      .expect_get(&chunk);
    let filename = get_js_chunk_filename_template(
      chunk,
      &compilation.options.output,
      &compilation.build_chunk_graph_artifact.chunk_group_by_ukey,
    );
    let filename = compilation
      .get_path(
        &filename,
        PathData::default()
          .chunk_id_optional(chunk.id().map(|id| id.as_str()))
          .chunk_hash_optional(chunk.rendered_hash(
            &compilation.chunk_hashes_artifact,
            compilation.options.output.hash_digest_length,
          ))
          .chunk_name_optional(chunk.name_for_filename_template())
          .content_hash_optional(chunk.rendered_content_hash_by_source_type(
            &compilation.chunk_hashes_artifact,
            &SourceType::JavaScript,
            compilation.options.output.hash_digest_length,
          )),
      )
      .await?;
    auto_public_path_template(
      runtime_template,
      self.id(),
      &filename,
      &compilation.options.output,
    )
  }
  fn runtime_requirements(
    &self,
    compilation: &Compilation,
  ) -> rspack_core::RuntimeModuleRuntimeRequirements {
    rspack_core::RuntimeModuleRuntimeRequirements {
      dependencies: if compilation.options.output.script_type == "module" {
        RuntimeGlobals::default()
      } else {
        RuntimeGlobals::GLOBAL
      },
      write: { RuntimeGlobals::PUBLIC_PATH },
      force_context: RuntimeGlobals::PUBLIC_PATH,
      ..Default::default()
    }
  }
}

fn auto_public_path_template(
  runtime_template: &RuntimeCodeTemplate,
  id: &str,
  filename: &str,
  output: &OutputOptions,
) -> rspack_error::Result<String> {
  let output_path = output.path.as_str().to_string();
  let undo_path = get_undo_path(filename, output_path, false);
  let import_meta_name = output.import_meta_name.clone();

  runtime_template.render(
    id,
    Some(serde_json::json!({
      "_script_type": output.script_type,
      "_import_meta_name": import_meta_name,
      "_undo_path": undo_path
    })),
  )
}