Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit84e103b

Browse files
authored
chore: Backport SWC-based RC optimization (#78260)
### What?Backport#75605### Why?x-ref:https://vercel.slack.com/archives/C06DGJ420TZ/p1744644426250019
1 parenta9e7a24 commit84e103b

File tree

10 files changed

+183
-17
lines changed

10 files changed

+183
-17
lines changed

‎crates/napi/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub mod minify;
5050
#[cfg(not(target_arch ="wasm32"))]
5151
pubmod next_api;
5252
pubmod parse;
53+
pubmod react_compiler;
5354
pubmod transform;
5455
#[cfg(not(target_arch ="wasm32"))]
5556
pubmod turbo_trace_server;

‎crates/napi/src/react_compiler.rs‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use std::{path::PathBuf, sync::Arc};
2+
3+
use napi::bindgen_prelude::*;
4+
use next_custom_transforms::react_compiler;
5+
use swc_core::{
6+
common::{SourceMap,GLOBALS},
7+
ecma::{
8+
ast::EsVersion,
9+
parser::{parse_file_as_program,Syntax,TsSyntax},
10+
},
11+
};
12+
13+
pubstructCheckTask{
14+
pubfilename:PathBuf,
15+
}
16+
17+
#[napi]
18+
implTaskforCheckTask{
19+
typeOutput =bool;
20+
typeJsValue =bool;
21+
22+
fncompute(&mutself) -> napi::Result<Self::Output>{
23+
GLOBALS.set(&Default::default(), ||{
24+
//
25+
let cm =Arc::new(SourceMap::default());
26+
letOk(fm) = cm.load_file(&self.filename.clone())else{
27+
returnOk(false);
28+
};
29+
letmut errors =vec![];
30+
letOk(program) =parse_file_as_program(
31+
&fm,
32+
Syntax::Typescript(TsSyntax{
33+
tsx:true,
34+
..Default::default()
35+
}),
36+
EsVersion::EsNext,
37+
None,
38+
&mut errors,
39+
)else{
40+
returnOk(false);
41+
};
42+
if !errors.is_empty(){
43+
returnOk(false);
44+
}
45+
46+
Ok(react_compiler::is_required(&program))
47+
})
48+
}
49+
50+
fnresolve(&mutself,_env:Env,result:Self::Output) -> napi::Result<Self::JsValue>{
51+
Ok(result)
52+
}
53+
}
54+
55+
#[napi]
56+
pubfnis_react_compiler_required(
57+
filename:String,
58+
signal:Option<AbortSignal>,
59+
) ->AsyncTask<CheckTask>{
60+
let filename =PathBuf::from(filename);
61+
AsyncTask::with_optional_signal(CheckTask{ filename}, signal)
62+
}

‎crates/next-custom-transforms/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use rustc_hash::FxHasher;
3939

4040
pubmod chain_transforms;
4141
mod linter;
42+
pubmod react_compiler;
4243
pubmod transforms;
4344

4445
typeFxIndexMap<K,V> =IndexMap<K,V,BuildHasherDefault<FxHasher>>;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use swc_core::ecma::{
2+
ast::{Callee,Expr,FnDecl,FnExpr,Program,ReturnStmt},
3+
visit::{Visit,VisitWith},
4+
};
5+
6+
pubfnis_required(program:&Program) ->bool{
7+
letmut finder =Finder::default();
8+
finder.visit_program(program);
9+
finder.found
10+
}
11+
12+
#[derive(Default)]
13+
structFinder{
14+
found:bool,
15+
16+
/// We are in a function that starts with a capital letter or it's a function that starts with
17+
/// `use`
18+
is_interested:bool,
19+
}
20+
21+
implVisitforFinder{
22+
fnvisit_callee(&mutself,node:&Callee){
23+
ifself.is_interested{
24+
ifletCallee::Expr(e) = node{
25+
ifletExpr::Ident(c) =&**e{
26+
if c.sym.starts_with("use"){
27+
self.found =true;
28+
return;
29+
}
30+
}
31+
}
32+
}
33+
34+
node.visit_children_with(self);
35+
}
36+
37+
fnvisit_fn_decl(&mutself,node:&FnDecl){
38+
let old =self.is_interested;
39+
self.is_interested = node.ident.sym.starts_with("use")
40+
|| node.ident.sym.starts_with(|c:char| c.is_ascii_uppercase());
41+
42+
node.visit_children_with(self);
43+
44+
self.is_interested = old;
45+
}
46+
47+
fnvisit_fn_expr(&mutself,node:&FnExpr){
48+
let old =self.is_interested;
49+
50+
self.is_interested = node.ident.as_ref().is_some_and(|ident|{
51+
ident.sym.starts_with("use") || ident.sym.starts_with(|c:char| c.is_ascii_uppercase())
52+
});
53+
54+
node.visit_children_with(self);
55+
56+
self.is_interested = old;
57+
}
58+
59+
fnvisit_return_stmt(&mutself,node:&ReturnStmt){
60+
ifself.is_interested{
61+
ifletSome(Expr::JSXElement(..) |Expr::JSXEmpty(..) |Expr::JSXFragment(..)) =
62+
node.arg.as_deref()
63+
{
64+
self.found =true;
65+
return;
66+
}
67+
}
68+
69+
node.visit_children_with(self);
70+
}
71+
}

‎packages/next/src/build/babel/loader/get-config.ts‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { NextBabelLoaderOptions, NextJsLoaderContext } from './types'
88
import{consumeIterator}from'./util'
99
import*asLogfrom'../../output/log'
1010
importjsxfrom'next/dist/compiled/babel/plugin-syntax-jsx'
11+
import{isReactCompilerRequired}from'../../swc'
1112

1213
constnextDistPath=
1314
/(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/
@@ -257,15 +258,15 @@ function checkCustomBabelConfigDeprecation(
257258
* Generate a new, flat Babel config, ready to be handed to Babel-traverse.
258259
* This config should have no unresolved overrides, presets, etc.
259260
*/
260-
functiongetFreshConfig(
261+
asyncfunctiongetFreshConfig(
261262
this:NextJsLoaderContext,
262263
cacheCharacteristics:CharacteristicsGermaneToCaching,
263264
loaderOptions:NextBabelLoaderOptions,
264265
target:string,
265266
filename:string,
266267
inputSourceMap?:object|null
267268
){
268-
consthasReactCompiler=(()=>{
269+
consthasReactCompiler=await(async()=>{
269270
if(
270271
loaderOptions.reactCompilerPlugins&&
271272
loaderOptions.reactCompilerPlugins.length===0
@@ -284,6 +285,10 @@ function getFreshConfig(
284285
returnfalse
285286
}
286287

288+
if(!(awaitisReactCompilerRequired(filename))){
289+
returnfalse
290+
}
291+
287292
returntrue
288293
})()
289294

@@ -436,7 +441,7 @@ type BabelConfig = any
436441
constconfigCache:Map<any,BabelConfig>=newMap()
437442
constconfigFiles:Set<string>=newSet()
438443

439-
exportdefaultfunctiongetConfig(
444+
exportdefaultasyncfunctiongetConfig(
440445
this:NextJsLoaderContext,
441446
{
442447
source,
@@ -451,7 +456,7 @@ export default function getConfig(
451456
filename:string
452457
inputSourceMap?:object|null
453458
}
454-
):BabelConfig{
459+
):Promise<BabelConfig>{
455460
constcacheCharacteristics=getCacheCharacteristics(
456461
loaderOptions,
457462
source,
@@ -493,7 +498,7 @@ export default function getConfig(
493498
)
494499
}
495500

496-
constfreshConfig=getFreshConfig.call(
501+
constfreshConfig=awaitgetFreshConfig.call(
497502
this,
498503
cacheCharacteristics,
499504
loaderOptions,

‎packages/next/src/build/babel/loader/index.ts‎

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@ async function nextBabelLoader(
2727

2828
constloaderSpanInner=parentTrace.traceChild('next-babel-turbo-transform')
2929
const{code:transformedSource,map:outputSourceMap}=
30-
loaderSpanInner.traceFn(()=>
31-
transform.call(
32-
this,
33-
inputSource,
34-
inputSourceMap,
35-
loaderOptions,
36-
filename,
37-
target,
38-
loaderSpanInner
39-
)
30+
awaitloaderSpanInner.traceAsyncFn(
31+
async()=>
32+
awaittransform.call(
33+
this,
34+
inputSource,
35+
inputSourceMap,
36+
loaderOptions,
37+
filename,
38+
target,
39+
loaderSpanInner
40+
)
4041
)
4142

4243
return[transformedSource,outputSourceMap]

‎packages/next/src/build/babel/loader/transform.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function transformAst(file: any, babelConfig: any, parentSpan: Span) {
6969
}
7070
}
7171

72-
exportdefaultfunctiontransform(
72+
exportdefaultasyncfunctiontransform(
7373
this:NextJsLoaderContext,
7474
source:string,
7575
inputSourceMap:object|null|undefined,
@@ -79,7 +79,7 @@ export default function transform(
7979
parentSpan:Span
8080
){
8181
constgetConfigSpan=parentSpan.traceChild('babel-turbo-get-config')
82-
constbabelConfig=getConfig.call(this,{
82+
constbabelConfig=awaitgetConfig.call(this,{
8383
source,
8484
loaderOptions,
8585
inputSourceMap,

‎packages/next/src/build/swc/generated-native.d.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ export declare function parse(
367367
filename?:string|undefined|null,
368368
signal?:AbortSignal|undefined|null
369369
):Promise<string>
370+
exportdeclarefunctionisReactCompilerRequired(
371+
filename:string,
372+
signal?:AbortSignal|undefined|null
373+
):Promise<boolean>
370374
exportdeclarefunctiontransform(
371375
src:string|Buffer|undefined,
372376
isModule:boolean,

‎packages/next/src/build/swc/index.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,11 @@ async function loadWasm(importPath = '') {
11041104
returnbindings.mdxCompileSync(src,getMdxOptions(options))
11051105
},
11061106
},
1107+
reactCompiler:{
1108+
isReactCompilerRequired(_filename:string){
1109+
returnPromise.resolve(true)
1110+
},
1111+
},
11071112
}
11081113
returnwasmBindings
11091114
}catch(e:any){
@@ -1275,6 +1280,11 @@ function loadNative(importPath?: string) {
12751280
},
12761281
},
12771282
},
1283+
reactCompiler:{
1284+
isReactCompilerRequired:(filename:string)=>{
1285+
returnbindings.isReactCompilerRequired(filename)
1286+
},
1287+
},
12781288
}
12791289
returnnativeBindings
12801290
}
@@ -1320,6 +1330,13 @@ export async function minify(
13201330
returnbindings.minify(src,options)
13211331
}
13221332

1333+
exportasyncfunctionisReactCompilerRequired(
1334+
filename:string
1335+
):Promise<boolean>{
1336+
letbindings=awaitloadBindings()
1337+
returnbindings.reactCompiler.isReactCompilerRequired(filename)
1338+
}
1339+
13231340
exportasyncfunctionparse(src:string,options:any):Promise<any>{
13241341
letbindings=awaitloadBindings()
13251342
letparserOptions=getParserOptions(options)

‎packages/next/src/build/swc/types.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export interface Binding {
3939
transformStyleAttr(transformAttrOptions:any):Promise<any>
4040
}
4141
}
42+
43+
reactCompiler:{
44+
isReactCompilerRequired(filename:string):Promise<boolean>
45+
}
4246
}
4347

4448
exporttypeStyledString=

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp