Skip to content

Plugin API

Plugins extend the functionality of mini-rspack by tapping into hooks at different stages of the compilation process.

Creating a Plugin

A plugin is a JavaScript class with an apply method that takes a compiler instance.

javascript
class MyPlugin {
  constructor(options) {
    this.options = options || {};
  }

  apply(compiler) {
    // Tap into compiler hooks
    compiler.hooks.emit.tap('MyPlugin', (compilation) => {
      // Modify the compilation
      compilation.assets['my-file.txt'] = 'Generated by MyPlugin';
    });
  }
}

module.exports = MyPlugin;

Plugin Interface

The Plugin trait represents a plugin in the mini-rspack system.

rust
pub trait Plugin {
    fn apply(&self, compiler: &mut crate::compiler::Compiler);
    fn name(&self) -> &str;
}

Methods

apply(compiler)

Applies the plugin to the given compiler.

rust
fn apply(&self, compiler: &mut crate::compiler::Compiler);

Parameters

  • compiler (Compiler): The compiler to apply the plugin to

name()

Returns the name of the plugin.

rust
fn name(&self) -> &str;

Returns

  • &str: The name of the plugin

CompilationPlugin Interface

The CompilationPlugin trait represents a plugin that can be applied to a compilation.

rust
pub trait CompilationPlugin {
    fn apply(&self, compilation: &mut crate::compilation::Compilation);
    fn name(&self) -> &str;
}

Methods

apply(compilation)

Applies the plugin to the given compilation.

rust
fn apply(&self, compilation: &mut crate::compilation::Compilation);

Parameters

  • compilation (Compilation): The compilation to apply the plugin to

name()

Returns the name of the plugin.

rust
fn name(&self) -> &str;

Returns

  • &str: The name of the plugin

EmitPlugin

The EmitPlugin is a built-in plugin that generates an assets.md file with a list of all assets.

rust
pub struct EmitPlugin;

impl Plugin for EmitPlugin {
    fn apply(&self, compiler: &mut Compiler) {
        // Tap into the emit hook
        compiler.hooks.emit.tap("EmitPlugin");
    }

    fn name(&self) -> &str {
        "EmitPlugin"
    }
}

impl CompilationPlugin for EmitPlugin {
    fn apply(&self, compilation: &mut Compilation) {
        // Get all assets
        let assets = compilation.assets.keys().cloned().collect::<Vec<String>>();
        
        // Generate markdown content
        let mut content = String::from("# Assets\n\n");
        for asset in assets {
            content.push_str(&format!("- {}\n", asset));
        }
        
        // Add the markdown file to the assets
        compilation.assets.insert("assets.md".to_string(), content);
        compilation.files.push("assets.md".to_string());
    }

    fn name(&self) -> &str {
        "EmitPlugin"
    }
}

Plugin System

The plugin system is responsible for applying plugins to the compiler and compilation.

apply_plugins

Applies plugins to the compiler.

rust
pub fn apply_plugins(&mut self) {
    if let Some(plugins) = &self.options.plugins {
        for plugin_name in plugins {
            match plugin_name.as_str() {
                "EmitPlugin" => {
                    let plugin = EmitPlugin;
                    Plugin::apply(&plugin, self);
                }
                // Add more built-in plugins here
                _ => {
                    // Try to load the plugin from the plugins directory
                    if let Ok(plugin) = load_plugin(plugin_name) {
                        Plugin::apply(&plugin, self);
                    }
                }
            }
        }
    }
}

load_plugin

Loads a plugin from the plugins directory.

rust
pub fn load_plugin(plugin_name: &str) -> Result<Box<dyn Plugin>> {
    // Get the current directory
    let current_dir = std::env::current_dir()?;
    
    // Construct the plugin path
    let plugin_path = current_dir.join("plugins").join(format!("{}.js", plugin_name));
    
    // Check if the plugin exists
    if !plugin_path.exists() {
        return Err(anyhow::anyhow!("Plugin not found: {}", plugin_name));
    }
    
    // Create a plugin context
    let context = PluginContext {
        compiler_options: serde_json::Value::Null,
        compilation: serde_json::Value::Null,
        hooks: vec!["run".to_string(), "emit".to_string(), "done".to_string()],
    };
    
    // Create a plugin instance
    let plugin = Box::new(JsPlugin {
        name: plugin_name.to_string(),
        path: plugin_path.to_string_lossy().to_string(),
        context,
    });
    
    Ok(plugin)
}

JsPlugin

The JsPlugin represents a JavaScript plugin in the mini-rspack system.

rust
pub struct JsPlugin {
    pub name: String,
    pub path: String,
    pub context: PluginContext,
}

impl Plugin for JsPlugin {
    fn apply(&self, compiler: &mut Compiler) {
        // Tap into the hooks
        compiler.hooks.run.tap(&self.name);
        compiler.hooks.emit.tap(&self.name);
        compiler.hooks.done.tap(&self.name);
    }

    fn name(&self) -> &str {
        &self.name
    }
}

PluginContext

The PluginContext represents the context in which a plugin is executed.

rust
pub struct PluginContext {
    pub compiler_options: serde_json::Value,
    pub compilation: serde_json::Value,
    pub hooks: Vec<String>,
}

Next Steps

Released under the MIT License.