Skip to content

Commit

Permalink
refactor(next-swc): introduce next-binding to consolidate dependencie…
Browse files Browse the repository at this point in the history
…s. (#43473)

<!--
Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change that you're making:
-->

Partial solutions for WEB-225.

One of the issue we want to improve is version bump process across
multiple dependencies sharing same transitive dependencies. There were
known cases of last-minute build failures of next-swc due to this. The
biggest thing is we have lot of dependenceis rely on swc_core, and
consolidating it altogether is tricky.

PR introduces `next-binding`, which reexports all the related
dependencies that next-swc and turbopack commonly uses. Unfortunately,
this is not a complete solution, but at least it'll make `upfront` cost
to turbopack when it try to update swc_core and others, so by the time
upgrading it in next-swc we expect minimal friction. Note not 0
friction: due to how cargo behaves for the merging all of the features,
there's still chances to have some build failures but meaningfully less
I believe.

I think the easiest way to describe before / after is having some
diagrams. This is rather simplified to illustrate problems easily, i.e
when it comes to actual build if there are same version of deps cargo
will dedupe, so below illustaration only would occur for non-compatible
version cases, etcs.

**Before**
```mermaid
graph TD
    A[next-swc] --> B(next-dev)
    A --> C(swc_core)
    A --> D(swc_emotion)
    D --> E(swc_core)
    A --> F(styled_jsx)
    F --> E
    A --> G(mdxrs)
    G --> H(swc_core)
    B --> I(swc_core)
    B --> J(swc_emotion)
    J --> K(swc_core)
```

**After**
```mermaid
graph TD
    A[next-swc] --> B(next-binding)
    B --> C[swc_core]
    B --> D[swc_emotion]
    D --> I[swc_core]
    B --> H[styled_jsx]
    B --> F[next-dev]
    B --> J[node-file-trace]
    F --> C
    H --> I
    B --> E(mdxrs)
    E --> G(swc_core)
 ```

You can see repeated dependencies (`swc_core`, `swc_emotion`) occurs lot more in next-swc in `before`, including next-swc top level direct import itself. In result, update process have to align between next-swc, turbopack, swc-plugins and others.

With newly proposed changes, `next-swc` no longer directly owns deps reduces those repetaed deps. At the moment of version bump, only `next-binding` need to be updated.

This brings small caveat however : next-swc does not directly update `swc_core`, but have to bump turbopack and its transitive dependencies. Given our bump process usually requires to bump up turbopack anyway, I wouldn't consider this as hard blocking though.
  • Loading branch information
kwonoj committed Dec 16, 2022
1 parent 1e0acc2 commit b45c815
Show file tree
Hide file tree
Showing 34 changed files with 181 additions and 186 deletions.
33 changes: 23 additions & 10 deletions packages/next-swc/Cargo.lock

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

37 changes: 14 additions & 23 deletions packages/next-swc/crates/core/Cargo.toml
Expand Up @@ -5,9 +5,7 @@ version = "0.0.0"
publish = false

[features]
plugin = [
"swc_core/plugin_transform_host_native"
]
plugin = ["next-binding/__swc_core_binding_napi_plugin"]

[dependencies]
chrono = "0.4"
Expand All @@ -25,26 +23,19 @@ styled_jsx = "0.29.8"
modularize_imports = "0.25.8"
tracing = { version = "0.1.37", features = ["release_max_level_info"] }

swc_core = { features = [
"common_concurrent",
"ecma_ast",
"ecma_visit",
"ecma_loader_node",
"ecma_loader_lru",
"ecma_utils",
"ecma_minifier",
"ecma_transforms",
"__ecma_transforms",
"ecma_transforms_react",
"ecma_transforms_typescript",
"ecma_transforms_optimization",
"ecma_parser",
"ecma_parser_typescript",
"cached",
"base"
], version = "0.45.4" }
next-binding = { git = "https://github.com/vercel/turbo.git", rev = "cc024fa59f1c3ad253e74eefe86e0386455455d1", features = [
"__swc_core",
"__swc_core_next_core",
"__swc_transform_styled_jsx",
"__swc_transform_emotion",
"__swc_transform_styled_components",
"__swc_transform_modularize_imports",
] }

[dev-dependencies]
swc_core = { features = ["testing_transform"], version = "0.45.4" }
testing = "0.31.14"
next-binding = { git = "https://github.com/vercel/turbo.git", rev = "cc024fa59f1c3ad253e74eefe86e0386455455d1", features = [
"__swc_core_testing_transform",
"__swc_testing",
] }

walkdir = "2.3.2"
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/src/amp_attributes.rs
@@ -1,4 +1,4 @@
use swc_core::{
use next_binding::swc::core::{
ecma::ast::{Ident, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXElementName, JSXOpeningElement},
ecma::atoms::JsWord,
ecma::visit::Fold,
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/src/auto_cjs/mod.rs
@@ -1,4 +1,4 @@
use swc_core::{
use next_binding::swc::core::{
ecma::ast::*,
ecma::visit::{Visit, VisitWith},
};
Expand Down
@@ -1,4 +1,4 @@
use swc_core::{
use next_binding::swc::core::{
common::errors::HANDLER,
ecma::ast::ExportAll,
ecma::transforms::base::pass::Optional,
Expand Down
52 changes: 31 additions & 21 deletions packages/next-swc/crates/core/src/lib.rs
Expand Up @@ -38,7 +38,7 @@ use std::cell::RefCell;
use std::rc::Rc;
use std::{path::PathBuf, sync::Arc};

use swc_core::{
use next_binding::swc::core::{
base::config::ModuleConfig,
common::{chain, comments::Comments, pass::Optional, FileName, SourceFile, SourceMap},
ecma::ast::EsVersion,
Expand Down Expand Up @@ -66,7 +66,7 @@ mod top_level_binding_collector;
#[serde(rename_all = "camelCase")]
pub struct TransformOptions {
#[serde(flatten)]
pub swc: swc_core::base::config::Options,
pub swc: next_binding::swc::core::base::config::Options,

#[serde(default)]
pub disable_next_ssg: bool,
Expand All @@ -93,7 +93,7 @@ pub struct TransformOptions {
pub styled_jsx: bool,

#[serde(default)]
pub styled_components: Option<styled_components::Config>,
pub styled_components: Option<next_binding::swc::custom_transform::styled_components::Config>,

#[serde(default)]
pub remove_console: Option<remove_console::Config>,
Expand All @@ -115,10 +115,10 @@ pub struct TransformOptions {
pub shake_exports: Option<shake_exports::Config>,

#[serde(default)]
pub emotion: Option<swc_emotion::EmotionOptions>,
pub emotion: Option<next_binding::swc::custom_transform::emotion::EmotionOptions>,

#[serde(default)]
pub modularize_imports: Option<modularize_imports::Config>,
pub modularize_imports: Option<next_binding::swc::custom_transform::modularize_imports::Config>,

#[serde(default)]
pub font_loaders: Option<next_font_loaders::Config>,
Expand Down Expand Up @@ -162,19 +162,23 @@ where
_ => Either::Right(noop()),
},
if opts.styled_jsx {
Either::Left(styled_jsx::visitor::styled_jsx(
cm.clone(),
file.name.clone(),
))
Either::Left(
next_binding::swc::custom_transform::styled_jsx::visitor::styled_jsx(
cm.clone(),
file.name.clone(),
),
)
} else {
Either::Right(noop())
},
match &opts.styled_components {
Some(config) => Either::Left(styled_components::styled_components(
file.name.clone(),
file.src_hash,
config.clone(),
)),
Some(config) => Either::Left(
next_binding::swc::custom_transform::styled_components::styled_components(
file.name.clone(),
file.src_hash,
config.clone(),
)
),
None => Either::Right(noop()),
},
Optional::new(
Expand Down Expand Up @@ -216,20 +220,26 @@ where
}
if let FileName::Real(path) = &file.name {
path.to_str().map(|_| {
Either::Left(swc_emotion::EmotionTransformer::new(
config.clone(),
path,
cm,
comments,
))
Either::Left(
next_binding::swc::custom_transform::emotion::EmotionTransformer::new(
config.clone(),
path,
cm,
comments,
),
)
})
} else {
None
}
})
.unwrap_or_else(|| Either::Right(noop())),
match &opts.modularize_imports {
Some(config) => Either::Left(modularize_imports::modularize_imports(config.clone())),
Some(config) => Either::Left(
next_binding::swc::custom_transform::modularize_imports::modularize_imports(
config.clone()
)
),
None => Either::Right(noop()),
},
match &opts.font_loaders {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/src/next_dynamic.rs
Expand Up @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf};

use pathdiff::diff_paths;

use swc_core::{
use next_binding::swc::core::{
common::{errors::HANDLER, FileName, DUMMY_SP},
ecma::ast::{
ArrayLit, ArrowExpr, BinExpr, BinaryOp, BlockStmtOrExpr, Bool, CallExpr, Callee, Expr,
Expand Down
@@ -1,7 +1,7 @@
use swc_core::common::errors::HANDLER;
use swc_core::ecma::ast::*;
use swc_core::ecma::visit::noop_visit_type;
use swc_core::ecma::visit::Visit;
use next_binding::swc::core::common::errors::HANDLER;
use next_binding::swc::core::ecma::ast::*;
use next_binding::swc::core::ecma::visit::noop_visit_type;
use next_binding::swc::core::ecma::visit::Visit;

pub struct FindFunctionsOutsideModuleScope<'a> {
pub state: &'a super::State,
Expand Down
@@ -1,8 +1,8 @@
use swc_core::common::errors::HANDLER;
use swc_core::ecma::ast::*;
use swc_core::ecma::atoms::JsWord;
use swc_core::ecma::visit::noop_visit_type;
use swc_core::ecma::visit::Visit;
use next_binding::swc::core::common::errors::HANDLER;
use next_binding::swc::core::ecma::ast::*;
use next_binding::swc::core::ecma::atoms::JsWord;
use next_binding::swc::core::ecma::visit::noop_visit_type;
use next_binding::swc::core::ecma::visit::Visit;

pub struct FontFunctionsCollector<'a> {
pub font_loaders: &'a [JsWord],
Expand Down
@@ -1,9 +1,9 @@
use next_binding::swc::core::common::errors::HANDLER;
use next_binding::swc::core::common::{Spanned, DUMMY_SP};
use next_binding::swc::core::ecma::ast::*;
use next_binding::swc::core::ecma::atoms::JsWord;
use next_binding::swc::core::ecma::visit::{noop_visit_type, Visit};
use serde_json::Value;
use swc_core::common::errors::HANDLER;
use swc_core::common::{Spanned, DUMMY_SP};
use swc_core::ecma::ast::*;
use swc_core::ecma::atoms::JsWord;
use swc_core::ecma::visit::{noop_visit_type, Visit};

pub struct FontImportsGenerator<'a> {
pub state: &'a mut super::State,
Expand Down
4 changes: 2 additions & 2 deletions packages/next-swc/crates/core/src/next_font_loaders/mod.rs
@@ -1,13 +1,13 @@
use fxhash::FxHashSet;
use serde::Deserialize;
use swc_core::{
use next_binding::swc::core::{
common::{collections::AHashMap, BytePos, Spanned},
ecma::{
ast::Id,
visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitWith},
},
ecma::{ast::ModuleItem, atoms::JsWord},
};
use serde::Deserialize;

mod find_functions_outside_module_scope;
mod font_functions_collector;
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/src/next_ssg.rs
Expand Up @@ -4,7 +4,7 @@ use std::cell::RefCell;
use std::mem::take;
use std::rc::Rc;

use swc_core::{
use next_binding::swc::core::{
common::{
errors::HANDLER,
pass::{Repeat, Repeated},
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/src/page_config.rs
@@ -1,6 +1,6 @@
use chrono::Utc;

use swc_core::{
use next_binding::swc::core::{
common::{errors::HANDLER, Span, DUMMY_SP},
ecma::ast::*,
ecma::visit::{Fold, FoldWith},
Expand Down
@@ -1,7 +1,7 @@
use regex::Regex;
use serde::Deserialize;

use swc_core::{
use next_binding::swc::core::{
ecma::ast::*,
ecma::visit::{noop_fold_type, Fold, FoldWith},
};
Expand Down
@@ -1,7 +1,7 @@
use regex::Regex;
use serde::Deserialize;

use swc_core::{
use next_binding::swc::core::{
common::{
comments::{Comment, CommentKind, Comments},
errors::HANDLER,
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/src/relay.rs
Expand Up @@ -3,7 +3,7 @@ use regex::Regex;
use serde::Deserialize;
use std::path::{Path, PathBuf};

use swc_core::{
use next_binding::swc::core::{
common::{errors::HANDLER, FileName},
ecma::ast::*,
ecma::atoms::JsWord,
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/src/remove_console.rs
@@ -1,6 +1,6 @@
use serde::Deserialize;

use swc_core::{
use next_binding::swc::core::{
common::{collections::AHashSet, DUMMY_SP},
ecma::ast::*,
ecma::atoms::JsWord,
Expand Down

0 comments on commit b45c815

Please sign in to comment.