use std::{any::Any, sync::Arc};
use crate::{
config::Config,
context::CompilationContext,
error::Result,
module::{
module_graph::ModuleGraph, module_group::ModuleGroupGraph, Module, ModuleId, ModuleMetaData,
},
resource::{meta_data::ResourcePotMetaData, resource_pot::ResourcePot},
stats::Stats,
HashMap,
};
pub mod constants;
pub mod hooks;
pub mod plugin_driver;
pub use hooks::{
analyze_deps::{PluginAnalyzeDepsHookParam, PluginAnalyzeDepsHookResultEntry},
finalize_module::PluginFinalizeModuleHookParam,
finalize_resources::PluginFinalizeResourcesHookParam,
freeze_module::PluginFreezeModuleHookParam,
generate_resources::{GeneratedResource, PluginGenerateResourcesHookResult},
handle_entry_resource::PluginHandleEntryResourceHookParam,
load::{PluginLoadHookParam, PluginLoadHookResult},
module_graph_updated::PluginModuleGraphUpdatedHookParam,
parse::PluginParseHookParam,
process_module::PluginProcessModuleHookParam,
resolve::{PluginResolveHookParam, PluginResolveHookResult, ResolveKind},
transform::{PluginTransformHookParam, PluginTransformHookResult},
update_modules::{PluginUpdateModulesHookParam, UpdateResult, UpdateType},
};
pub const DEFAULT_PRIORITY: i32 = 100;
pub trait Plugin: Any + Send + Sync {
fn name(&self) -> &str;
fn priority(&self) -> i32 {
DEFAULT_PRIORITY
}
fn config(&self, _config: &mut Config) -> Result<Option<()>> {
Ok(None)
}
fn plugin_cache_loaded(
&self,
_cache: &Vec<u8>,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn build_start(&self, _context: &Arc<CompilationContext>) -> Result<Option<()>> {
Ok(None)
}
fn resolve(
&self,
_param: &PluginResolveHookParam,
_context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> Result<Option<PluginResolveHookResult>> {
Ok(None)
}
fn load(
&self,
_param: &PluginLoadHookParam,
_context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> Result<Option<PluginLoadHookResult>> {
Ok(None)
}
fn transform(
&self,
_param: &PluginTransformHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<PluginTransformHookResult>> {
Ok(None)
}
fn parse(
&self,
_param: &PluginParseHookParam,
_context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> Result<Option<ModuleMetaData>> {
Ok(None)
}
fn process_module(
&self,
_param: &mut PluginProcessModuleHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn analyze_deps(
&self,
_param: &mut PluginAnalyzeDepsHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn finalize_module(
&self,
_param: &mut PluginFinalizeModuleHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn freeze_module(
&self,
_param: &mut PluginFreezeModuleHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn module_graph_build_end(
&self,
_module_graph: &mut ModuleGraph,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn build_end(&self, _context: &Arc<CompilationContext>) -> Result<Option<()>> {
Ok(None)
}
fn generate_start(&self, _context: &Arc<CompilationContext>) -> Result<Option<()>> {
Ok(None)
}
fn optimize_module_graph(
&self,
_module_graph: &mut ModuleGraph,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn freeze_module_graph_meta(
&self,
_module_graph: &mut ModuleGraph,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn analyze_module_graph(
&self,
_module_graph: &mut ModuleGraph,
_context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> Result<Option<ModuleGroupGraph>> {
Ok(None)
}
fn partial_bundling(
&self,
_modules: &Vec<ModuleId>,
_context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> Result<Option<Vec<ResourcePot>>> {
Ok(None)
}
fn process_resource_pots(
&self,
_resource_pots: &mut Vec<&mut ResourcePot>,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn render_start(
&self,
_config: &Config,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn render_resource_pot(
&self,
_resource_pot: &ResourcePot,
_context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> Result<Option<ResourcePotMetaData>> {
Ok(None)
}
fn process_rendered_resource_pot(
&self,
_resource_pot: &mut ResourcePot,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn augment_resource_pot_hash(
&self,
_render_pot: &ResourcePot,
_context: &Arc<CompilationContext>,
) -> Result<Option<String>> {
Ok(None)
}
fn optimize_resource_pot(
&self,
_resource: &mut ResourcePot,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn generate_resources(
&self,
_resource_pot: &mut ResourcePot,
_context: &Arc<CompilationContext>,
_hook_context: &PluginHookContext,
) -> Result<Option<PluginGenerateResourcesHookResult>> {
Ok(None)
}
fn process_generated_resources(
&self,
_resources: &mut PluginGenerateResourcesHookResult,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn handle_entry_resource(
&self,
_resource: &mut PluginHandleEntryResourceHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn finalize_resources(
&self,
_param: &mut PluginFinalizeResourcesHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn generate_end(&self, _context: &Arc<CompilationContext>) -> Result<Option<()>> {
Ok(None)
}
fn finish(&self, _stat: &Stats, _context: &Arc<CompilationContext>) -> Result<Option<()>> {
Ok(None)
}
fn update_modules(
&self,
_params: &mut PluginUpdateModulesHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn module_graph_updated(
&self,
_param: &PluginModuleGraphUpdatedHookParam,
_context: &Arc<CompilationContext>,
) -> Result<Option<()>> {
Ok(None)
}
fn update_finished(&self, _context: &Arc<CompilationContext>) -> Result<Option<()>> {
Ok(None)
}
fn handle_persistent_cached_module(
&self,
_module: &Module,
_context: &Arc<CompilationContext>,
) -> Result<Option<bool>> {
Ok(None)
}
fn write_plugin_cache(&self, _context: &Arc<CompilationContext>) -> Result<Option<Vec<u8>>> {
Ok(None)
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
pub struct PluginHookContext {
pub caller: Option<String>,
pub meta: HashMap<String, String>,
}
impl PluginHookContext {
fn caller_format<T: AsRef<str>>(name: T) -> String {
format!("[{}]", name.as_ref())
}
pub fn add_caller<T: AsRef<str>>(&self, name: T) -> Option<String> {
match self.caller.as_ref() {
Some(c) => Some(format!("{}{}", c, Self::caller_format(name))),
None => Some(Self::caller_format(name)),
}
}
pub fn clone_and_append_caller<T: AsRef<str>>(&self, name: T) -> Self {
let mut new = self.clone();
if let Some(c) = new.add_caller(name) {
new.caller = Some(c);
}
new
}
pub fn contain_caller<T: AsRef<str>>(&self, name: T) -> bool {
if let Some(ref s) = self.caller {
s.contains(&Self::caller_format(name))
} else {
false
}
}
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct EmptyPluginHookParam {}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct EmptyPluginHookResult {}