Skip to content

Commit bad99c6

Browse files
fix(turbopack-ecmascript): make free var replacements (compile time defines) work for member expressions and allow JSON values (vercel/turborepo#6000)
1 parent c60b682 commit bad99c6

File tree

8 files changed

+51
-33
lines changed

8 files changed

+51
-33
lines changed

crates/turbopack-core/src/compile_time_info.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,14 @@ macro_rules! free_var_references {
7272
};
7373
}
7474

75+
// TODO: replace with just a `serde_json::Value`
76+
// https://linear.app/vercel/issue/WEB-1641/compiletimedefinevalue-should-just-use-serde-jsonvalue
7577
#[turbo_tasks::value(serialization = "auto_for_input")]
7678
#[derive(Debug, Clone, Hash, PartialOrd, Ord)]
7779
pub enum CompileTimeDefineValue {
7880
Bool(bool),
7981
String(String),
82+
JSON(String),
8083
}
8184

8285
impl From<bool> for CompileTimeDefineValue {
@@ -97,7 +100,14 @@ impl From<&str> for CompileTimeDefineValue {
97100
}
98101
}
99102

103+
impl From<serde_json::Value> for CompileTimeDefineValue {
104+
fn from(value: serde_json::Value) -> Self {
105+
Self::JSON(value.to_string())
106+
}
107+
}
108+
100109
#[turbo_tasks::value(transparent)]
110+
#[derive(Debug, Clone)]
101111
pub struct CompileTimeDefines(pub IndexMap<Vec<String>, CompileTimeDefineValue>);
102112

103113
impl IntoIterator for CompileTimeDefines {
@@ -118,7 +128,7 @@ impl CompileTimeDefines {
118128
}
119129

120130
#[turbo_tasks::value]
121-
#[derive(Debug)]
131+
#[derive(Debug, Clone)]
122132
pub enum FreeVarReference {
123133
EcmaScriptModule {
124134
request: String,
@@ -153,6 +163,7 @@ impl From<CompileTimeDefineValue> for FreeVarReference {
153163
}
154164

155165
#[turbo_tasks::value(transparent)]
166+
#[derive(Debug, Clone)]
156167
pub struct FreeVarReferences(pub IndexMap<Vec<String>, FreeVarReference>);
157168

158169
#[turbo_tasks::value_impl]
@@ -164,6 +175,7 @@ impl FreeVarReferences {
164175
}
165176

166177
#[turbo_tasks::value(shared)]
178+
#[derive(Debug, Clone)]
167179
pub struct CompileTimeInfo {
168180
pub environment: Vc<Environment>,
169181
pub defines: Vc<CompileTimeDefines>,

crates/turbopack-ecmascript/src/analyzer/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ impl From<&CompileTimeDefineValue> for JsValue {
502502
match v {
503503
CompileTimeDefineValue::String(s) => JsValue::Constant(s.as_str().into()),
504504
CompileTimeDefineValue::Bool(b) => JsValue::Constant((*b).into()),
505+
CompileTimeDefineValue::JSON(_) => JsValue::unknown_empty("compile time injected JSON"),
505506
}
506507
}
507508
}

crates/turbopack-ecmascript/src/path_visitor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ impl VisitMutAstPath for ApplyVisitors<'_, '_> {
144144
// TODO: we need a macro to apply that for all methods
145145
method!(visit_mut_prop, Prop);
146146
method!(visit_mut_expr, Expr);
147+
method!(visit_mut_member_expr, MemberExpr);
147148
method!(visit_mut_pat, Pat);
148149
method!(visit_mut_stmt, Stmt);
149150
method!(visit_mut_module_decl, ModuleDecl);

crates/turbopack-ecmascript/src/references/constant_value.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,20 @@ impl CodeGenerateable for ConstantValue {
3535
_context: Vc<Box<dyn EcmascriptChunkingContext>>,
3636
) -> Result<Vc<CodeGeneration>> {
3737
let value = self.value.clone();
38-
let visitors = [
39-
create_visitor!(exact &self.path.await?, visit_mut_expr(expr: &mut Expr) {
40-
*expr = match value {
41-
CompileTimeDefineValue::Bool(true) => quote!("(\"TURBOPACK compile-time value\", true)" as Expr),
42-
CompileTimeDefineValue::Bool(false) => quote!("(\"TURBOPACK compile-time value\", false)" as Expr),
43-
CompileTimeDefineValue::String(ref s) => quote!("(\"TURBOPACK compile-time value\", $e)" as Expr, e: Expr = s.to_string().into()),
44-
};
45-
}),
46-
]
47-
.into();
38+
let path = &self.path.await?;
4839

49-
Ok(CodeGeneration { visitors }.cell())
40+
let visitor = create_visitor!(path, visit_mut_expr(expr: &mut Expr) {
41+
*expr = match value {
42+
CompileTimeDefineValue::Bool(true) => quote!("(\"TURBOPACK compile-time value\", true)" as Expr),
43+
CompileTimeDefineValue::Bool(false) => quote!("(\"TURBOPACK compile-time value\", false)" as Expr),
44+
CompileTimeDefineValue::String(ref s) => quote!("(\"TURBOPACK compile-time value\", $e)" as Expr, e: Expr = s.to_string().into()),
45+
CompileTimeDefineValue::JSON(ref s) => quote!("(\"TURBOPACK compile-time value\", JSON.parse($e))" as Expr, e: Expr = s.to_string().into()),
46+
};
47+
});
48+
49+
Ok(CodeGeneration {
50+
visitors: vec![visitor],
51+
}
52+
.cell())
5053
}
5154
}

crates/turbopack-tests/tests/snapshot.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::{
1111
use anyhow::{bail, Context, Result};
1212
use dunce::canonicalize;
1313
use serde::Deserialize;
14+
use serde_json::json;
1415
use turbo_tasks::{ReadRef, TryJoinIterExt, TurboTasks, Value, ValueToString, Vc};
1516
use turbo_tasks_env::DotenvProcessEnv;
1617
use turbo_tasks_fs::{
@@ -34,6 +35,7 @@ use turbopack_core::{
3435
context::AssetContext,
3536
environment::{BrowserEnvironment, Environment, ExecutionEnvironment, NodeJsEnvironment},
3637
file_source::FileSource,
38+
free_var_references,
3739
issue::{Issue, IssueDescriptionExt},
3840
module::Module,
3941
output::OutputAsset,
@@ -209,17 +211,18 @@ async fn run_test(resource: String) -> Result<Vc<FileSystemPath>> {
209211
)
210212
}
211213
}));
214+
215+
let defines = compile_time_defines!(
216+
process.turbopack = true,
217+
process.env.NODE_ENV = "development",
218+
DEFINED_VALUE = "value",
219+
DEFINED_TRUE = true,
220+
A.VERY.LONG.DEFINED.VALUE = json!({ "test": true }),
221+
);
222+
212223
let compile_time_info = CompileTimeInfo::builder(env)
213-
.defines(
214-
compile_time_defines!(
215-
process.turbopack = true,
216-
process.env.NODE_ENV = "development",
217-
DEFINED_VALUE = "value",
218-
DEFINED_TRUE = true,
219-
A.VERY.LONG.DEFINED.VALUE = "value",
220-
)
221-
.cell(),
222-
)
224+
.defines(defines.clone().cell())
225+
.free_var_references(free_var_references!(..defines.into_iter()).cell())
223226
.cell();
224227

225228
let custom_ecma_transform_plugins = Some(CustomEcmascriptTransformPlugins::cell(

crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ if (process.env.NODE_ENV === 'production') {
2020

2121
var p = process;
2222

23-
// TODO: replacement is not implemented yet
2423
console.log(A.VERY.LONG.DEFINED.VALUE);
2524
console.log(DEFINED_VALUE);
2625
console.log(p.env.NODE_ENV);

crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js

Lines changed: 7 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_b53fce.js.map

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)