Skip to content

Commit

Permalink
feat: context repl plugin (#7853)
Browse files Browse the repository at this point in the history
  • Loading branch information
SyMind authored and JSerFeng committed Sep 25, 2024
1 parent b8545af commit 5e226ab
Show file tree
Hide file tree
Showing 39 changed files with 1,416 additions and 557 deletions.
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 33 additions & 12 deletions crates/node_binding/binding.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,30 @@ export class JsCompilation {
addRuntimeModule(chunkUkey: number, runtimeModule: JsAddingRuntimeModule): void
}

export class JsContextModuleFactoryAfterResolveData {
get resource(): string
set resource(resource: string)
get context(): string
set context(context: string)
get request(): string
set request(request: string)
get regExp(): RawRegex | undefined
set regExp(rawRegExp: RawRegex | undefined)
get recursive(): boolean
set recursive(recursive: boolean)
}

export class JsContextModuleFactoryBeforeResolveData {
get context(): string
set context(context: string)
get request(): string
set request(request: string)
get regExp(): RawRegex | undefined
set regExp(rawRegExp: RawRegex | undefined)
get recursive(): boolean
set recursive(recursive: boolean)
}

export class JsEntries {
clear(): void
get size(): number
Expand Down Expand Up @@ -266,6 +290,7 @@ export enum BuiltinPluginName {
RuntimeChunkPlugin = 'RuntimeChunkPlugin',
SizeLimitsPlugin = 'SizeLimitsPlugin',
NoEmitOnErrorsPlugin = 'NoEmitOnErrorsPlugin',
ContextReplacementPlugin = 'ContextReplacementPlugin',
HttpExternalsRspackPlugin = 'HttpExternalsRspackPlugin',
CopyRspackPlugin = 'CopyRspackPlugin',
HtmlRspackPlugin = 'HtmlRspackPlugin',
Expand Down Expand Up @@ -473,18 +498,6 @@ export interface JsCompatSource {
map?: string
}

export interface JsContextModuleFactoryAfterResolveData {
resource: string
context: string
request: string
regExp?: RawRegex
}

export interface JsContextModuleFactoryBeforeResolveData {
context: string
request?: string
}

export interface JsCreateData {
request: string
userRequest: string
Expand Down Expand Up @@ -1163,6 +1176,14 @@ export interface RawContainerReferencePluginOptions {
enhanced: boolean
}

export interface RawContextReplacementPluginOptions {
resourceRegExp: RawRegex
newContentResource?: string
newContentRecursive?: boolean
newContentRegExp?: RawRegex
newContentCreateContextMap?: Record<string, string>
}

export interface RawCopyGlobOptions {
caseSensitiveMatch?: boolean
dot?: boolean
Expand Down
59 changes: 17 additions & 42 deletions crates/node_binding/src/plugins/interceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use rspack_binding_values::{
JsAfterEmitData, JsAfterResolveData, JsAfterResolveOutput, JsAfterTemplateExecutionData,
JsAlterAssetTagGroupsData, JsAlterAssetTagsData, JsAssetEmittedArgs,
JsBeforeAssetTagGenerationData, JsBeforeEmitData, JsBeforeResolveArgs, JsBeforeResolveOutput,
JsChunk, JsChunkAssetArgs, JsCompilationWrapper, JsContextModuleFactoryAfterResolveData,
JsContextModuleFactoryAfterResolveResult, JsContextModuleFactoryBeforeResolveData,
JsChunk, JsChunkAssetArgs, JsCompilationWrapper, JsContextModuleFactoryAfterResolveDataWrapper,
JsContextModuleFactoryAfterResolveResult, JsContextModuleFactoryBeforeResolveDataWrapper,
JsContextModuleFactoryBeforeResolveResult, JsCreateData, JsExecuteModuleArg, JsFactorizeArgs,
JsFactorizeOutput, JsModule, JsNormalModuleFactoryCreateModuleArgs, JsResolveArgs,
JsResolveForSchemeArgs, JsResolveForSchemeOutput, JsResolveOutput, JsRuntimeGlobals,
Expand All @@ -25,13 +25,13 @@ use rspack_binding_values::{
};
use rspack_collections::IdentifierSet;
use rspack_core::{
parse_resource, AfterResolveData, AfterResolveResult, AssetEmittedInfo, BeforeResolveData,
BeforeResolveResult, BoxModule, Chunk, ChunkUkey, CodeGenerationResults, Compilation,
CompilationAdditionalTreeRuntimeRequirements, CompilationAdditionalTreeRuntimeRequirementsHook,
CompilationAfterOptimizeModules, CompilationAfterOptimizeModulesHook,
CompilationAfterProcessAssets, CompilationAfterProcessAssetsHook, CompilationAfterSeal,
CompilationAfterSealHook, CompilationBuildModule, CompilationBuildModuleHook,
CompilationChunkAsset, CompilationChunkAssetHook, CompilationChunkHash, CompilationChunkHashHook,
parse_resource, AfterResolveResult, AssetEmittedInfo, BeforeResolveResult, BoxModule, Chunk,
ChunkUkey, CodeGenerationResults, Compilation, CompilationAdditionalTreeRuntimeRequirements,
CompilationAdditionalTreeRuntimeRequirementsHook, CompilationAfterOptimizeModules,
CompilationAfterOptimizeModulesHook, CompilationAfterProcessAssets,
CompilationAfterProcessAssetsHook, CompilationAfterSeal, CompilationAfterSealHook,
CompilationBuildModule, CompilationBuildModuleHook, CompilationChunkAsset,
CompilationChunkAssetHook, CompilationChunkHash, CompilationChunkHashHook,
CompilationExecuteModule, CompilationExecuteModuleHook, CompilationFinishModules,
CompilationFinishModulesHook, CompilationOptimizeChunkModules,
CompilationOptimizeChunkModulesHook, CompilationOptimizeModules, CompilationOptimizeModulesHook,
Expand Down Expand Up @@ -1555,23 +1555,14 @@ impl ContextModuleFactoryBeforeResolve for ContextModuleFactoryBeforeResolveTap
async fn run(&self, result: BeforeResolveResult) -> rspack_error::Result<BeforeResolveResult> {
let js_result = match result {
BeforeResolveResult::Ignored => JsContextModuleFactoryBeforeResolveResult::A(false),
BeforeResolveResult::Data(d) => {
JsContextModuleFactoryBeforeResolveResult::B(JsContextModuleFactoryBeforeResolveData {
context: d.context,
request: d.request,
})
}
BeforeResolveResult::Data(data) => JsContextModuleFactoryBeforeResolveResult::B(
JsContextModuleFactoryBeforeResolveDataWrapper::new(data),
),
};
match self.function.call_with_promise(js_result).await {
Ok(js_result) => match js_result {
napi::bindgen_prelude::Either::A(_) => Ok(BeforeResolveResult::Ignored),
napi::bindgen_prelude::Either::B(d) => {
let data = BeforeResolveData {
context: d.context,
request: d.request,
};
Ok(BeforeResolveResult::Data(Box::new(data)))
}
napi::bindgen_prelude::Either::B(js_data) => Ok(BeforeResolveResult::Data(js_data.take())),
},
Err(err) => Err(err),
}
Expand All @@ -1587,29 +1578,13 @@ impl ContextModuleFactoryAfterResolve for ContextModuleFactoryAfterResolveTap {
async fn run(&self, result: AfterResolveResult) -> rspack_error::Result<AfterResolveResult> {
let js_result = match result {
AfterResolveResult::Ignored => JsContextModuleFactoryAfterResolveResult::A(false),
AfterResolveResult::Data(d) => {
JsContextModuleFactoryAfterResolveResult::B(JsContextModuleFactoryAfterResolveData {
resource: d.resource.as_str().to_owned(),
context: d.context.to_owned(),
request: d.request.to_owned(),
reg_exp: d.reg_exp.clone().map(|r| r.into()),
})
}
AfterResolveResult::Data(data) => JsContextModuleFactoryAfterResolveResult::B(
JsContextModuleFactoryAfterResolveDataWrapper::new(data),
),
};
match self.function.call_with_promise(js_result).await? {
napi::Either::A(_) => Ok(AfterResolveResult::Ignored),
napi::Either::B(d) => {
let data = AfterResolveData {
resource: d.resource.into(),
context: d.context,
request: d.request,
reg_exp: match d.reg_exp {
Some(r) => Some(r.try_into()?),
None => None,
},
};
Ok(AfterResolveResult::Data(Box::new(data)))
}
napi::Either::B(js_data) => Ok(AfterResolveResult::Data(js_data.take())),
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/rspack_binding_options/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ rspack_napi_macros = { version = "0.1.0", path = "../rspack_n
rspack_paths = { version = "0.1.0", path = "../rspack_paths" }
rspack_plugin_asset = { version = "0.1.0", path = "../rspack_plugin_asset" }
rspack_plugin_banner = { version = "0.1.0", path = "../rspack_plugin_banner" }
rspack_plugin_context_replacement = { version = "0.1.0", path = "../rspack_plugin_context_replacement" }
rspack_plugin_copy = { version = "0.1.0", path = "../rspack_plugin_copy" }
rspack_plugin_css = { version = "0.1.0", path = "../rspack_plugin_css" }
rspack_plugin_devtool = { version = "0.1.0", path = "../rspack_plugin_devtool" }
Expand Down
14 changes: 11 additions & 3 deletions crates/rspack_binding_options/src/options/raw_builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use rspack_ids::{
use rspack_napi::NapiResultExt;
use rspack_plugin_asset::AssetPlugin;
use rspack_plugin_banner::BannerPlugin;
use rspack_plugin_context_replacement::ContextReplacementPlugin;
use rspack_plugin_copy::{CopyRspackPlugin, CopyRspackPluginOptions};
use rspack_plugin_css::CssPlugin;
use rspack_plugin_devtool::{
Expand Down Expand Up @@ -91,9 +92,10 @@ use self::{
raw_size_limits::RawSizeLimitsPluginOptions,
};
use crate::{
plugins::JsLoaderRspackPlugin, JsLoaderRunner, RawDynamicEntryPluginOptions,
RawEvalDevToolModulePluginOptions, RawExternalItemWrapper, RawExternalsPluginOptions,
RawHttpExternalsRspackPluginOptions, RawSourceMapDevToolPluginOptions, RawSplitChunksOptions,
plugins::JsLoaderRspackPlugin, JsLoaderRunner, RawContextReplacementPluginOptions,
RawDynamicEntryPluginOptions, RawEvalDevToolModulePluginOptions, RawExternalItemWrapper,
RawExternalsPluginOptions, RawHttpExternalsRspackPluginOptions, RawSourceMapDevToolPluginOptions,
RawSplitChunksOptions,
};

#[napi(string_enum)]
Expand Down Expand Up @@ -161,6 +163,7 @@ pub enum BuiltinPluginName {
RuntimeChunkPlugin,
SizeLimitsPlugin,
NoEmitOnErrorsPlugin,
ContextReplacementPlugin,

// rspack specific plugins
// naming format follow XxxRspackPlugin
Expand Down Expand Up @@ -504,6 +507,11 @@ impl BuiltinPlugin {
BuiltinPluginName::NoEmitOnErrorsPlugin => {
plugins.push(NoEmitOnErrorsPlugin::default().boxed());
}
BuiltinPluginName::ContextReplacementPlugin => {
let raw_options = downcast_into::<RawContextReplacementPluginOptions>(self.options)?;
let options = raw_options.try_into()?;
plugins.push(ContextReplacementPlugin::new(options).boxed());
}
}
Ok(())
}
Expand Down
57 changes: 57 additions & 0 deletions crates/rspack_binding_options/src/plugins/context_replacement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use napi::bindgen_prelude::Object;
use napi_derive::napi;
use rspack_binding_values::RawRegex;
use rspack_error::{miette::IntoDiagnostic, Error};
use rspack_plugin_context_replacement::ContextReplacementPluginOptions;
use rspack_regex::RspackRegex;
use rustc_hash::FxHashMap as HashMap;

#[napi(object, object_to_js = false)]
pub struct RawContextReplacementPluginOptions {
pub resource_reg_exp: RawRegex,
pub new_content_resource: Option<String>,
pub new_content_recursive: Option<bool>,
pub new_content_reg_exp: Option<RawRegex>,
#[napi(ts_type = "Record<string, string>")]
pub new_content_create_context_map: Option<Object>,
// new_content_callback
}

impl TryFrom<RawContextReplacementPluginOptions> for ContextReplacementPluginOptions {
type Error = Error;

fn try_from(val: RawContextReplacementPluginOptions) -> Result<Self, Self::Error> {
let new_content_reg_exp = match val.new_content_reg_exp {
Some(js_regex) => {
let regex = RspackRegex::with_flags(&js_regex.source, &js_regex.flags)?;
Some(regex)
}
None => None,
};

let new_content_create_context_map = if let Some(raw) = val.new_content_create_context_map {
let mut map = HashMap::default();
let keys = Object::keys(&raw).into_diagnostic()?;
for key in keys {
let value = raw.get::<&str, String>(&key).into_diagnostic()?;
if let Some(value) = value {
map.insert(key, value);
}
}
Some(map)
} else {
None
};

Ok(Self {
resource_reg_exp: RspackRegex::with_flags(
&val.resource_reg_exp.source,
&val.resource_reg_exp.flags,
)?,
new_content_resource: val.new_content_resource,
new_content_recursive: val.new_content_recursive,
new_content_reg_exp,
new_content_create_context_map,
})
}
}
3 changes: 3 additions & 0 deletions crates/rspack_binding_options/src/plugins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
mod context_replacement;
mod js_loader;

pub use context_replacement::*;
pub(super) use js_loader::{JsLoaderRspackPlugin, JsLoaderRunner};
Loading

0 comments on commit 5e226ab

Please sign in to comment.