Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ecma-plugins): extract custom emotion transform #4662

Merged
merged 5 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ members = [
"crates/turbopack-dev",
"crates/turbopack-dev-server",
"crates/turbopack-ecmascript",
"crates/turbopack-ecmascript-plugins",
"crates/turbopack-env",
"crates/turbopack-image",
"crates/turbopack-json",
Expand Down Expand Up @@ -134,6 +135,7 @@ turbopack-css = { path = "crates/turbopack-css" }
turbopack-dev = { path = "crates/turbopack-dev" }
turbopack-dev-server = { path = "crates/turbopack-dev-server" }
turbopack-ecmascript = { path = "crates/turbopack-ecmascript" }
turbopack-ecmascript-plugins = { path = "crates/turbopack-ecmascript-plugins" }
turbopack-env = { path = "crates/turbopack-env" }
turbopack-image = { path = "crates/turbopack-image" }
turbopack-json = { path = "crates/turbopack-json" }
Expand Down
7 changes: 7 additions & 0 deletions crates/turbo-binding/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ __turbopack_dev_dynamic_embed_contents = [
]
__turbopack_dev_server = ["__turbopack", "turbopack-dev-server"]
__turbopack_ecmascript = ["__turbopack", "turbopack-ecmascript"]
# [Note]: currently all of the transform features are enabled by default
__turbopack_ecmascript_plugin = [
"__turbopack",
"turbopack-ecmascript-plugins",
"turbopack-ecmascript-plugins/transform_emotion",
]
__turbopack_env = ["__turbopack", "turbopack-env"]
__turbopack_image = ["__turbopack", "turbopack-image"]
__turbopack_image_avif = ["turbopack-image/avif"]
Expand Down Expand Up @@ -185,6 +191,7 @@ turbopack-css = { optional = true, workspace = true }
turbopack-dev = { optional = true, workspace = true }
turbopack-dev-server = { optional = true, workspace = true }
turbopack-ecmascript = { optional = true, workspace = true }
turbopack-ecmascript-plugins = { optional = true, workspace = true }
turbopack-env = { optional = true, workspace = true }
turbopack-image = { optional = true, workspace = true }
turbopack-json = { optional = true, workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions crates/turbo-binding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ pub mod turbopack {
pub use turbopack_dev_server as dev_server;
#[cfg(feature = "__turbopack_ecmascript")]
pub use turbopack_ecmascript as ecmascript;
#[cfg(feature = "__turbopack_ecmascript_plugin")]
pub use turbopack_ecmascript_plugins as ecmascript_plugin;
#[cfg(feature = "__turbopack_env")]
pub use turbopack_env as env;
#[cfg(feature = "__turbopack_image")]
Expand Down
3 changes: 3 additions & 0 deletions crates/turbopack-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ turbopack-cli-utils = { workspace = true }
turbopack-core = { workspace = true }
turbopack-dev = { workspace = true }
turbopack-dev-server = { workspace = true }
turbopack-ecmascript-plugins = { workspace = true, features = [
"transform_emotion",
] }
turbopack-env = { workspace = true }
turbopack-node = { workspace = true }
webbrowser = { workspace = true }
Expand Down
5 changes: 3 additions & 2 deletions crates/turbopack-cli/src/dev/web_entry_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use turbopack::{
condition::ContextCondition,
ecmascript::EcmascriptModuleAssetVc,
module_options::{
EmotionTransformConfigVc, JsxTransformOptions, ModuleOptionsContext,
ModuleOptionsContextVc, StyledComponentsTransformConfigVc,
JsxTransformOptions, ModuleOptionsContext, ModuleOptionsContextVc,
StyledComponentsTransformConfigVc,
},
resolve_options_context::{ResolveOptionsContext, ResolveOptionsContextVc},
transition::TransitionsByNameVc,
Expand All @@ -35,6 +35,7 @@ use turbopack_dev_server::{
html::DevHtmlAssetVc,
source::{asset_graph::AssetGraphContentSourceVc, ContentSourceVc},
};
use turbopack_ecmascript_plugins::transform::emotion::EmotionTransformConfigVc;
use turbopack_node::execution_context::ExecutionContextVc;

use crate::embed_js::embed_file_path;
Expand Down
1 change: 1 addition & 0 deletions crates/turbopack-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ pub(crate) mod embed_js;
pub fn register() {
turbopack::register();
turbopack_dev::register();
turbopack_ecmascript_plugins::register();
include!(concat!(env!("OUT_DIR"), "/register.rs"));
}
26 changes: 26 additions & 0 deletions crates/turbopack-ecmascript-plugins/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "turbopack-ecmascript-plugins"
version = "0.1.0"
description = "TBD"
license = "MPL-2.0"
edition = "2021"
autobenches = false

[lib]
bench = false

[features]
transform_emotion = []

[dependencies]
anyhow = { workspace = true }
serde = { workspace = true }

turbo-tasks = { workspace = true }
turbopack-ecmascript = { workspace = true }

swc_core = { workspace = true, features = ["ecma_ast", "ecma_visit", "common"] }
swc_emotion = { workspace = true }

[build-dependencies]
turbo-tasks-build = { workspace = true }
5 changes: 5 additions & 0 deletions crates/turbopack-ecmascript-plugins/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use turbo_tasks_build::generate_register;

fn main() {
generate_register();
}
7 changes: 7 additions & 0 deletions crates/turbopack-ecmascript-plugins/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub mod transform;

pub fn register() {
turbo_tasks::register();
turbopack_ecmascript::register();
include!(concat!(env!("OUT_DIR"), "/register.rs"));
}
126 changes: 126 additions & 0 deletions crates/turbopack-ecmascript-plugins/src/transform/emotion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#![allow(unused)]
use std::{
hash::{Hash, Hasher},
path::Path,
};

use anyhow::Result;
use serde::{Deserialize, Serialize};
use swc_core::{
common::util::take::Take,
ecma::{
ast::{Module, Program},
visit::FoldWith,
},
};
use turbo_tasks::trace::TraceRawVcs;
use turbopack_ecmascript::{CustomTransformer, TransformContext};

#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum EmotionLabelKind {
DevOnly,
Always,
Never,
}

#[turbo_tasks::value(transparent)]
pub struct OptionEmotionTransformConfig(Option<EmotionTransformConfigVc>);

//[TODO]: need to support importmap, there are type mismatch between
//next.config.js to swc's emotion options
#[turbo_tasks::value(shared)]
#[derive(Default, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct EmotionTransformConfig {
pub sourcemap: Option<bool>,
pub label_format: Option<String>,
pub auto_label: Option<EmotionLabelKind>,
}

#[turbo_tasks::value_impl]
impl EmotionTransformConfigVc {
#[turbo_tasks::function]
pub fn default() -> Self {
Self::cell(Default::default())
}
}

impl Default for EmotionTransformConfigVc {
fn default() -> Self {
Self::default()
}
}

#[derive(Debug)]
pub struct EmotionTransformer {
#[cfg(feature = "transform_emotion")]
config: swc_emotion::EmotionOptions,
}

#[cfg(feature = "transform_emotion")]
impl EmotionTransformer {
pub fn new(config: &EmotionTransformConfig) -> Option<Self> {
let config = swc_emotion::EmotionOptions {
// When you create a transformer structure, it is assumed that you are performing an
// emotion transform.
enabled: Some(true),
sourcemap: config.sourcemap,
label_format: config.label_format.clone(),
auto_label: if let Some(auto_label) = config.auto_label.as_ref() {
match auto_label {
EmotionLabelKind::Always => Some(true),
EmotionLabelKind::Never => Some(false),
// [TODO]: this is not correct coerece, need to be fixed
EmotionLabelKind::DevOnly => None,
}
} else {
None
},
..Default::default()
};

Some(EmotionTransformer { config })
}
}

#[cfg(not(feature = "transform_emotion"))]
impl EmotionTransformer {
pub fn new(_config: &EmotionTransformConfig) -> Option<Self> {
None
}
}

impl CustomTransformer for EmotionTransformer {
fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Option<Program> {
#[cfg(feature = "transform_emotion")]
{
let p = std::mem::replace(program, Program::Module(Module::dummy()));
let hash = {
#[allow(clippy::disallowed_types)]
let mut hasher = std::collections::hash_map::DefaultHasher::new();
p.hash(&mut hasher);
hasher.finish()
};
*program = p.fold_with(&mut swc_emotion::emotion(
self.config.clone(),
Path::new(ctx.file_name_str),
hash as u32,
ctx.source_map.clone(),
ctx.comments.clone(),
));
}

None
}
}

pub async fn build_emotion_transformer(
config: &Option<EmotionTransformConfigVc>,
) -> Result<Option<Box<EmotionTransformer>>> {
Ok(if let Some(config) = config {
EmotionTransformer::new(&*config.await?).map(Box::new)
} else {
None
})
}
1 change: 1 addition & 0 deletions crates/turbopack-ecmascript-plugins/src/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod emotion;
4 changes: 2 additions & 2 deletions crates/turbopack-ecmascript/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ use swc_core::{
},
};
pub use transform::{
CustomTransform, CustomTransformVc, CustomTransformer, EcmascriptInputTransform,
EcmascriptInputTransformsVc, TransformContext,
CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransformsVc, TransformContext,
TransformPlugin, TransformPluginVc,
};
use turbo_tasks::{
primitives::StringVc, trace::TraceRawVcs, RawVc, ReadRef, TryJoinIterExt, Value, ValueToString,
Expand Down
Loading