diff --git a/crates/binding/src/js_hook.rs b/crates/binding/src/js_hook.rs index f167655b0..21ba89ac0 100644 --- a/crates/binding/src/js_hook.rs +++ b/crates/binding/src/js_hook.rs @@ -68,6 +68,8 @@ pub struct JsHooks { ts_type = "(content: { content: string, type: 'css' | 'js' }, path: string) => Promise<{ content: string, type: 'css' | 'js' } | void> | void;" )] pub transform: Option, + #[napi(ts_type = "(filePath: string) => Promise | bool;")] + pub transform_include: Option, } pub struct TsFnHooks { @@ -79,6 +81,7 @@ pub struct TsFnHooks { Option>>, pub _on_generate_file: Option>, pub transform: Option>>, + pub transform_include: Option>>, } impl TsFnHooks { @@ -105,6 +108,9 @@ impl TsFnHooks { transform: hooks.transform.as_ref().map(|hook| unsafe { ThreadsafeFunction::from_napi_value(env.raw(), hook.raw()).unwrap() }), + transform_include: hooks.transform_include.as_ref().map(|hook| unsafe { + ThreadsafeFunction::from_napi_value(env.raw(), hook.raw()).unwrap() + }), } } } diff --git a/crates/binding/src/js_plugin.rs b/crates/binding/src/js_plugin.rs index 289f6bcfb..2e561ad49 100644 --- a/crates/binding/src/js_plugin.rs +++ b/crates/binding/src/js_plugin.rs @@ -11,6 +11,21 @@ use crate::js_hook::{ LoadResult, ResolveIdParams, ResolveIdResult, TransformResult, TsFnHooks, WriteFile, }; +fn content_from_result(result: TransformResult) -> Result { + match result.content_type.as_str() { + "js" | "ts" => Ok(Content::Js(JsContent { + content: result.content, + is_jsx: false, + })), + "jsx" | "tsx" => Ok(Content::Js(JsContent { + content: result.content, + is_jsx: true, + })), + "css" => Ok(Content::Css(result.content)), + _ => Err(anyhow!("Unsupported content type: {}", result.content_type)), + } +} + pub struct JsPlugin { pub hooks: TsFnHooks, } @@ -42,22 +57,11 @@ impl Plugin for JsPlugin { } let x: Option = hook.call(param.file.path.to_string_lossy().to_string())?; if let Some(x) = x { - match x.content_type.as_str() { - "js" | "ts" => { - return Ok(Some(Content::Js(JsContent { - content: x.content, - is_jsx: false, - }))) - } - "jsx" | "tsx" => { - return Ok(Some(Content::Js(JsContent { - content: x.content, - is_jsx: true, - }))) - } - "css" => return Ok(Some(Content::Css(x.content))), - _ => return Err(anyhow!("Unsupported content type: {}", x.content_type)), - } + return content_from_result(TransformResult { + content: x.content, + content_type: x.content_type, + }) + .map(Some); } } Ok(None) @@ -122,6 +126,12 @@ impl Plugin for JsPlugin { path: &str, _context: &Arc, ) -> Result> { + if let Some(hook) = &self.hooks.transform_include { + if hook.call(path.to_string())? == Some(false) { + return Ok(None); + } + } + if let Some(hook) = &self.hooks.transform { let content_str = match content { Content::Js(js_content) => js_content.content.clone(), @@ -132,22 +142,7 @@ impl Plugin for JsPlugin { let result: Option = hook.call((content_str, path.to_string()))?; if let Some(result) = result { - match result.content_type.as_str() { - "js" | "ts" => { - return Ok(Some(Content::Js(JsContent { - content: result.content, - is_jsx: false, - }))) - } - "jsx" | "tsx" => { - return Ok(Some(Content::Js(JsContent { - content: result.content, - is_jsx: true, - }))) - } - "css" => return Ok(Some(Content::Css(result.content))), - _ => return Err(anyhow!("Unsupported content type: {}", result.content_type)), - } + return content_from_result(result).map(Some); } } Ok(None) diff --git a/docs/config.md b/docs/config.md index 6ae3b7810..dc2f89e56 100644 --- a/docs/config.md +++ b/docs/config.md @@ -575,6 +575,7 @@ Specify the plugins to use. loadInclude?: (filePath: string) => boolean; resolveId?: (id: string, importer: string, { isEntry: bool }) => Promise<{ id: string, external: bool }>; transform?: (content: string, id: string) => Promise<{ content: string, type: 'css'|'js'|'jsx'|'ts'|'tsx' }>; + transformInclude?: (filePath: string) => Promise | boolean; } ``` diff --git a/docs/config.zh-CN.md b/docs/config.zh-CN.md index 53ed1d0a9..9da777168 100644 --- a/docs/config.zh-CN.md +++ b/docs/config.zh-CN.md @@ -573,6 +573,7 @@ import(/* webpackIgnore: true */ "./foo"); loadInclude?: (filePath: string) => boolean; resolveId?: (id: string, importer: string, { isEntry: bool }) => Promise<{ id: string, external: bool }>; transform?: (content: string, id: string) => Promise<{ content: string, type: 'css'|'js'|'jsx'|'ts'|'tsx' }>; + transformInclude?: (filePath: string) => Promise | boolean; } ``` diff --git a/packages/mako/binding.d.ts b/packages/mako/binding.d.ts index 5bd858867..ee5231e67 100644 --- a/packages/mako/binding.d.ts +++ b/packages/mako/binding.d.ts @@ -61,6 +61,7 @@ export interface JsHooks { content: { content: string; type: 'css' | 'js' }, path: string, ) => Promise<{ content: string; type: 'css' | 'js' } | void> | void; + transformInclude?: (filePath: string) => Promise | bool; } export interface WriteFile { path: string; @@ -77,7 +78,7 @@ export interface ResolveIdResult { export interface ResolveIdParams { isEntry: boolean; } -export interface LoadTransformResult { +export interface TransformResult { content: string; type: string; }