feat(next-core): apply rsc transform in turbopack (#59629)
### What? Turbopack does not apply same transform for the react server components, which makes missing lot of compilation error validation and custom comments. PR refactors transform to be used in next-swc / turbopack both, then apply it into turbopack. There are still some of test cases are not passing, might need further digging for the transform condition. Closes PACK-2155 --------- Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
This commit is contained in:
parent
f60c609bdb
commit
f641d9ccfc
15 changed files with 449 additions and 266 deletions
222
Cargo.lock
generated
222
Cargo.lock
generated
|
@ -521,9 +521,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "binding_macros"
|
||||
version = "0.61.9"
|
||||
version = "0.61.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6d1716f24e94103e6cb4d0a267d80b3a572692cbdcd7969ff2212adbc340ea7"
|
||||
checksum = "6f223044d1a486a04e27ae0012400169aeb9f6fba2e86f72537c1e827a2f8c1c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"console_error_panic_hook",
|
||||
|
@ -3445,6 +3445,7 @@ dependencies = [
|
|||
"next-swc",
|
||||
"next-transform-dynamic",
|
||||
"next-transform-font",
|
||||
"next-transform-react-server-components",
|
||||
"next-transform-strip-page-exports",
|
||||
"once_cell",
|
||||
"qstring",
|
||||
|
@ -3471,6 +3472,8 @@ dependencies = [
|
|||
"hex",
|
||||
"next-transform-dynamic",
|
||||
"next-transform-font",
|
||||
"next-transform-react-server-components",
|
||||
"next-visitor-cjs-finder",
|
||||
"once_cell",
|
||||
"pathdiff",
|
||||
"react_remove_properties",
|
||||
|
@ -3535,6 +3538,18 @@ dependencies = [
|
|||
"swc_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "next-transform-react-server-components"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"next-visitor-cjs-finder",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"swc_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "next-transform-strip-page-exports"
|
||||
version = "0.1.0"
|
||||
|
@ -3545,6 +3560,13 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "next-visitor-cjs-finder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"swc_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "node-file-trace"
|
||||
version = "0.1.0"
|
||||
|
@ -5258,9 +5280,9 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
|||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
|
@ -5728,9 +5750,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc"
|
||||
version = "0.270.10"
|
||||
version = "0.270.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05aaaaae20ffb7d640865597be257f4ace06ad8556cdf823ac721805cb5d654c"
|
||||
checksum = "7a27aa57c85cbd942540fe5e50f5d665723a1666305506f0cf0daf423903e2a9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.4",
|
||||
|
@ -5794,9 +5816,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_bundler"
|
||||
version = "0.223.8"
|
||||
version = "0.223.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "965299522027c285ac65b8e2419c1fab845e38c08d22e020dbb959afc77286f3"
|
||||
checksum = "e912d8387fc8592465c081b2e6b8df89443117ae4ca5160f21e08d47d7d58d7a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crc",
|
||||
|
@ -5873,9 +5895,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_compiler_base"
|
||||
version = "0.4.8"
|
||||
version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ebca7b430009d4557bf0f9b1d6653fe1adea0aa68a70555499d7b960ef3880"
|
||||
checksum = "2b8a76c7c388f1db934d10ba7fd293ea69e6ed8bd031855b579e4794aff5af85"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.4",
|
||||
|
@ -5921,9 +5943,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_core"
|
||||
version = "0.87.10"
|
||||
version = "0.87.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0e1d5e08e79bea5f7dadd8d8fd023dd60fde1fbcc9c5c87c420b00483af758"
|
||||
checksum = "455c32b15bcdf8cddd87ce4c5d51f89bc16dfb3e6e58959e1cead7634ab2e828"
|
||||
dependencies = [
|
||||
"binding_macros",
|
||||
"swc",
|
||||
|
@ -5962,9 +5984,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_ast"
|
||||
version = "0.140.13"
|
||||
version = "0.140.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec1b459dc890410ea18225d2879786247f1dbc2ddb95eb92cae9dd83c6193ed5"
|
||||
checksum = "85eb09e34d7a6e1869897b4aa884c739c5f5320aea00b35b589d2e4391e47868"
|
||||
dependencies = [
|
||||
"is-macro",
|
||||
"string_enum",
|
||||
|
@ -5974,9 +5996,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_codegen"
|
||||
version = "0.151.22"
|
||||
version = "0.151.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b0abf66b951f31b7bc8e1877edbf64744bb1ccd38b271ca41a57e24b4c99956"
|
||||
checksum = "5d292d3dbf611b6be21980919f8896852af40bbb0d430d6008f4283685137e64"
|
||||
dependencies = [
|
||||
"auto_impl",
|
||||
"bitflags 2.4.0",
|
||||
|
@ -6003,9 +6025,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_compat"
|
||||
version = "0.27.23"
|
||||
version = "0.27.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61b846b7cfc13b28c5d43c0f9927e8ef0b01826da70ccbaee26487f13299c060"
|
||||
checksum = "a544c80e5b481dab958e4bdd1286349b7583b1412e53993fbcf1aeb83d0e585e"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"once_cell",
|
||||
|
@ -6020,9 +6042,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_minifier"
|
||||
version = "0.116.22"
|
||||
version = "0.116.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2a8a5b334be14e66a4ccdf98de4cac7065f901390cf5b761a873673ad251898"
|
||||
checksum = "e9807dea905a6c4696076ff642e507ecaf63e624ef20c55a303017d3e6f301e9"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
|
@ -6034,9 +6056,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_modules"
|
||||
version = "0.29.25"
|
||||
version = "0.29.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2585bd54215cbaa2102904c3ed0262d34c175cfd140c788aa5072e2c2432f745"
|
||||
checksum = "caceeba805e5123dbbe9f4210bb28644ea026bdd7a6f407046c7b3c941573332"
|
||||
dependencies = [
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
|
@ -6050,9 +6072,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_parser"
|
||||
version = "0.150.21"
|
||||
version = "0.150.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c788f5ca9a539504609fde165da45288a55fb3eb07fb2c54bd8df7794dcb072"
|
||||
checksum = "9fb8221a52f2f50cd23c6b70fa024f4ef21a3dd737a67965292fdac49f391036"
|
||||
dependencies = [
|
||||
"lexical",
|
||||
"serde",
|
||||
|
@ -6063,9 +6085,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_prefixer"
|
||||
version = "0.153.23"
|
||||
version = "0.153.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c34762ca85e7136bfb83036467b91a296818471660da2955e5df0d1de14d3f4"
|
||||
checksum = "74adc2822de64d5215ad253ce360dc39f99686dbb46840b6ae374aad69133cfa"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"preset_env_base",
|
||||
|
@ -6080,9 +6102,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_utils"
|
||||
version = "0.137.13"
|
||||
version = "0.137.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6b4b604827b202bcf644ced07ad897ae5cbb5fae62a8a3d154ebca73da06b0f"
|
||||
checksum = "426952c65332d750820cc4cb2b8e21955d6315c57b30939e43def2c48f36c55f"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"serde",
|
||||
|
@ -6095,9 +6117,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_visit"
|
||||
version = "0.139.13"
|
||||
version = "0.139.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "761dc5b0b95b7c950083519dda1f82246566f6682b3b21a009b1e0e20a6d693c"
|
||||
checksum = "0653b91d85ef5415bfd7b205d03d7a4772ec8e324c980873523294bc2e827717"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
|
@ -6108,9 +6130,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_ast"
|
||||
version = "0.110.15"
|
||||
version = "0.110.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aa3e4c43a071a747bf3e18a5423d47aab54048fdedab550d7f3c662127ba4d8"
|
||||
checksum = "79401a45da704f4fb2552c5bf86ee2198e8636b121cb81f8036848a300edd53b"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"bytecheck",
|
||||
|
@ -6128,9 +6150,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_codegen"
|
||||
version = "0.146.48"
|
||||
version = "0.146.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86bb6d13035523d41a75ff9cdfd8802fac15fd0fd7e217306d9ae72f2ddc13f1"
|
||||
checksum = "99b61ca275e3663238b71c4b5da8e6fb745bde9989ef37d94984dfc81fc6d009"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"num-bigint",
|
||||
|
@ -6159,9 +6181,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_bugfixes"
|
||||
version = "0.2.7"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57b38205191eaecddb2c3efe33dfedd6ee97e9cb9a155af7c3c722a7e8895b79"
|
||||
checksum = "9a69ac870b965a458340c6a5a31059f8473093595a1f9efb169002f23bc05261"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -6176,9 +6198,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_common"
|
||||
version = "0.2.2"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33232ee8d61059c3359b8734efbaa9cfb6558c96f6a0d1a85cc06f9cf3d40261"
|
||||
checksum = "8b0a57bd134c03dd545263ee41824a8cb06af1553016dccf8ac1ad8cbbb940c3"
|
||||
dependencies = [
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
|
@ -6189,9 +6211,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2015"
|
||||
version = "0.2.7"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c8f000c0a0c344fb2eee695116aac050894ed3168be00bea7960dbc39a516fd"
|
||||
checksum = "6189b89270bca5d3b103818a49c8decca0f9a63b4507f4f5301b052b0fb42d51"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"indexmap 2.0.0",
|
||||
|
@ -6215,9 +6237,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2016"
|
||||
version = "0.2.5"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ec5acfe5730f317bbf249e9fb92bc926b14f5cb6fda9a58c7ceed30f4f3db32"
|
||||
checksum = "0708c1ae05f82d4e19da2f02a5b093e4e50d581e9bfac527f4aa7693bd791cf7"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -6232,9 +6254,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2017"
|
||||
version = "0.2.5"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92c892ea977c52478805eb387e8abd87180a99c7275b64428a683fa40300d1ac"
|
||||
checksum = "e3701ee2c0321f79258a2acc3633b875af7770cd0173e17a0615d9e707ba32ac"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
|
@ -6250,9 +6272,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2018"
|
||||
version = "0.2.6"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fc343bd82c7d0b457da37b7c90a6f5bb207b4f29f080f34d5509cbc7ee0c71"
|
||||
checksum = "def1e23336a20ca46d297685c2f5c60703eb2d7aea0b8996fefa577be3fad508"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
|
@ -6269,9 +6291,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2019"
|
||||
version = "0.2.5"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db7925f1535272e89fa7688471505fdcf84c07686b8f543f2ff7c7a7c4dffb7a"
|
||||
checksum = "72dd4288e3dfbba53a72410daf190d84d7601f91300e6c524ddea1f0708f2495"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -6285,9 +6307,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2020"
|
||||
version = "0.2.6"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7a049c2b8775dfafe55504810b5619d293b80e3afcf6fc58727d73095d89290"
|
||||
checksum = "f654fe803d73320c723ba25e88b4b561fd1d53ad59ad8622f209fe03f6849b3b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
|
@ -6303,9 +6325,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2021"
|
||||
version = "0.2.5"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e675286ffd4be6d3d038593f3858ab57f761eec4975b3e271c93f3ae1d16b5e"
|
||||
checksum = "9a33089b3b121acadc052ca636905c1dd465db3cc94fa456c26eacc65d5074db"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -6319,9 +6341,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es2022"
|
||||
version = "0.2.6"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5141124b7edbe46da07195a7799dbbdb33815a6e63c4afde9ffeac42e5280b50"
|
||||
checksum = "ebe2a334c1ed213b0a58adb09518c63c63229afad705e5ab027e2fd0f3ff20bd"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -6338,9 +6360,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_compat_es3"
|
||||
version = "0.2.5"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1804166f985561cf8f0f9975ac36a350510910acc224b7c2d437b2f6d15bea2e"
|
||||
checksum = "5b2f3ac54636b7690f17adc9430318d83bf8423635ca848bbb9f9c045e01e377"
|
||||
dependencies = [
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
|
@ -6353,9 +6375,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_ext_transforms"
|
||||
version = "0.111.1"
|
||||
version = "0.111.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "467c0692a8a1a68eed822db03127ecef888eaa8fae9faed510d1b2a8873b8215"
|
||||
checksum = "4e728d14119048a95e023c3c5c0ad5ddddb1f405bfef3bd55f81dc5fc3c9e95a"
|
||||
dependencies = [
|
||||
"phf 0.11.2",
|
||||
"swc_atoms",
|
||||
|
@ -6367,9 +6389,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_lints"
|
||||
version = "0.90.5"
|
||||
version = "0.90.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "695bb91f19bdd0b65d675ebd73895d86b7e0ab4ca1cb81917cc803c468ee45b4"
|
||||
checksum = "5afe579c82fe80a24e8c815fa19e7f1126c8114db0985f211c985d5b4db4137e"
|
||||
dependencies = [
|
||||
"auto_impl",
|
||||
"dashmap",
|
||||
|
@ -6408,9 +6430,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_minifier"
|
||||
version = "0.190.8"
|
||||
version = "0.190.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc73ee27d9a4bcae2f8791913da8bcd610274dcb28e1e17a5fe38d1cb3137496"
|
||||
checksum = "cdd196fa7d01ddd4eaa935f0ddd12854df57db21243aebde9169882d22d381f3"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"indexmap 2.0.0",
|
||||
|
@ -6443,9 +6465,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_parser"
|
||||
version = "0.141.34"
|
||||
version = "0.141.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a67621d078321fb09e73ebe3084da09c352a5dfc1075c6ee833dea2c0209529"
|
||||
checksum = "c4d17401dd95048a6a62b777d533c0999dabdd531ef9d667e22f8ae2a2a0d294"
|
||||
dependencies = [
|
||||
"either",
|
||||
"new_debug_unreachable",
|
||||
|
@ -6465,9 +6487,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_preset_env"
|
||||
version = "0.204.7"
|
||||
version = "0.204.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eda37d5dc19f9462efd4eb0f96f5d32e7258035574c2fb12298a5406d19afaf9"
|
||||
checksum = "94556b1404aa1c8e9f22312fe83a11b5c882b0122557daae1187826575162627"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dashmap",
|
||||
|
@ -6490,9 +6512,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_quote_macros"
|
||||
version = "0.52.34"
|
||||
version = "0.52.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4642b332ceef54ca1420a748d184f9728670fd548726fa6d3f46b01396fe3551"
|
||||
checksum = "d2bd72fda3eb232e08ac6ce9766edb59791dab5f588377c151a1da6c1862b734"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"proc-macro2",
|
||||
|
@ -6520,9 +6542,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.227.7"
|
||||
version = "0.227.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbbbb5ed23c63d99f4290ccaa5715abfaf7c12f0f3ab07423663a5fcb185fe5d"
|
||||
checksum = "b319ba24f6311afa72c5d7e81f06f52b1cd9ad4debf0524eac599b7640b9039a"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -6540,9 +6562,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_base"
|
||||
version = "0.135.5"
|
||||
version = "0.135.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2592b26fc593f5917935d0fe79524e458837de4049b10afb05e3418461dc68a9"
|
||||
checksum = "6d4ab26ec124b03e47f54d4daade8e9a9dcd66d3a4ca3cd47045f138d267a60e"
|
||||
dependencies = [
|
||||
"better_scoped_tls",
|
||||
"bitflags 2.4.0",
|
||||
|
@ -6564,9 +6586,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_classes"
|
||||
version = "0.124.5"
|
||||
version = "0.124.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c560c5d364140754675ecd9404d8f5ea84df354d39ed616d6fd23a15874e2194"
|
||||
checksum = "9fe4376c024fa04394cafb8faecafb4623722b92dbbe46532258cc0a6b569d9c"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -6578,9 +6600,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_compat"
|
||||
version = "0.161.7"
|
||||
version = "0.161.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f86e7531ce193c3ac1babea420db10e8ddefdf8c88c8619b245228c8f4cac7d"
|
||||
checksum = "93a7192ebd94fa4454114ff79513000260ac583d3b80067d9037daa119f318df"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"indexmap 2.0.0",
|
||||
|
@ -6627,9 +6649,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_module"
|
||||
version = "0.178.7"
|
||||
version = "0.178.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "997191873260eb18707f8e5de3c6dc20d4a5e67311532fe4ad2e6bfdadc655ba"
|
||||
checksum = "fc1ba85cf4620c7690eb67f00bf2b1efa0d88265bbbf8cea60dfc7aec59c3e99"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"anyhow",
|
||||
|
@ -6654,9 +6676,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_optimization"
|
||||
version = "0.196.7"
|
||||
version = "0.196.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c489523b48c24d00906b148f59c24b3d07c35c00bf53233d69ef69b603631b13"
|
||||
checksum = "eefef9f5a80afdbd4b517401dc053825d1ac0d95bb63f3ae92d2b335d8d7d4f8"
|
||||
dependencies = [
|
||||
"dashmap",
|
||||
"indexmap 2.0.0",
|
||||
|
@ -6679,9 +6701,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_proposal"
|
||||
version = "0.169.7"
|
||||
version = "0.169.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7854a2eb5953bb35e6db890dd5db6d50b436a489d1fb2a3d02b86187d07f84b5"
|
||||
checksum = "86de99757fc31d8977f47c02a26e5c9a243cb63b03fe8aa8b36d79924b8fa29c"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rustc-hash",
|
||||
|
@ -6699,9 +6721,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_react"
|
||||
version = "0.181.7"
|
||||
version = "0.181.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "574213391391a13cd02fafd6257cc970b71d66a2be823d1107546a1e829d71a2"
|
||||
checksum = "9918e22caf1ea4a71085f5d818d6c0bf5c19d669cfb9d38f9fdc3da0496abdc7"
|
||||
dependencies = [
|
||||
"base64 0.21.4",
|
||||
"dashmap",
|
||||
|
@ -6724,9 +6746,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_testing"
|
||||
version = "0.138.5"
|
||||
version = "0.138.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e90f6f8f95556e05a3abc1d6725a9849bd6dafb2e6a2c67b42aa4c70227df2de"
|
||||
checksum = "c9def5b4509c1764173a5cfce81d46d3d64ae479fbc7f1975ba3758dda4abc79"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
|
@ -6750,9 +6772,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_typescript"
|
||||
version = "0.186.7"
|
||||
version = "0.186.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdf0d2543127998a3be5cc254955e8eb67b93f4048d2f3afda0780f6f3784403"
|
||||
checksum = "e1d1495c969ffdc224384f1fb73646b9c1b170779f20fdb984518deb054aa522"
|
||||
dependencies = [
|
||||
"ryu-js",
|
||||
"serde",
|
||||
|
@ -6767,9 +6789,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_usage_analyzer"
|
||||
version = "0.21.2"
|
||||
version = "0.21.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c7788fc819b3f38c48fd4464d8e98bf041ff58cdc8299243ed62315ce2100"
|
||||
checksum = "2bf6ae5dd022ac6f39034896dd94eaeb590bf1fc6ab6e4f302fc9cdd8569e9b7"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"rustc-hash",
|
||||
|
@ -6784,9 +6806,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_utils"
|
||||
version = "0.125.1"
|
||||
version = "0.125.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cfe59ddbeeba9015fe8fdb82d3141d939e09b70350aa064e183a9a7bc2f36bf"
|
||||
checksum = "7cead1083e46b0f072a82938f16d366014468f7510350957765bb4d013496890"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"num_cpus",
|
||||
|
@ -6803,9 +6825,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_visit"
|
||||
version = "0.96.15"
|
||||
version = "0.96.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a823435d7b3d909391499c1d944be52fb9c6c59d6b5020367a511dfa1b1a3ecd"
|
||||
checksum = "a1d0100c383fb08b6f34911ab6f925950416a5d14404c1cd520d59fb8dfbb3bf"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"serde",
|
||||
|
@ -6938,9 +6960,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_plugin_proxy"
|
||||
version = "0.39.15"
|
||||
version = "0.39.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2de6bfd049cad7723e8298cea8bf4f9ee4851a142f83fe935846887ead28c53d"
|
||||
checksum = "9f00d9e79d36925854ce4de73acf397a6882a0dccb5b248d1ec48202ac3f72ad"
|
||||
dependencies = [
|
||||
"better_scoped_tls",
|
||||
"rkyv",
|
||||
|
@ -6952,9 +6974,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_plugin_runner"
|
||||
version = "0.104.38"
|
||||
version = "0.104.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce10d3783b7792f8f06f8a9cfdd4f5a0ead041dd9fb05b78d0e74741bd1619e"
|
||||
checksum = "26ed41b8a0e1a6afa4bca94c7e78329cccdce9271ec44cd3c4d67d097ce6c03f"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"enumset",
|
||||
|
@ -7401,9 +7423,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.14"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
|
||||
checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
|
|
|
@ -12,6 +12,8 @@ members = [
|
|||
"packages/next-swc/crates/next-transform-font",
|
||||
"packages/next-swc/crates/next-transform-dynamic",
|
||||
"packages/next-swc/crates/next-transform-strip-page-exports",
|
||||
"packages/next-swc/crates/next-transform-react-server-components",
|
||||
"packages/next-swc/crates/next-visitor-cjs-finder",
|
||||
]
|
||||
|
||||
[workspace.lints.clippy]
|
||||
|
@ -34,6 +36,8 @@ next-swc = { path = "packages/next-swc/crates/core" }
|
|||
next-transform-font = { path = "packages/next-swc/crates/next-transform-font" }
|
||||
next-transform-dynamic = { path = "packages/next-swc/crates/next-transform-dynamic" }
|
||||
next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-transform-strip-page-exports" }
|
||||
next-transform-react-server-components = { path = "packages/next-swc/crates/next-transform-react-server-components" }
|
||||
next-visitor-cjs-finder = { path = "packages/next-swc/crates/next-visitor-cjs-finder" }
|
||||
|
||||
# SWC crates
|
||||
swc_core = { version = "0.87.10", features = [
|
||||
|
|
|
@ -26,8 +26,10 @@ serde_json = "1"
|
|||
sha1 = "0.10.1"
|
||||
tracing = { version = "0.1.37" }
|
||||
|
||||
next-visitor-cjs-finder = { workspace = true }
|
||||
next-transform-dynamic = { workspace = true }
|
||||
next-transform-font = { workspace = true }
|
||||
next-transform-react-server-components = { workspace = true }
|
||||
|
||||
turbopack-binding = { workspace = true, features = [
|
||||
"__swc_core",
|
||||
|
|
|
@ -34,11 +34,11 @@ DEALINGS IN THE SOFTWARE.
|
|||
|
||||
use std::{cell::RefCell, path::PathBuf, rc::Rc, sync::Arc};
|
||||
|
||||
use auto_cjs::contains_cjs;
|
||||
use either::Either;
|
||||
use fxhash::FxHashSet;
|
||||
use next_transform_dynamic::{next_dynamic, NextDynamicMode};
|
||||
use next_transform_font::next_font_loaders;
|
||||
use next_visitor_cjs_finder::contains_cjs;
|
||||
use serde::Deserialize;
|
||||
use turbopack_binding::swc::{
|
||||
core::{
|
||||
|
@ -56,7 +56,6 @@ use turbopack_binding::swc::{
|
|||
};
|
||||
|
||||
pub mod amp_attributes;
|
||||
mod auto_cjs;
|
||||
pub mod cjs_optimizer;
|
||||
pub mod disallow_re_export_all_in_page;
|
||||
mod import_analyzer;
|
||||
|
@ -66,7 +65,6 @@ pub mod optimize_barrel;
|
|||
pub mod optimize_server_react;
|
||||
pub mod page_config;
|
||||
pub mod pure;
|
||||
pub mod react_server_components;
|
||||
pub mod server_actions;
|
||||
pub mod shake_exports;
|
||||
|
||||
|
@ -101,7 +99,7 @@ pub struct TransformOptions {
|
|||
pub prefer_esm: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub server_components: Option<react_server_components::Config>,
|
||||
pub server_components: Option<next_transform_react_server_components::Config>,
|
||||
|
||||
#[serde(default)]
|
||||
pub styled_jsx: Option<turbopack_binding::swc::custom_transform::styled_jsx::visitor::Config>,
|
||||
|
@ -194,7 +192,7 @@ where
|
|||
disallow_re_export_all_in_page::disallow_re_export_all_in_page(opts.is_page_file),
|
||||
match &opts.server_components {
|
||||
Some(config) if config.truthy() =>
|
||||
Either::Left(react_server_components::server_components(
|
||||
Either::Left(next_transform_react_server_components::server_components(
|
||||
file.name.clone(),
|
||||
config.clone(),
|
||||
comments.clone(),
|
||||
|
@ -236,7 +234,7 @@ where
|
|||
Some(config) if config.truthy() => match config {
|
||||
// Always enable the Server Components mode for both
|
||||
// server and client layers.
|
||||
react_server_components::Config::WithOptions(config) => config.is_react_server_layer,
|
||||
next_transform_react_server_components::Config::WithOptions(config) => config.is_react_server_layer,
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
|
|
|
@ -63,6 +63,7 @@ turbo-tasks-fs = { workspace = true }
|
|||
next-transform-strip-page-exports = { workspace = true }
|
||||
next-transform-font = { workspace = true }
|
||||
next-transform-dynamic = { workspace = true }
|
||||
next-transform-react-server-components = { workspace = true }
|
||||
|
||||
swc_core = { workspace = true, features = [
|
||||
"ecma_ast",
|
||||
|
|
|
@ -11,7 +11,9 @@ use crate::{
|
|||
next_shared::transforms::{
|
||||
get_next_dynamic_transform_rule, get_next_font_transform_rule, get_next_image_rule,
|
||||
get_next_modularize_imports_rule, get_next_pages_transforms_rule,
|
||||
get_server_actions_transform_rule, server_actions::ActionsTransform,
|
||||
get_server_actions_transform_rule,
|
||||
next_react_server_components::get_next_react_server_components_transform_rule,
|
||||
server_actions::ActionsTransform,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -60,6 +62,11 @@ pub async fn get_next_server_transforms_rules(
|
|||
ActionsTransform::Server,
|
||||
mdx_rs,
|
||||
));
|
||||
|
||||
rules.push(get_next_react_server_components_transform_rule(
|
||||
true, mdx_rs,
|
||||
));
|
||||
|
||||
if let Some(client_transition) = client_transition {
|
||||
rules.push(get_next_css_client_reference_transforms_rule(
|
||||
client_transition,
|
||||
|
|
|
@ -2,6 +2,7 @@ pub(crate) mod emotion;
|
|||
pub(crate) mod modularize_imports;
|
||||
pub(crate) mod next_dynamic;
|
||||
pub(crate) mod next_font;
|
||||
pub(crate) mod next_react_server_components;
|
||||
pub(crate) mod next_strip_page_exports;
|
||||
pub(crate) mod relay;
|
||||
pub(crate) mod server_actions;
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
use next_transform_react_server_components::{server_components, Config, Options};
|
||||
use swc_core::{
|
||||
common::{util::take::Take, FileName},
|
||||
ecma::{
|
||||
ast::{Module, Program},
|
||||
visit::FoldWith,
|
||||
},
|
||||
};
|
||||
use turbo_tasks::Vc;
|
||||
use turbopack_binding::turbopack::{
|
||||
ecmascript::{CustomTransformer, EcmascriptInputTransform, TransformContext},
|
||||
turbopack::module_options::{ModuleRule, ModuleRuleEffect},
|
||||
};
|
||||
|
||||
use super::module_rule_match_js_no_url;
|
||||
|
||||
/// Returns a rule which applies the Next.js react server components transform.
|
||||
pub fn get_next_react_server_components_transform_rule(
|
||||
is_react_server_layer: bool,
|
||||
enable_mdx_rs: bool,
|
||||
) -> ModuleRule {
|
||||
let transformer =
|
||||
EcmascriptInputTransform::Plugin(Vc::cell(Box::new(NextJsReactServerComponents {
|
||||
is_react_server_layer,
|
||||
}) as _));
|
||||
|
||||
ModuleRule::new(
|
||||
module_rule_match_js_no_url(enable_mdx_rs),
|
||||
vec![ModuleRuleEffect::AddEcmascriptTransforms(Vc::cell(vec![
|
||||
transformer,
|
||||
]))],
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NextJsReactServerComponents {
|
||||
is_react_server_layer: bool,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl CustomTransformer for NextJsReactServerComponents {
|
||||
async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> {
|
||||
let p = std::mem::replace(program, Program::Module(Module::dummy()));
|
||||
|
||||
let mut visitor = server_components(
|
||||
FileName::Custom(ctx.file_path_str.to_string()),
|
||||
Config::WithOptions(Options {
|
||||
is_react_server_layer: self.is_react_server_layer,
|
||||
}),
|
||||
ctx.comments,
|
||||
Some(PathBuf::from(ctx.file_path.parent().await?.path.clone())),
|
||||
);
|
||||
|
||||
*program = p.fold_with(&mut visitor);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
[package]
|
||||
name = "next-transform-react-server-components"
|
||||
version = "0.1.0"
|
||||
description = "TBD"
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true, features = ["preserve_order"] }
|
||||
regex = "1.5"
|
||||
anyhow = { workspace = true }
|
||||
|
||||
swc_core = { workspace = true }
|
||||
next-visitor-cjs-finder = { workspace = true }
|
|
@ -1,8 +1,11 @@
|
|||
#![feature(arbitrary_self_types)]
|
||||
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use next_visitor_cjs_finder::contains_cjs;
|
||||
use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use turbopack_binding::swc::core::{
|
||||
use swc_core::{
|
||||
common::{
|
||||
comments::{Comment, CommentKind, Comments},
|
||||
errors::HANDLER,
|
||||
|
@ -16,8 +19,6 @@ use turbopack_binding::swc::core::{
|
|||
},
|
||||
};
|
||||
|
||||
use crate::auto_cjs::contains_cjs;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Config {
|
||||
|
@ -57,6 +58,102 @@ struct ModuleImports {
|
|||
specifiers: Vec<(JsWord, Span)>,
|
||||
}
|
||||
|
||||
enum RSCErrorKind {
|
||||
/// When `use client` and `use server` are in the same file.
|
||||
/// It's not possible to have both directives in the same file.
|
||||
RedundantDirectives(Span),
|
||||
NextRscErrServerImport((String, Span)),
|
||||
NextRscErrClientImport((String, Span)),
|
||||
NextRscErrClientDirective(Span),
|
||||
NextRscErrReactApi((String, Span)),
|
||||
NextRscErrErrorFileServerComponent(Span),
|
||||
NextRscErrClientMetadataExport((String, Span)),
|
||||
NextRscErrConflictMetadataExport(Span),
|
||||
NextRscErrInvalidApi((String, Span)),
|
||||
}
|
||||
|
||||
impl<C: Comments> ReactServerComponents<C> {
|
||||
/// Consolidated place to parse, generate error messages for the RSC parsing
|
||||
/// errors.
|
||||
fn report_error(&self, error_kind: RSCErrorKind) {
|
||||
let (msg, span) = match error_kind {
|
||||
RSCErrorKind::RedundantDirectives(span) => (
|
||||
"It's not possible to have both `use client` and `use server` directives in the \
|
||||
same file."
|
||||
.to_string(),
|
||||
span,
|
||||
),
|
||||
RSCErrorKind::NextRscErrClientDirective(span) => (
|
||||
"The \"use client\" directive must be placed before other expressions. Move it to \
|
||||
the top of the file to resolve this issue."
|
||||
.to_string(),
|
||||
span,
|
||||
),
|
||||
RSCErrorKind::NextRscErrServerImport((source, span)) => {
|
||||
let msg = match source.as_str() {
|
||||
// If importing "react-dom/server", we should show a different error.
|
||||
"react-dom/server" => "You're importing a component that imports react-dom/server. To fix it, render or return the content directly as a Server Component instead for perf and security.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials".to_string(),
|
||||
// If importing "next/router", we should tell them to use "next/navigation".
|
||||
"next/router" => r#"You have a Server Component that imports next/router. Use next/navigation instead.\nLearn more: https://nextjs.org/docs/app/api-reference/functions/use-router"#.to_string(),
|
||||
_ => format!(r#"You're importing a component that imports {}. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials\n\n"#, source)
|
||||
};
|
||||
|
||||
(msg, span)
|
||||
}
|
||||
RSCErrorKind::NextRscErrClientImport((source, span)) => {
|
||||
// [NOTE]: in turbopack currently only type of AppRsc runs this transform,
|
||||
// so it won't hit pages_dir case
|
||||
let is_app_dir = self
|
||||
.app_dir
|
||||
.as_ref()
|
||||
.map(|app_dir| {
|
||||
if let Some(app_dir) = app_dir.as_os_str().to_str() {
|
||||
self.filepath.starts_with(app_dir)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let msg = if !is_app_dir {
|
||||
format!("You're importing a component that needs {}. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components\n\n", source)
|
||||
} else {
|
||||
format!("You're importing a component that needs {}. That only works in a Server Component but one of its parents is marked with \"use client\", so it's a Client Component.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials\n\n", source)
|
||||
};
|
||||
(msg, span)
|
||||
}
|
||||
RSCErrorKind::NextRscErrReactApi((source, span)) => {
|
||||
let msg = if source == "Component" {
|
||||
"You’re importing a class component. It only works in a Client Component but none of its parents are marked with \"use client\", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials#client-components\n\n".to_string()
|
||||
} else {
|
||||
format!("You're importing a component that needs {}. It only works in a Client Component but none of its parents are marked with \"use client\", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials\n\n", source)
|
||||
};
|
||||
|
||||
(msg,span)
|
||||
},
|
||||
RSCErrorKind::NextRscErrErrorFileServerComponent(span) => {
|
||||
(
|
||||
format!("{} must be a Client Component. Add the \"use client\" directive the top of the file to resolve this issue.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials#client-components\n\n", self.filepath),
|
||||
span
|
||||
)
|
||||
},
|
||||
RSCErrorKind::NextRscErrClientMetadataExport((source, span)) => {
|
||||
(format!("You are attempting to export \"{}\" from a component marked with \"use client\", which is disallowed. Either remove the export, or the \"use client\" directive. Read more: https://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive\n\n", source), span)
|
||||
},
|
||||
RSCErrorKind::NextRscErrConflictMetadataExport(span) => (
|
||||
"\"metadata\" and \"generateMetadata\" cannot be exported at the same time, please keep one of them. Read more: https://nextjs.org/docs/app/api-reference/file-conventions/metadata\n\n".to_string(),
|
||||
span
|
||||
),
|
||||
//NEXT_RSC_ERR_INVALID_API
|
||||
RSCErrorKind::NextRscErrInvalidApi((source, span)) => (
|
||||
format!("\"{}\" is not supported in app/. Read more: https://nextjs.org/docs/app/building-your-application/data-fetching\n\n", source), span
|
||||
),
|
||||
};
|
||||
|
||||
HANDLER.with(|handler| handler.struct_span_err(span, msg.as_str()).emit())
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Comments> VisitMut for ReactServerComponents<C> {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
|
@ -106,19 +203,6 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
let mut is_client_entry = false;
|
||||
let mut is_action_file = false;
|
||||
|
||||
fn panic_both_directives(span: Span) {
|
||||
// It's not possible to have both directives in the same file.
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
span,
|
||||
"It's not possible to have both `use client` and `use server` directives \
|
||||
in the same file.",
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
}
|
||||
|
||||
let _ = &module.body.retain(|item| {
|
||||
match item {
|
||||
ModuleItem::Stmt(stmt) => {
|
||||
|
@ -136,17 +220,18 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
is_client_entry = true;
|
||||
|
||||
if is_action_file {
|
||||
panic_both_directives(expr_stmt.span)
|
||||
self.report_error(
|
||||
RSCErrorKind::RedundantDirectives(
|
||||
expr_stmt.span,
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
expr_stmt.span,
|
||||
"NEXT_RSC_ERR_CLIENT_DIRECTIVE",
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(
|
||||
RSCErrorKind::NextRscErrClientDirective(
|
||||
expr_stmt.span,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Remove the directive.
|
||||
|
@ -155,7 +240,9 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
is_action_file = true;
|
||||
|
||||
if is_client_entry {
|
||||
panic_both_directives(expr_stmt.span)
|
||||
self.report_error(RSCErrorKind::RedundantDirectives(
|
||||
expr_stmt.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,14 +253,11 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
finished_directives = true;
|
||||
if let Expr::Lit(Lit::Str(Str { value, .. })) = &**expr {
|
||||
if &**value == "use client" {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
expr_stmt.span,
|
||||
"NEXT_RSC_ERR_CLIENT_DIRECTIVE_PAREN",
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(
|
||||
RSCErrorKind::NextRscErrClientDirective(
|
||||
expr_stmt.span,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,40 +434,28 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
for import in imports {
|
||||
let source = import.source.0.clone();
|
||||
if self.invalid_server_imports.contains(&source) {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
import.source.1,
|
||||
format!("NEXT_RSC_ERR_SERVER_IMPORT: {}", source).as_str(),
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrServerImport((
|
||||
source.to_string(),
|
||||
import.source.1,
|
||||
)));
|
||||
}
|
||||
if source == *"react" {
|
||||
for specifier in &import.specifiers {
|
||||
if self.invalid_server_react_apis.contains(&specifier.0) {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
specifier.1,
|
||||
format!("NEXT_RSC_ERR_REACT_API: {}", &specifier.0).as_str(),
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrReactApi((
|
||||
specifier.0.to_string(),
|
||||
specifier.1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if source == *"react-dom" {
|
||||
for specifier in &import.specifiers {
|
||||
if self.invalid_server_react_dom_apis.contains(&specifier.0) {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
specifier.1,
|
||||
format!("NEXT_RSC_ERR_REACT_API: {}", &specifier.0).as_str(),
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrReactApi((
|
||||
specifier.0.to_string(),
|
||||
specifier.1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -404,17 +476,13 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
if let Some(app_dir) = &self.app_dir {
|
||||
if let Some(app_dir) = app_dir.to_str() {
|
||||
if self.filepath.starts_with(app_dir) {
|
||||
HANDLER.with(|handler| {
|
||||
let span = if let Some(first_item) = module.body.first() {
|
||||
first_item.span()
|
||||
} else {
|
||||
module.span
|
||||
};
|
||||
let span = if let Some(first_item) = module.body.first() {
|
||||
first_item.span()
|
||||
} else {
|
||||
module.span
|
||||
};
|
||||
|
||||
handler
|
||||
.struct_span_err(span, "NEXT_RSC_ERR_ERROR_FILE_SERVER_COMPONENT")
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrErrorFileServerComponent(span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,14 +496,10 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
for import in imports {
|
||||
let source = import.source.0.clone();
|
||||
if self.invalid_client_imports.contains(&source) {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
import.source.1,
|
||||
format!("NEXT_RSC_ERR_CLIENT_IMPORT: {}", source).as_str(),
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrClientImport((
|
||||
source.to_string(),
|
||||
import.source.1,
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,41 +582,25 @@ impl<C: Comments> ReactServerComponents<C> {
|
|||
// Client entry can't export `generateMetadata` or `metadata`.
|
||||
if is_client_entry {
|
||||
if has_gm_export || has_metadata_export {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
span,
|
||||
format!(
|
||||
"NEXT_RSC_ERR_CLIENT_METADATA_EXPORT: {}",
|
||||
invalid_export_name
|
||||
)
|
||||
.as_str(),
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrClientMetadataExport((
|
||||
invalid_export_name.clone(),
|
||||
span,
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
// Server entry can't export `generateMetadata` and `metadata` together.
|
||||
if has_gm_export && has_metadata_export {
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(span, "NEXT_RSC_ERR_CONFLICT_METADATA_EXPORT")
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrConflictMetadataExport(span));
|
||||
}
|
||||
}
|
||||
// Assert `getServerSideProps` and `getStaticProps` exports.
|
||||
if invalid_export_name == "getServerSideProps"
|
||||
|| invalid_export_name == "getStaticProps"
|
||||
{
|
||||
HANDLER.with(|handler| {
|
||||
handler
|
||||
.struct_span_err(
|
||||
span,
|
||||
format!("NEXT_RSC_ERR_INVALID_API: {}", invalid_export_name).as_str(),
|
||||
)
|
||||
.emit()
|
||||
})
|
||||
self.report_error(RSCErrorKind::NextRscErrInvalidApi((
|
||||
invalid_export_name.clone(),
|
||||
span,
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
15
packages/next-swc/crates/next-visitor-cjs-finder/Cargo.toml
Normal file
15
packages/next-swc/crates/next-visitor-cjs-finder/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "next-visitor-cjs-finder"
|
||||
version = "0.1.0"
|
||||
description = "TBD"
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
swc_core = { workspace = true }
|
|
@ -1,9 +1,9 @@
|
|||
use turbopack_binding::swc::core::ecma::{
|
||||
use swc_core::ecma::{
|
||||
ast::*,
|
||||
visit::{Visit, VisitWith},
|
||||
};
|
||||
|
||||
pub(crate) fn contains_cjs(m: &Module) -> bool {
|
||||
pub fn contains_cjs(m: &Module) -> bool {
|
||||
let mut v = CjsFinder::default();
|
||||
m.visit_with(&mut v);
|
||||
v.found && !v.is_esm
|
|
@ -280,7 +280,7 @@ describe('Error overlay - RSC build errors', () => {
|
|||
|
||||
expect(await session.hasRedbox(true)).toBe(true)
|
||||
expect(await session.getRedboxSource()).toInclude(
|
||||
`You're importing a component that needs ${api}. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.`
|
||||
`You're importing a component that needs ${api}. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components`
|
||||
)
|
||||
|
||||
await cleanup()
|
||||
|
@ -348,25 +348,29 @@ describe('Error overlay - RSC build errors', () => {
|
|||
)
|
||||
|
||||
expect(await session.hasRedbox(true)).toBe(true)
|
||||
await check(() => session.getRedboxSource(), /must be a Client Component/)
|
||||
await check(
|
||||
() => session.getRedboxSource(),
|
||||
/must be a Client \n| Component/
|
||||
)
|
||||
expect(
|
||||
next.normalizeTestDirContent(await session.getRedboxSource())
|
||||
).toMatchInlineSnapshot(
|
||||
next.normalizeSnapshot(`
|
||||
`
|
||||
"./app/server-with-errors/error-file/error.js
|
||||
ReactServerComponentsError:
|
||||
|
||||
./app/server-with-errors/error-file/error.js must be a Client Component. Add the "use client" directive the top of the file to resolve this issue.
|
||||
Learn more: https://nextjs.org/docs/getting-started/react-essentials#client-components
|
||||
|
||||
Error:
|
||||
x TEST_DIR/app/server-with-errors/error-file/error.js must be a Client Component. Add the "use client" directive the top
|
||||
| of the file to resolve this issue.
|
||||
| Learn more: https://nextjs.org/docs/getting-started/react-essentials#client-components
|
||||
|
|
||||
|
|
||||
,-[TEST_DIR/app/server-with-errors/error-file/error.js:1:1]
|
||||
1 | export default function Error() {}
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
\`----
|
||||
|
||||
Import path:
|
||||
Import trace for requested module:
|
||||
./app/server-with-errors/error-file/error.js"
|
||||
`)
|
||||
`
|
||||
)
|
||||
|
||||
await cleanup()
|
||||
|
|
|
@ -53,28 +53,27 @@ describe('Error Overlay for server components compiler errors in pages', () => {
|
|||
() => session.getRedboxSource(),
|
||||
/That only works in a Server Component/
|
||||
)
|
||||
expect(
|
||||
next.normalizeTestDirContent(await session.getRedboxSource())
|
||||
).toMatchInlineSnapshot(
|
||||
next.normalizeSnapshot(`
|
||||
"./components/Comp.js
|
||||
ReactServerComponentsError:
|
||||
|
||||
You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components
|
||||
expect(next.normalizeTestDirContent(await session.getRedboxSource()))
|
||||
.toMatchInlineSnapshot(`
|
||||
"./components/Comp.js
|
||||
Error:
|
||||
x You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/
|
||||
| react-essentials#server-components
|
||||
|
|
||||
|
|
||||
,-[TEST_DIR/components/Comp.js:1:1]
|
||||
1 | import { cookies } from 'next/headers'
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2 |
|
||||
3 | export default function Page() {
|
||||
4 | return <p>hello world</p>
|
||||
\`----
|
||||
|
||||
,-[TEST_DIR/components/Comp.js:1:1]
|
||||
1 | import { cookies } from 'next/headers'
|
||||
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
2 |
|
||||
3 | export default function Page() {
|
||||
4 | return <p>hello world</p>
|
||||
\`----
|
||||
|
||||
Import trace for requested module:
|
||||
./components/Comp.js
|
||||
./pages/index.js"
|
||||
`)
|
||||
)
|
||||
Import trace for requested module:
|
||||
./components/Comp.js
|
||||
./pages/index.js"
|
||||
`)
|
||||
|
||||
await cleanup()
|
||||
})
|
||||
|
@ -85,7 +84,7 @@ describe('Error Overlay for server components compiler errors in pages', () => {
|
|||
await next.patchFile(
|
||||
'components/Comp.js',
|
||||
outdent`
|
||||
import 'server-only'
|
||||
import 'server-only'
|
||||
|
||||
export default function Page() {
|
||||
return 'hello world'
|
||||
|
@ -98,28 +97,27 @@ describe('Error Overlay for server components compiler errors in pages', () => {
|
|||
() => session.getRedboxSource(),
|
||||
/That only works in a Server Component/
|
||||
)
|
||||
expect(
|
||||
next.normalizeTestDirContent(await session.getRedboxSource())
|
||||
).toMatchInlineSnapshot(
|
||||
next.normalizeSnapshot(`
|
||||
"./components/Comp.js
|
||||
ReactServerComponentsError:
|
||||
|
||||
You're importing a component that needs server-only. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components
|
||||
expect(next.normalizeTestDirContent(await session.getRedboxSource()))
|
||||
.toMatchInlineSnapshot(`
|
||||
"./components/Comp.js
|
||||
Error:
|
||||
x You're importing a component that needs server-only. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/
|
||||
| react-essentials#server-components
|
||||
|
|
||||
|
|
||||
,-[TEST_DIR/components/Comp.js:1:1]
|
||||
1 | import 'server-only'
|
||||
: ^^^^^^^^^^^^^^^^^^^^
|
||||
2 |
|
||||
3 | export default function Page() {
|
||||
4 | return 'hello world'
|
||||
\`----
|
||||
|
||||
,-[TEST_DIR/components/Comp.js:1:1]
|
||||
1 | import 'server-only'
|
||||
: ^^^^^^^^^^^^^^^^^^^^
|
||||
2 |
|
||||
3 | export default function Page() {
|
||||
4 | return 'hello world'
|
||||
\`----
|
||||
|
||||
Import trace for requested module:
|
||||
./components/Comp.js
|
||||
./pages/index.js"
|
||||
`)
|
||||
)
|
||||
Import trace for requested module:
|
||||
./components/Comp.js
|
||||
./pages/index.js"
|
||||
`)
|
||||
|
||||
await cleanup()
|
||||
})
|
||||
|
|
|
@ -1126,11 +1126,8 @@
|
|||
"Error overlay - RSC build errors should error for invalid undefined module retuning from next dynamic",
|
||||
"Error overlay - RSC build errors should error when page component export is not valid",
|
||||
"Error overlay - RSC build errors should error when page component export is not valid on initial load",
|
||||
"Error overlay - RSC build errors should freeze parent resolved metadata to avoid mutating in generateMetadata"
|
||||
],
|
||||
"failed": [
|
||||
"Error overlay - RSC build errors should freeze parent resolved metadata to avoid mutating in generateMetadata",
|
||||
"Error overlay - RSC build errors should allow to use and handle rsc poisoning client-only",
|
||||
"Error overlay - RSC build errors should allow to use and handle rsc poisoning server-only",
|
||||
"Error overlay - RSC build errors should error when Component from react is used in server component",
|
||||
"Error overlay - RSC build errors should error when PureComponent from react is used in server component",
|
||||
"Error overlay - RSC build errors should error when createContext from react is used in server component",
|
||||
|
@ -1152,7 +1149,10 @@
|
|||
"Error overlay - RSC build errors should error when useSyncExternalStore from react is used in server component",
|
||||
"Error overlay - RSC build errors should error when useTransition from react is used in server component",
|
||||
"Error overlay - RSC build errors should throw an error when \"Component\" is imported in server components",
|
||||
"Error overlay - RSC build errors should throw an error when \"use client\" is on the top level but after other expressions",
|
||||
"Error overlay - RSC build errors should throw an error when \"use client\" is on the top level but after other expressions"
|
||||
],
|
||||
"failed": [
|
||||
"Error overlay - RSC build errors should allow to use and handle rsc poisoning server-only",
|
||||
"Error overlay - RSC build errors should throw an error when error file is a server component",
|
||||
"Error overlay - RSC build errors should throw an error when error file is a server component with empty error file",
|
||||
"Error overlay - RSC build errors should throw an error when getServerSideProps is used",
|
||||
|
|
Loading…
Reference in a new issue