Skip to content

Commit

Permalink
Merge branch 'master' into fix/css-order-after-optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
xusd320 authored Jan 8, 2025
2 parents c2c2a1a + 13bd12e commit e8d5478
Show file tree
Hide file tree
Showing 31 changed files with 719 additions and 107 deletions.
27 changes: 15 additions & 12 deletions crates/binding/src/js_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use napi::NapiRaw;
use napi_derive::napi;
use serde_json::Value;

use crate::js_plugin::PluginContext;
use crate::threadsafe_function::ThreadsafeFunction;

#[napi(object)]
Expand Down Expand Up @@ -81,19 +82,21 @@ pub struct JsHooks {
pub transform_include: Option<JsFunction>,
}

type ResolveIdFuncParams = (PluginContext, String, String, ResolveIdParams);

pub struct TsFnHooks {
pub build_start: Option<ThreadsafeFunction<(), ()>>,
pub build_end: Option<ThreadsafeFunction<(), ()>>,
pub write_bundle: Option<ThreadsafeFunction<(), ()>>,
pub generate_end: Option<ThreadsafeFunction<Value, ()>>,
pub load: Option<ThreadsafeFunction<String, Option<LoadResult>>>,
pub load_include: Option<ThreadsafeFunction<String, Option<bool>>>,
pub watch_changes: Option<ThreadsafeFunction<(String, WatchChangesParams), ()>>,
pub resolve_id:
Option<ThreadsafeFunction<(String, String, ResolveIdParams), Option<ResolveIdResult>>>,
pub _on_generate_file: Option<ThreadsafeFunction<WriteFile, ()>>,
pub transform: Option<ThreadsafeFunction<(String, String), Option<TransformResult>>>,
pub transform_include: Option<ThreadsafeFunction<String, Option<bool>>>,
pub build_start: Option<ThreadsafeFunction<PluginContext, ()>>,
pub build_end: Option<ThreadsafeFunction<PluginContext, ()>>,
pub write_bundle: Option<ThreadsafeFunction<PluginContext, ()>>,
pub generate_end: Option<ThreadsafeFunction<(PluginContext, Value), ()>>,
pub load: Option<ThreadsafeFunction<(PluginContext, String), Option<LoadResult>>>,
pub load_include: Option<ThreadsafeFunction<(PluginContext, String), Option<bool>>>,
pub watch_changes: Option<ThreadsafeFunction<(PluginContext, String, WatchChangesParams), ()>>,
pub resolve_id: Option<ThreadsafeFunction<ResolveIdFuncParams, Option<ResolveIdResult>>>,
pub _on_generate_file: Option<ThreadsafeFunction<(PluginContext, WriteFile), ()>>,
pub transform:
Option<ThreadsafeFunction<(PluginContext, String, String), Option<TransformResult>>>,
pub transform_include: Option<ThreadsafeFunction<(PluginContext, String), Option<bool>>>,
}

impl TsFnHooks {
Expand Down
119 changes: 93 additions & 26 deletions crates/binding/src/js_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use mako::ast::file::{Content, JsContent};
use mako::compiler::Context;
use mako::plugin::{Plugin, PluginGenerateEndParams, PluginLoadParam, PluginResolveIdParams};
use mako::resolve::{ExternalResource, Resolution, ResolvedResource, ResolverResource};
use napi_derive::napi;

use crate::js_hook::{
LoadResult, ResolveIdParams, ResolveIdResult, TransformResult, TsFnHooks, WatchChangesParams,
Expand All @@ -27,6 +28,29 @@ fn content_from_result(result: TransformResult) -> Result<Content> {
}
}

#[napi]
pub struct PluginContext {
context: Arc<Context>,
}

#[napi]
impl PluginContext {
#[napi]
pub fn warn(&self, msg: String) {
println!("WARN: {}", msg)
}
#[napi]
pub fn error(&self, msg: String) {
println!("ERROR: {}", msg)
}
#[napi]
pub fn emit_file(&self, origin_path: String, output_path: String) {
let mut assets_info = self.context.assets_info.lock().unwrap();
assets_info.insert(origin_path, output_path);
drop(assets_info);
}
}

pub struct JsPlugin {
pub hooks: TsFnHooks,
pub name: Option<String>,
Expand All @@ -42,27 +66,33 @@ impl Plugin for JsPlugin {
self.enforce.as_deref()
}

fn build_start(&self, _context: &Arc<Context>) -> Result<()> {
fn build_start(&self, context: &Arc<Context>) -> Result<()> {
if let Some(hook) = &self.hooks.build_start {
hook.call(())?
hook.call(PluginContext {
context: context.clone(),
})?
}
Ok(())
}

fn load(&self, param: &PluginLoadParam, _context: &Arc<Context>) -> Result<Option<Content>> {
fn load(&self, param: &PluginLoadParam, context: &Arc<Context>) -> Result<Option<Content>> {
if let Some(hook) = &self.hooks.load {
if self.hooks.load_include.is_some()
&& self
.hooks
.load_include
.as_ref()
.unwrap()
.call(param.file.path.to_string_lossy().to_string())?
== Some(false)
&& self.hooks.load_include.as_ref().unwrap().call((
PluginContext {
context: context.clone(),
},
param.file.path.to_string_lossy().to_string(),
))? == Some(false)
{
return Ok(None);
}
let x: Option<LoadResult> = hook.call(param.file.path.to_string_lossy().to_string())?;
let x: Option<LoadResult> = hook.call((
PluginContext {
context: context.clone(),
},
param.file.path.to_string_lossy().to_string(),
))?;
if let Some(x) = x {
return content_from_result(TransformResult {
content: x.content,
Expand All @@ -79,10 +109,13 @@ impl Plugin for JsPlugin {
source: &str,
importer: &str,
params: &PluginResolveIdParams,
_context: &Arc<Context>,
context: &Arc<Context>,
) -> Result<Option<ResolverResource>> {
if let Some(hook) = &self.hooks.resolve_id {
let x: Option<ResolveIdResult> = hook.call((
PluginContext {
context: context.clone(),
},
source.to_string(),
importer.to_string(),
ResolveIdParams {
Expand Down Expand Up @@ -110,21 +143,31 @@ impl Plugin for JsPlugin {
Ok(None)
}

fn generate_end(&self, param: &PluginGenerateEndParams, _context: &Arc<Context>) -> Result<()> {
fn generate_end(&self, param: &PluginGenerateEndParams, context: &Arc<Context>) -> Result<()> {
// keep generate_end for compatibility
// since build_end does not have none error params in unplugin's api spec
if let Some(hook) = &self.hooks.generate_end {
hook.call(serde_json::to_value(param)?)?
hook.call((
PluginContext {
context: context.clone(),
},
serde_json::to_value(param)?,
))?
}
if let Some(hook) = &self.hooks.build_end {
hook.call(())?
hook.call(PluginContext {
context: context.clone(),
})?
}
Ok(())
}

fn watch_changes(&self, id: &str, event: &str, _context: &Arc<Context>) -> Result<()> {
fn watch_changes(&self, id: &str, event: &str, context: &Arc<Context>) -> Result<()> {
if let Some(hook) = &self.hooks.watch_changes {
hook.call((
PluginContext {
context: context.clone(),
},
id.to_string(),
WatchChangesParams {
event: event.to_string(),
Expand All @@ -134,19 +177,31 @@ impl Plugin for JsPlugin {
Ok(())
}

fn write_bundle(&self, _context: &Arc<Context>) -> Result<()> {
fn write_bundle(&self, context: &Arc<Context>) -> Result<()> {
if let Some(hook) = &self.hooks.write_bundle {
hook.call(())?
hook.call(PluginContext {
context: context.clone(),
})?
}
Ok(())
}

fn before_write_fs(&self, path: &std::path::Path, content: &[u8]) -> Result<()> {
fn before_write_fs(
&self,
path: &std::path::Path,
content: &[u8],
context: &Arc<Context>,
) -> Result<()> {
if let Some(hook) = &self.hooks._on_generate_file {
hook.call(WriteFile {
path: path.to_string_lossy().to_string(),
content: content.to_vec(),
})?;
hook.call((
PluginContext {
context: context.clone(),
},
WriteFile {
path: path.to_string_lossy().to_string(),
content: content.to_vec(),
},
))?;
}
Ok(())
}
Expand All @@ -155,10 +210,16 @@ impl Plugin for JsPlugin {
&self,
content: &mut Content,
path: &str,
_context: &Arc<Context>,
context: &Arc<Context>,
) -> Result<Option<Content>> {
if let Some(hook) = &self.hooks.transform_include {
if hook.call(path.to_string())? == Some(false) {
if hook.call((
PluginContext {
context: context.clone(),
},
path.to_string(),
))? == Some(false)
{
return Ok(None);
}
}
Expand All @@ -170,7 +231,13 @@ impl Plugin for JsPlugin {
_ => return Ok(None),
};

let result: Option<TransformResult> = hook.call((content_str, path.to_string()))?;
let result: Option<TransformResult> = hook.call((
PluginContext {
context: context.clone(),
},
content_str,
path.to_string(),
))?;

if let Some(result) = result {
return content_from_result(result).map(Some);
Expand Down
12 changes: 8 additions & 4 deletions crates/mako/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,9 @@ impl PartialOrd for ModuleId {
impl ModuleId {
// we use absolute path as module id now
pub fn new(id: String) -> Self {
Self { id }
Self {
id: win_path(id.as_str()),
}
}

pub fn generate(&self, context: &Arc<Context>) -> String {
Expand All @@ -304,20 +306,22 @@ impl ModuleId {

impl From<String> for ModuleId {
fn from(id: String) -> Self {
Self { id }
Self {
id: win_path(id.as_str()),
}
}
}

impl From<&str> for ModuleId {
fn from(id: &str) -> Self {
Self { id: id.to_string() }
Self { id: win_path(id) }
}
}

impl From<PathBuf> for ModuleId {
fn from(path: PathBuf) -> Self {
Self {
id: path.to_string_lossy().to_string(),
id: win_path(path.to_string_lossy().to_string().as_str()),
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions crates/mako/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,12 @@ pub trait Plugin: Any + Send + Sync {
Ok(())
}

fn before_write_fs(&self, _path: &Path, _content: &[u8]) -> Result<()> {
fn before_write_fs(
&self,
_path: &Path,
_content: &[u8],
_context: &Arc<Context>,
) -> Result<()> {
Ok(())
}

Expand Down Expand Up @@ -422,9 +427,10 @@ impl PluginDriver {
&self,
path: P,
content: C,
context: &Arc<Context>,
) -> Result<()> {
for p in &self.plugins {
p.before_write_fs(path.as_ref(), content.as_ref())?;
p.before_write_fs(path.as_ref(), content.as_ref(), context)?;
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/mako/src/plugins/bundless_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl BundlessCompiler {

self.context
.plugin_driver
.before_write_fs(&to, content.as_ref())
.before_write_fs(&to, content.as_ref(), &self.context)
.unwrap();

if !self.context.config.output.skip_write {
Expand Down
3 changes: 2 additions & 1 deletion crates/mako/src/plugins/context_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use swc_core::ecma::ast::{
use swc_core::ecma::utils::{member_expr, quote_ident, quote_str, ExprExt, ExprFactory};
use swc_core::ecma::visit::{VisitMut, VisitMutWith};

use crate::ast::file::{Content, JsContent};
use crate::ast::file::{win_path, Content, JsContent};
use crate::ast::utils::{is_commonjs_require, is_dynamic_import};
use crate::ast::DUMMY_CTXT;
use crate::build::load::JS_EXTENSIONS;
Expand Down Expand Up @@ -120,6 +120,7 @@ module.exports = (id) => {{
"#,
key_values
.into_values()
.map(|v| win_path(v.as_str()))
.collect::<Vec<String>>()
.join(",\n")
);
Expand Down
5 changes: 3 additions & 2 deletions crates/mako/src/plugins/require_context/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use swc_core::ecma::ast::{Expr, ExprOrSpread, Lit, Regex};
use thiserror::Error;

use super::VIRTUAL_REQUIRE_CONTEXT_MODULE;
use crate::ast::file::win_path;
use crate::compiler::Context;

#[derive(Debug)]
Expand All @@ -34,9 +35,9 @@ impl ContextParam {
Ok(format!(
"{}?root={}&sub={}&reg={}&mode={}&ig={}",
VIRTUAL_REQUIRE_CONTEXT_MODULE,
encode(relative_path.to_string_lossy().as_ref(),),
encode(win_path(relative_path.to_string_lossy().as_ref()).as_str()),
self.use_subdirectories,
encode(self.reg_expr.exp.as_ref()),
encode(win_path(self.reg_expr.exp.as_ref()).as_str()),
self.mode,
ignore_case,
))
Expand Down
Loading

0 comments on commit e8d5478

Please sign in to comment.