Skip to content

Commit

Permalink
feat: refactor emotion implementation into emotion plugin (#884)
Browse files Browse the repository at this point in the history
Co-authored-by: zp365238 <[email protected]>
  • Loading branch information
zhangpanweb and zp365238 authored Jan 19, 2024
1 parent 35543ac commit f946932
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 76 deletions.
1 change: 1 addition & 0 deletions crates/mako/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ impl Compiler {
Arc::new(plugins::hmr_runtime::HMRRuntimePlugin {}),
Arc::new(plugins::wasm_runtime::WasmRuntimePlugin {}),
Arc::new(plugins::async_runtime::AsyncRuntimePlugin {}),
Arc::new(plugins::emotion::EmotionPlugin {}),
];
plugins.extend(builtin_plugins);

Expand Down
2 changes: 1 addition & 1 deletion crates/mako/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ pub struct InjectItem {
pub prefer_require: Option<bool>,
}

#[derive(Deserialize, Serialize, Debug)]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub enum ReactRuntimeConfig {
#[serde(rename = "automatic")]
Automatic,
Expand Down
84 changes: 84 additions & 0 deletions crates/mako/src/plugins/emotion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use std::path::Path;

use mako_core::anyhow::Ok;
use mako_core::swc_common::sync::Lrc;
use mako_core::swc_common::SourceMap;
use mako_core::swc_ecma_ast::Module;
use mako_core::swc_ecma_visit::{Fold, VisitMut, VisitMutWith};
use mako_core::swc_emotion::{emotion, EmotionOptions};
use swc_core::common::comments::NoopComments;

use crate::config::{Mode, ReactConfig};
use crate::plugin::Plugin;

pub struct EmotionPlugin {}

impl Plugin for EmotionPlugin {
fn name(&self) -> &str {
"emotion"
}

fn modify_config(
&self,
config: &mut crate::config::Config,
_root: &std::path::Path,
_args: &crate::compiler::Args,
) -> mako_core::anyhow::Result<()> {
if config.emotion {
config.react = ReactConfig {
pragma: "jsx".into(),
import_source: "@emotion/react".into(),
pragma_frag: config.react.pragma_frag.clone(),
runtime: config.react.runtime.clone(),
}
}
Ok(())
}

fn transform_js(
&self,
param: &crate::plugin::PluginTransformJsParam,
ast: &mut mako_core::swc_ecma_ast::Module,
context: &std::sync::Arc<crate::compiler::Context>,
) -> mako_core::anyhow::Result<()> {
if context.config.emotion {
ast.visit_mut_with(&mut Emotion {
mode: context.config.mode.clone(),
cm: context.meta.script.cm.clone(),
path: param.path.into(),
});
}

Ok(())
}
}

struct Emotion {
cm: Lrc<SourceMap>,
path: String,
mode: Mode,
}

impl VisitMut for Emotion {
fn visit_mut_module(&mut self, module: &mut Module) {
let is_dev = matches!(self.mode, Mode::Development);
let pos = self.cm.lookup_char_pos(module.span.lo);
let hash = pos.file.src_hash as u32;
let mut folder = emotion(
EmotionOptions {
enabled: Some(true),
sourcemap: Some(true),
auto_label: Some(is_dev),
import_map: None,
..Default::default()
},
Path::new(&self.path),
hash,
self.cm.clone(),
NoopComments,
);
module.body = folder.fold_module(module.clone()).body;

module.visit_mut_children_with(self);
}
}
1 change: 1 addition & 0 deletions crates/mako/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod bundless_compiler;
pub mod context_module;
pub mod copy;
pub mod css;
pub mod emotion;
pub mod farm_tree_shake;
pub mod hmr_runtime;
pub mod ignore;
Expand Down
96 changes: 21 additions & 75 deletions crates/mako/src/transformers/transform_react.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use std::path::Path;
use std::sync::Arc;

use mako_core::swc_common::comments::NoopComments;
use mako_core::swc_common::sync::Lrc;
use mako_core::swc_common::{chain, Mark, SourceMap};
use mako_core::swc_ecma_ast::Module;
use mako_core::swc_ecma_transforms_react::{react, Options, RefreshOptions, Runtime};
use mako_core::swc_ecma_visit::{Fold, VisitMut, VisitMutWith};
use mako_core::swc_emotion::{emotion, EmotionOptions};
use mako_core::swc_ecma_visit::{VisitMut, VisitMutWith};

use crate::ast::build_js_ast;
use crate::compiler::Context;
Expand Down Expand Up @@ -48,55 +45,34 @@ pub fn mako_react(
};
}

let (import_source, pragma) = if context.config.emotion {
("@emotion/react", "jsx")
} else {
(
context.config.react.import_source.as_str(),
context.config.react.pragma.as_str(),
)
};
let runtime = if matches!(context.config.react.runtime, ReactRuntimeConfig::Automatic) {
Runtime::Automatic
} else {
Runtime::Classic
};

let emotion = if context.config.emotion {
Box::new(Emotion {
mode: context.config.mode.clone(),
cm: cm.clone(),
path: task.path.clone(),
})
} else {
noop()
};

let origin_comments = context.meta.script.origin_comments.read().unwrap();
let visit = chain!(
emotion,
react(
cm,
Some(origin_comments.get_swc_comments().clone()),
Options {
import_source: Some(import_source.to_string()),
pragma: Some(pragma.to_string()),
pragma_frag: Some(context.config.react.pragma_frag.clone()),
// support react 17 + only
runtime: Some(runtime),
development: Some(is_dev),
// to avoid throw error for svg namespace element
throw_if_namespace: Some(false),
refresh: if use_refresh {
Some(RefreshOptions::default())
} else {
None
},
..Default::default()
let visit = react(
cm,
Some(origin_comments.get_swc_comments().clone()),
Options {
import_source: Some(context.config.react.import_source.clone()),
pragma: Some(context.config.react.pragma.clone()),
pragma_frag: Some(context.config.react.pragma_frag.clone()),
// support react 17 + only
runtime: Some(runtime),
development: Some(is_dev),
// to avoid throw error for svg namespace element
throw_if_namespace: Some(false),
refresh: if use_refresh {
Some(RefreshOptions::default())
} else {
None
},
*top_level_mark,
*unresolved_mark,
)
..Default::default()
},
*top_level_mark,
*unresolved_mark,
);
if use_refresh {
Box::new(chain!(
Expand All @@ -109,36 +85,6 @@ pub fn mako_react(
}
}

struct Emotion {
cm: Lrc<SourceMap>,
path: String,
mode: Mode,
}

impl VisitMut for Emotion {
fn visit_mut_module(&mut self, module: &mut Module) {
let is_dev = matches!(self.mode, Mode::Development);
let pos = self.cm.lookup_char_pos(module.span.lo);
let hash = pos.file.src_hash as u32;
let mut folder = emotion(
EmotionOptions {
enabled: Some(true),
sourcemap: Some(true),
auto_label: Some(is_dev),
import_map: None,
..Default::default()
},
Path::new(&self.path),
hash,
self.cm.clone(),
NoopComments,
);
module.body = folder.fold_module(module.clone()).body;

module.visit_mut_children_with(self);
}
}

impl VisitMut for PrefixCode {
fn visit_mut_module(&mut self, module: &mut Module) {
let post_code_snippet_module =
Expand Down

0 comments on commit f946932

Please sign in to comment.