rspack_binding_builder_macros/
lib.rs

1//! Exports a few macros to help you create a custom plugin register with Rspack.
2//!
3//! # Important
4//! This crate is used for creating a custom binding. It is not intended to be used directly by non-custom binding users.
5//!
6//! # Guide
7//! [Rspack Custom binding](https://rspack-contrib.github.io/rspack-rust-book/custom-binding/getting-started/index.html)
8
9mod register_plugin;
10
11use proc_macro::TokenStream;
12use syn::parse_macro_input;
13
14/// Create a custom plugin register with Rspack.
15///
16/// The created plugin register will be exposed to the final N-API binding.
17///
18/// The plugin needs to be wrapped with `require('@rspack/core').experiments.createNativePlugin`
19/// to be used in the host.
20///
21/// ## Usage
22///
23/// `register_plugin` macro accepts two arguments:
24/// - The name of the plugin
25/// - A resolver function that returns a `rspack_core::BoxPlugin`
26///
27/// The resolver function accepts two arguments:
28/// - `env`: The environment of the plugin, it is the same as `napi::bindgen_prelude::Env`
29/// - `options`: The options of the plugin, it is the same as `napi::bindgen_prelude::Unknown<'_>`
30///
31/// The resolver function should return a `rspack_core::BoxPlugin`
32///
33/// # Example
34///
35/// This example will expose `registerMyBannerPlugin` in the final N-API binding:
36///
37/// ```rust,ignore
38/// use napi_derive::napi;
39/// use rspack_binding_builder_macros::register_plugin;
40///
41/// register_plugin!(
42///   "MyBannerPlugin",
43///   |env: napi::bindgen_prelude::Env, options: napi::bindgen_prelude::Unknown<'_>| {
44///     Ok(Box::new(MyBannerPlugin) as rspack_core::BoxPlugin)
45///   }
46/// );
47///
48/// #[derive(Debug)]
49/// struct MyBannerPlugin;
50///
51/// impl rspack_core::Plugin for MyBannerPlugin {
52///   fn apply(&self, ctx: &mut rspack_core::ApplyContext<'_>) -> rspack_error::Result<()> {
53///     Ok(())
54///   }
55/// }
56/// ```
57///
58/// The `registerMyBannerPlugin` function will be exposed to the final N-API binding.
59///
60/// ```js
61/// const { registerMyBannerPlugin } = require('your-custom-binding');
62///
63/// const plugin = registerMyBannerPlugin();
64/// ```
65///
66/// To actually use the plugin, you need to wrap it with `require('@rspack/core').experiments.createNativePlugin`:
67///
68/// ```js
69/// require('@rspack/core').experiments.createNativePlugin("MyBannerPlugin", (options) => options)
70/// ```
71#[proc_macro]
72pub fn register_plugin(input: TokenStream) -> TokenStream {
73  let input = parse_macro_input!(input as register_plugin::RegisterPluginInput);
74  input.expand().into()
75}