Skip to content

Commit

Permalink
perf: Do not allocate if visitors are not used (#391)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 authored Jan 23, 2025
1 parent 32992a5 commit 5886faf
Show file tree
Hide file tree
Showing 16 changed files with 179 additions and 78 deletions.
25 changes: 10 additions & 15 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ cipher = "0.4.4"
clap = "4.5.4"
convert_case = "0.6.0"
default-from-serde = "0.1"
fxhash = "0.2.1"
handlebars = "5.1.2"
hex = "0.4.3"
langtag = "0.3.2"
Expand Down Expand Up @@ -71,6 +70,7 @@ testing = "5.0.0"
tracing = "0.1.40"
widestring = "1.0.2"

rustc-hash = "2.1.0"
swc_icu_messageformat_parser = { version = "1.0.0", path = "./crates/swc_icu_messageformat_parser" }


Expand Down
6 changes: 6 additions & 0 deletions packages/emotion/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @swc/plugin-emotion

## 8.1.0

### Minor Changes

- 05a2458: Improve performance greatly

## 8.0.4

### Patch Changes
Expand Down
1 change: 1 addition & 0 deletions packages/emotion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
swc_atoms = { workspace = true }
swc_common = { workspace = true, features = ["concurrent"] }
swc_core = { workspace = true, features = ["ecma_plugin_transform"] }
swc_ecma_ast = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions packages/emotion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ Source code for plugin itself (not transforms) are copied from https://github.co
# @swc/plugin-emotion
## 8.1.0
### Minor Changes
- 05a2458: Improve performance greatly
## 8.0.4
### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/emotion/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-emotion",
"version": "8.0.4",
"version": "8.1.0",
"description": "SWC plugin for emotion css-in-js library",
"main": "swc_plugin_emotion.wasm",
"scripts": {
Expand Down
5 changes: 3 additions & 2 deletions packages/emotion/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::path::Path;

use serde::Deserialize;
use swc_atoms::{atom, Atom};
use swc_common::{plugin::metadata::TransformPluginMetadataContextKind, SourceMapper, Spanned};
use swc_ecma_ast::Program;
use swc_emotion::EmotionOptions;
Expand All @@ -23,7 +24,7 @@ enum EmotionJsAutoLabel {
struct EmotionJsOptions {
source_map: Option<bool>,
auto_label: Option<EmotionJsAutoLabel>,
label_format: Option<String>,
label_format: Option<Atom>,
#[serde(flatten)]
extra: swc_emotion::EmotionOptions,
}
Expand All @@ -44,7 +45,7 @@ impl EmotionJsOptions {
EmotionJsAutoLabel::DevOnly => matches!(env_name, "development"),
},
),
label_format: Some(self.label_format.unwrap_or_else(|| "[local]".to_string())),
label_format: Some(self.label_format.unwrap_or_else(|| atom!("[local]"))),
..self.extra
}
}
Expand Down
35 changes: 18 additions & 17 deletions packages/emotion/transform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,29 @@ license = { workspace = true }
name = "swc_emotion"
repository = { workspace = true }
rust-version = { workspace = true }
version = "0.74.1"
version = "0.74.2"


# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
base64 = { workspace = true }
byteorder = { workspace = true }
fxhash = { workspace = true }
once_cell = { workspace = true }
radix_fmt = { workspace = true }
regex = { workspace = true }
serde = { workspace = true }
sourcemap = { workspace = true }
swc_atoms = { workspace = true }
swc_common = { workspace = true }
swc_ecma_ast = { workspace = true }
swc_ecma_codegen = { workspace = true }
swc_ecma_utils = { workspace = true }
swc_ecma_visit = { workspace = true }
swc_trace_macro = { workspace = true }
tracing = { workspace = true }
base64 = { workspace = true }
byteorder = { workspace = true }
once_cell = { workspace = true }
radix_fmt = { workspace = true }
regex = { workspace = true }
rustc-hash = { workspace = true }
serde = { workspace = true }
sourcemap = { workspace = true }
swc_atoms = { workspace = true }
swc_common = { workspace = true }
swc_ecma_ast = { workspace = true }
swc_ecma_codegen = { workspace = true }
swc_ecma_transforms = { workspace = true }
swc_ecma_utils = { workspace = true }
swc_ecma_visit = { workspace = true }
swc_trace_macro = { workspace = true }
tracing = { workspace = true }

[dev-dependencies]
serde_json = { workspace = true }
Expand Down
6 changes: 3 additions & 3 deletions packages/emotion/transform/src/import_map.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};
use swc_atoms::JsWord;
use swc_common::collections::AHashMap;

use crate::{EmotionModuleConfig, ExportItem};

/// key: `importSource`
pub type ImportMap = AHashMap<JsWord, ImportMapValue>;
pub type ImportMap = FxHashMap<JsWord, ImportMapValue>;

/// key: `localExportName`
pub type ImportMapValue = AHashMap<JsWord, ImportItemConfig>;
pub type ImportMapValue = FxHashMap<JsWord, ImportItemConfig>;

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
Expand Down
65 changes: 51 additions & 14 deletions packages/emotion/transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use std::{
};

use base64::Engine;
use fxhash::FxHashMap;
use once_cell::sync::Lazy;
use regex::{Regex, RegexBuilder};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};
use sourcemap::{RawToken, SourceMap as RawSourcemap};
use swc_atoms::JsWord;
use swc_atoms::{atom, Atom};
use swc_common::{comments::Comments, util::take::Take, BytePos, SourceMapperDyn, DUMMY_SP};
use swc_ecma_ast::{
ArrayLit, CallExpr, Callee, ClassDecl, ClassMethod, ClassProp, Expr, ExprOrSpread, FnDecl, Id,
Expand All @@ -20,7 +20,7 @@ use swc_ecma_ast::{
SourceMapperExt, SpreadElement, Tpl, VarDeclarator,
};
use swc_ecma_utils::ExprFactory;
use swc_ecma_visit::{fold_pass, Fold, FoldWith};
use swc_ecma_visit::{Fold, FoldWith, Visit, VisitWith};
use swc_trace_macro::swc_trace;

pub use crate::import_map::*;
Expand Down Expand Up @@ -104,13 +104,17 @@ static MULTI_LINE_COMMENT: Lazy<Regex> = Lazy::new(|| {
static SPACE_AROUND_COLON: Lazy<Regex> =
Lazy::new(|| Regex::new(r"\s*(?P<s>[:;,\{,\}])\s*").unwrap());

fn default_label_format() -> Atom {
atom!("[local]")
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EmotionOptions {
pub enabled: Option<bool>,
pub sourcemap: Option<bool>,
pub auto_label: Option<bool>,
pub label_format: Option<String>,
pub label_format: Option<Atom>,
pub import_map: Option<ImportMap>,
}

Expand All @@ -120,15 +124,15 @@ impl Default for EmotionOptions {
enabled: Some(false),
sourcemap: Some(true),
auto_label: Some(true),
label_format: Some("[local]".to_owned()),
label_format: Some(default_label_format()),
import_map: None,
}
}
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct EmotionModuleConfig {
module_name: JsWord,
module_name: Atom,
exported_names: Vec<ExportItem>,
default_export: Option<ExprKind>,
}
Expand Down Expand Up @@ -168,13 +172,7 @@ pub fn emotion<C: Comments>(
cm: Arc<SourceMapperDyn>,
comments: C,
) -> impl Pass {
fold_pass(EmotionTransformer::new(
emotion_options,
path,
src_file_hash,
cm,
comments,
))
EmotionTransformer::new(emotion_options, path, src_file_hash, cm, comments)
}

pub struct EmotionTransformer<C: Comments> {
Expand Down Expand Up @@ -258,7 +256,7 @@ impl<C: Comments> EmotionTransformer<C> {
self.options
.label_format
.clone()
.unwrap_or_else(|| "[local]".to_owned())
.unwrap_or_else(default_label_format)
);
if let Some(current_context) = &self.current_context {
label = label.replace("[local]", &self.sanitize_label_part(current_context));
Expand Down Expand Up @@ -989,6 +987,45 @@ fn remove_space_around_colon(input: &str, is_first_item: bool, is_last_item: boo
)
}

impl<C> Pass for EmotionTransformer<C>
where
C: Comments,
{
fn process(&mut self, program: &mut swc_ecma_ast::Program) {
let mut checker = ShouldWorkChecker {
should_work: false,
registered_imports: &self.registered_imports,
};
program.visit_with(&mut checker);
if !checker.should_work {
return;
}

program.map_with_mut(|p| p.fold_with(self));
}
}

struct ShouldWorkChecker<'a> {
should_work: bool,

registered_imports: &'a [EmotionModuleConfig],
}

impl Visit for ShouldWorkChecker<'_> {
fn visit_import_decl(&mut self, i: &ImportDecl) {
if self
.registered_imports
.iter()
.any(|item| item.module_name == i.src.value)
{
self.should_work = true;
return;
}

i.visit_children_with(self);
}
}

#[cfg(test)]
mod test_emotion {
use super::minify_css_string;
Expand Down
Loading

0 comments on commit 5886faf

Please sign in to comment.