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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
pub struct PluginContext {
pub compiler_options: serde_json::Value,
pub compilation: serde_json::Value,
pub hooks: Vec<String>,
}
Next Steps
- Loader: Learn about the Loader API
- Compiler: Learn about the Compiler API
- Compilation: Learn about the Compilation API