feat(next-swc): Update swc crates (#35996)
* Move * Adjust * publish = false * Tree * Move tests * fixup * Split `emotion` * Split `styled_jsx` * Split `styled_jsx` * fmt * `--fix` * clippy * Update crates * fixup * publish * Bump * Rename * authors * Update * More update * Oh * Update test refs * Update test refs * Update again * Fix
This commit is contained in:
parent
01109734ce
commit
16f7084e7f
265 changed files with 4467 additions and 317 deletions
248
packages/next-swc/Cargo.lock
generated
248
packages/next-swc/Cargo.lock
generated
|
@ -63,12 +63,6 @@ version = "1.0.56"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.2"
|
||||
|
@ -723,6 +717,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json_comments"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41ee439ee368ba4a77ac70d04f14015415af8600d6c894dc1f11bd79758c57d5"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
@ -819,9 +819,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
@ -904,9 +904,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mimalloc-rust"
|
||||
version = "0.1.1"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffcd5c93c5b59f49b89b58100fad6ea023dbec6f9344f0d0932a96d9497821a"
|
||||
checksum = "bcc30df9dfdb5bb6cb2470de65ca604c3eaa3e5dc2ad02a9a98f567df5844472"
|
||||
dependencies = [
|
||||
"cty",
|
||||
"mimalloc-rust-sys",
|
||||
|
@ -914,9 +914,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mimalloc-rust-sys"
|
||||
version = "1.7.2"
|
||||
version = "1.7.3-source"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96f7f32dcc7aeb79781116048bbd27cc819b9db55805690b3379d536d40e9590"
|
||||
checksum = "3adc8731262b982f4e0860770dba118305cafe1b2e7ebe95b29b2c2f46a70666"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cty",
|
||||
|
@ -938,6 +938,20 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "modularize_imports"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"handlebars",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"serde",
|
||||
"swc_cached",
|
||||
"swc_ecma_transforms_testing",
|
||||
"swc_ecmascript",
|
||||
"testing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi"
|
||||
version = "1.8.0"
|
||||
|
@ -983,30 +997,26 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
|||
name = "next-swc"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"easy-error",
|
||||
"either",
|
||||
"fxhash",
|
||||
"handlebars",
|
||||
"modularize_imports",
|
||||
"once_cell",
|
||||
"pathdiff",
|
||||
"radix_fmt",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"styled_components",
|
||||
"styled_jsx",
|
||||
"swc",
|
||||
"swc_atoms",
|
||||
"swc_cached",
|
||||
"swc_common",
|
||||
"swc_css",
|
||||
"swc_css_prefixer",
|
||||
"swc_ecma_loader",
|
||||
"swc_ecma_transforms_testing",
|
||||
"swc_ecmascript",
|
||||
"swc_node_base",
|
||||
"swc_emotion",
|
||||
"testing",
|
||||
"tracing",
|
||||
"walkdir",
|
||||
|
@ -1037,13 +1047,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.0"
|
||||
version = "7.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109"
|
||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1325,14 +1334,14 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
|||
|
||||
[[package]]
|
||||
name = "preset_env_base"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e44b8d534a4ecea4519138ff80780a499691c4e948bc063651487e069966a703"
|
||||
checksum = "44b10336bf81e96a223c487607acb08a1407d3e208a65e477190e3fe51fc5dea"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"browserslist-rs",
|
||||
"dashmap 4.0.2",
|
||||
"dashmap 5.1.0",
|
||||
"from_variant",
|
||||
"once_cell",
|
||||
"semver 1.0.6",
|
||||
|
@ -1712,19 +1721,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "st-map"
|
||||
version = "0.1.4"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3caeb13a58f859600a7b75fffe66322e1fca0122ca02cfc7262344a7e30502d1"
|
||||
checksum = "bc9c9f3a1df5f73b7392bd9773108fef41ad9126f0282412fd5904389f0c0c4f"
|
||||
dependencies = [
|
||||
"arrayvec 0.5.2",
|
||||
"arrayvec",
|
||||
"static-map-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static-map-macro"
|
||||
version = "0.2.1"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5503e07f148238811bbfd578684a0457c7284bab41b60d76def35431a1295fd"
|
||||
checksum = "752564de9cd8937fdbc1c55d47ac391758c352ab3755607cc391b659fe87d56b"
|
||||
dependencies = [
|
||||
"pmutil",
|
||||
"proc-macro2",
|
||||
|
@ -1785,17 +1794,32 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
|||
|
||||
[[package]]
|
||||
name = "styled_components"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a29f0d8eb056b9763d224462594cda0f2dc96aa613fab7ada00ade37d3f05443"
|
||||
version = "0.26.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_transforms_testing",
|
||||
"swc_ecmascript",
|
||||
"testing",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "styled_jsx"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"easy-error",
|
||||
"swc_common",
|
||||
"swc_css",
|
||||
"swc_css_prefixer",
|
||||
"swc_ecma_transforms_testing",
|
||||
"swc_ecmascript",
|
||||
"testing",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -1829,9 +1853,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc"
|
||||
version = "0.161.1"
|
||||
version = "0.164.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21ec4e431e58f946a96690e348e5a876534a2d99ccebc0690610f5410f0ccb89"
|
||||
checksum = "661eab0d653f9f4a15ed5f832c4f2cb63823cb8e0aec4bed7f07ec4b73fb2c54"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
|
@ -1839,6 +1863,7 @@ dependencies = [
|
|||
"dashmap 5.1.0",
|
||||
"either",
|
||||
"indexmap",
|
||||
"json_comments",
|
||||
"lru",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
|
@ -1883,9 +1908,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_bundler"
|
||||
version = "0.130.0"
|
||||
version = "0.133.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7019f6b663117b77c085b4bc432d13370fd7715fe1a7e63cb54070756710133a"
|
||||
checksum = "052dafe1f3a9144331ee15f0a3f2c5fe0bb535e19f0bc1ada374b2d0256c314c"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
|
@ -1932,9 +1957,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_common"
|
||||
version = "0.17.18"
|
||||
version = "0.17.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "278ad1cbb3fb3b2686c86a7dd5f307ef791918d249a6da60fa6cd3388f4c6a78"
|
||||
checksum = "41b22848d9ad250e618289ea94a171392aea86d8d878caf0b1cad4589521b6f7"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"ast_node",
|
||||
|
@ -1962,9 +1987,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css"
|
||||
version = "0.103.0"
|
||||
version = "0.104.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35b5f2bb2b2845da367ce7343e8c4821849694d4294fd54cdd8663bb08d04ac0"
|
||||
checksum = "9835ebfd7815b71f9b8f2ae95f65defe06692f96b26ef39acbe7d64bd33aa1c4"
|
||||
dependencies = [
|
||||
"swc_css_ast",
|
||||
"swc_css_codegen",
|
||||
|
@ -1975,9 +2000,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_ast"
|
||||
version = "0.91.0"
|
||||
version = "0.92.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f124ebd2d7588bb68e7902485a497a7f0e7e9876f113cd3f9f366a7bbb5bf7b4"
|
||||
checksum = "8ee9ad91b962d5713f41a8d2222d1f4c78ee3e1a8f7529427bb7289277e52509"
|
||||
dependencies = [
|
||||
"is-macro",
|
||||
"serde",
|
||||
|
@ -1988,9 +2013,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_codegen"
|
||||
version = "0.100.0"
|
||||
version = "0.101.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "895cfa7ee88d809ecefb9af9da2c1c8c2f45e58e303967cfe0aaa96d319064d7"
|
||||
checksum = "b2bfa5fef9aa88ad90c643d17cfab1ab88d3bf32b351b4307e96ea3feae9aa65"
|
||||
dependencies = [
|
||||
"auto_impl",
|
||||
"bitflags",
|
||||
|
@ -2015,9 +2040,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_parser"
|
||||
version = "0.99.0"
|
||||
version = "0.100.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7b306eb9375370f47c252d4f41068e0ca9e8d3f0d365142ba44be95287db149"
|
||||
checksum = "63ba20eb665492621fee54b67432c29f58a8f440541d2c68f549d212cd595dea"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"lexical",
|
||||
|
@ -2028,9 +2053,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_prefixer"
|
||||
version = "0.99.3"
|
||||
version = "0.100.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "301926ee69de04a6643f9c4ac8dcc67c6a5de3edd9fe218c6c2cf99f8c934652"
|
||||
checksum = "18c5f217ee19b60c74fd3a26eba2d778da094c6f8c6f581142656845491f7051"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -2041,9 +2066,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_utils"
|
||||
version = "0.88.2"
|
||||
version = "0.89.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e57af5708496f58a8777f1e23b82fcb8745404a480fb5588a9ed57baf48c5bbe"
|
||||
checksum = "1590d47d3d254226c4561b31e72347b5ac75ea7a49531d032fda65415b8990f3"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -2053,9 +2078,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_css_visit"
|
||||
version = "0.90.0"
|
||||
version = "0.91.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c60ac83b8c5ffc8e3ff1c2fb60036f30d7a747534df55d2f05bb01c66ed83427"
|
||||
checksum = "7713c4d8255be1b7d5e93580fd2f32bfbb3c832a60be2941948e62442a207b04"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -2065,9 +2090,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_ast"
|
||||
version = "0.73.0"
|
||||
version = "0.75.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20447f3de45ecf25ecb13d7ca039fae8ea9c2acdcde1efb020526b5f7ffbc7a"
|
||||
checksum = "72961898fbe56591997e667a1ec6a268383582810351c279a15ec710b6177d33"
|
||||
dependencies = [
|
||||
"is-macro",
|
||||
"num-bigint",
|
||||
|
@ -2080,9 +2105,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_codegen"
|
||||
version = "0.101.0"
|
||||
version = "0.103.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55757ca4dd7bd6882beeef38352e730ea06b772c14b1c49a46aa489605794def"
|
||||
checksum = "99ca430d8ea2c8791d1341c4035431c90b87330e39479b4a6dabb4fded124e30"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
|
@ -2112,9 +2137,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_ext_transforms"
|
||||
version = "0.63.0"
|
||||
version = "0.65.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d94b94ebbace370a5b28c9b57801e52f43580a4813e33a3f23f1f228487a1fbe"
|
||||
checksum = "c6a1fa7a3c4f26cea3858f9def2ff8c06d014cb9c0c3761847fac9db48f88fe7"
|
||||
dependencies = [
|
||||
"phf",
|
||||
"swc_atoms",
|
||||
|
@ -2126,9 +2151,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_lints"
|
||||
version = "0.29.0"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be74227a2b1d2bb0f6060ed905c7dc1b298cba279dc99c7ad5e7886f5bff144"
|
||||
checksum = "5af16f1f01c10ef7793546a7e414ad2e89f479192eeea3ceb8c6b649f8f47dde"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"auto_impl",
|
||||
|
@ -2167,9 +2192,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_minifier"
|
||||
version = "0.97.2"
|
||||
version = "0.100.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f8e7de2647680236508cf7ea06fdfcdf5a9c4632a9fd5a5d99764818a77188d"
|
||||
checksum = "3351240509020dcfec0442907fff87c7023dd2ff4bf42aefec01a7e38d58babf"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"indexmap",
|
||||
|
@ -2198,9 +2223,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_parser"
|
||||
version = "0.98.1"
|
||||
version = "0.100.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e45b91e7d45fca94d60e31493475647ef7be6173e56d34aacdce3579dbd8c315"
|
||||
checksum = "890d967031e3e7330cd7892f27d826b7b4f37c7caa19db85c78a0862e1fe3974"
|
||||
dependencies = [
|
||||
"either",
|
||||
"enum_kind",
|
||||
|
@ -2218,9 +2243,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_preset_env"
|
||||
version = "0.114.0"
|
||||
version = "0.117.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc23914b7af5f5087e8888e82a2a1835386305a5cfe0252e5fb743c0c994d567"
|
||||
checksum = "77a37c95c8e7e47a1fd6bf09ff2744fe55570235e8aba2c9373200213ec2ce25"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
|
@ -2243,9 +2268,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.139.0"
|
||||
version = "0.142.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbf12cb1884d8feaad7fbeb7f3196d3a3d30df8179eadd8b1785ac0471da261"
|
||||
checksum = "f20e5e2d8ab843fa0454e049f73f6d99c444a8c0e2320f77028361ab75e2d18e"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -2263,9 +2288,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_base"
|
||||
version = "0.73.0"
|
||||
version = "0.75.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98801b04bdcdd9a4870847416f07fc7c5fd0d1c9d3cfe90afa50062562d22bfa"
|
||||
checksum = "404c6ea7ca61ceb2ce1f4ed448d1436a38c31b8c572850f04541c0229c966bbf"
|
||||
dependencies = [
|
||||
"better_scoped_tls",
|
||||
"once_cell",
|
||||
|
@ -2284,9 +2309,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_classes"
|
||||
version = "0.61.0"
|
||||
version = "0.63.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27e3c8d1a0b800da20a831cc920d9a91fba1f369af547195f1869bc8354990d3"
|
||||
checksum = "503f2f6bd0f9e6363a93406753bf64675163423774256a267c85a5d9b5b44b08"
|
||||
dependencies = [
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
|
@ -2298,12 +2323,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_compat"
|
||||
version = "0.86.2"
|
||||
version = "0.89.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d32c7565f1c220c99fc3c713ac09e172590cd89a9e3c5052141e51ad6ac8548b"
|
||||
checksum = "1d234c84cee8aeeda2ec60087f65acd420e2475bb334a64bbf988b538c21b31d"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"arrayvec 0.7.2",
|
||||
"arrayvec",
|
||||
"indexmap",
|
||||
"is-macro",
|
||||
"num-bigint",
|
||||
|
@ -2337,9 +2362,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_module"
|
||||
version = "0.99.0"
|
||||
version = "0.102.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d185c341ff825c91b10cdb755bb04b4b1afc172a0d49c82e34456bef11a2b28"
|
||||
checksum = "6c340a0228a9a49240d97a4a4e99a0a61e6613b29b427cc09a60f6ad4dcbf728"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"ahash",
|
||||
|
@ -2361,9 +2386,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_optimization"
|
||||
version = "0.109.1"
|
||||
version = "0.112.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bee3cd507ce6a037d97cb4002577aed4889172b20410f6c75aac60322dfff8fa"
|
||||
checksum = "a4d892a269f4fd26f37967fd8e98d841b379c1f66f2381c84b71f986792562fb"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"dashmap 5.1.0",
|
||||
|
@ -2384,9 +2409,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_proposal"
|
||||
version = "0.94.0"
|
||||
version = "0.97.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2f9247a4cec018ea30c5c877babaefff255d1187f4c23b4663af2a0a6ef5948"
|
||||
checksum = "93d08411e517736b0167f3c9784fe9b98cc09308ae12e6072abd2bb2c2236da2"
|
||||
dependencies = [
|
||||
"either",
|
||||
"serde",
|
||||
|
@ -2403,9 +2428,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_react"
|
||||
version = "0.101.0"
|
||||
version = "0.104.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4ebd2bbd902ad2e490cf89441231942e3e42cb2f5ffd7b2f982f6b813ea2d8"
|
||||
checksum = "43cda44270dfcc95d61582981baddaf53d96c5233ea7384e81cd6e462816c58e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"base64 0.13.0",
|
||||
|
@ -2428,9 +2453,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_testing"
|
||||
version = "0.75.0"
|
||||
version = "0.77.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e088c1f7504ce44f35d933fbaba92c6da1421f29a6609256e17c1e56627b52ab"
|
||||
checksum = "4388e2875202996bcd4bbbf3513369a94bf2135d55140fd0ae6c9e90fa3d0fec"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
|
@ -2451,9 +2476,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_transforms_typescript"
|
||||
version = "0.104.0"
|
||||
version = "0.107.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82fa00fa362f8346c8d7ed4a464972f43471d56d6ad418efa3fca584d842fb79"
|
||||
checksum = "a09397169ed7ce0751a82cb71655f3a4a1fb00d8863aabd5cca9b46eff3dd5f2"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"swc_atoms",
|
||||
|
@ -2467,9 +2492,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_utils"
|
||||
version = "0.77.0"
|
||||
version = "0.79.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e7128690ddd0f56f79572dabb973f0b237e503e23d6dbcc2fe111dc0690202"
|
||||
checksum = "44ee8d60b9977f58214af7102dc30855a6754e742afe6d6e26e5bf13883c7b91"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
|
@ -2483,9 +2508,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecma_visit"
|
||||
version = "0.59.0"
|
||||
version = "0.61.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2348e0ce526f12e74c0b700f8fec234893386bb1afe1b8c3f46ad10aad22442f"
|
||||
checksum = "b5ea00a52ba2b971955c62275696d5c59f3cf0cd06db74a66dec378ec9843c78"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"swc_atoms",
|
||||
|
@ -2497,9 +2522,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_ecmascript"
|
||||
version = "0.140.0"
|
||||
version = "0.143.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "492ee96c31b4260e32485ae638820397bb103745d04533877ce193818ccc53f9"
|
||||
checksum = "ebda93aa6422956c184a9eb5fdb0f0f0ff433169fa15e55ef445e5ad0b5e0abe"
|
||||
dependencies = [
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_codegen",
|
||||
|
@ -2510,6 +2535,25 @@ dependencies = [
|
|||
"swc_ecma_visit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_emotion"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"byteorder",
|
||||
"fxhash",
|
||||
"once_cell",
|
||||
"radix_fmt",
|
||||
"regex",
|
||||
"serde",
|
||||
"sourcemap",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_ecma_transforms_testing",
|
||||
"swc_ecmascript",
|
||||
"testing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "swc_eq_ignore_macros"
|
||||
version = "0.1.0"
|
||||
|
@ -2559,9 +2603,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_macros_common"
|
||||
version = "0.3.3"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08ed2e930f5a1a4071fe62c90fd3a296f6030e5d94bfe13993244423caf59a78"
|
||||
checksum = "033f8b6e2fc4991a8e422a20b4f52741affcac2267c29357c931508a1a500797"
|
||||
dependencies = [
|
||||
"pmutil",
|
||||
"proc-macro2",
|
||||
|
@ -2571,9 +2615,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "swc_node_base"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d32ab9aa6f4abcc9a96c2c2559444919658f1c395965468a205ecff5e5f5a020"
|
||||
checksum = "0efb0cc6b36a0eef28e60dd677eceb343b336fb5c425f6f7abec640f8c230293"
|
||||
dependencies = [
|
||||
"mimalloc-rust",
|
||||
]
|
||||
|
@ -2802,9 +2846,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.23"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c"
|
||||
checksum = "90442985ee2f57c9e1b548ee72ae842f4a9a20e3f417cc38dbc5dc684d9bb4ee"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"valuable",
|
||||
|
@ -2823,9 +2867,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.9"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e0ab7bdc962035a87fba73f3acca9b8a8d0034c2e6f60b84aeaaddddc155dce"
|
||||
checksum = "b9df98b037d039d03400d9dd06b0f8ce05486b5f25e9a2d7d36196e142ebbc52"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"lazy_static",
|
||||
|
|
|
@ -2,37 +2,35 @@
|
|||
edition = "2018"
|
||||
name = "next-swc"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13"
|
||||
byteorder = "1"
|
||||
chrono = "0.4"
|
||||
easy-error = "1.0.0"
|
||||
either = "1"
|
||||
fxhash = "0.2.1"
|
||||
once_cell = "1.8.0"
|
||||
pathdiff = "0.2.0"
|
||||
radix_fmt = "1"
|
||||
regex = "1.5"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
styled_components = "0.23.0"
|
||||
swc = "0.161.1"
|
||||
swc_emotion = {path="../emotion"}
|
||||
styled_components = {path="../styled_components"}
|
||||
styled_jsx = {path="../styled_jsx"}
|
||||
modularize_imports = {path="../modularize_imports"}
|
||||
swc = "0.164.0"
|
||||
swc_atoms = "0.2.11"
|
||||
swc_common = { version = "0.17.18", features = ["concurrent", "sourcemap"] }
|
||||
swc_css = "0.103.0"
|
||||
swc_common = { version = "0.17.19", features = ["concurrent", "sourcemap"] }
|
||||
swc_ecma_loader = { version = "0.29.0", features = ["node", "lru"] }
|
||||
swc_ecmascript = { version = "0.140.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] }
|
||||
swc_node_base = "0.5.1"
|
||||
swc_ecmascript = { version = "0.143.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] }
|
||||
swc_cached = "0.1.1"
|
||||
swc_css_prefixer = "0.99.3"
|
||||
tracing = {version = "0.1.28", features = ["release_max_level_off"]}
|
||||
handlebars = "4.2.1"
|
||||
tracing = { version = "0.1.32", features = ["release_max_level_off"] }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
swc_ecma_transforms_testing = "0.75.0"
|
||||
swc_ecma_transforms_testing = "0.77.0"
|
||||
testing = "0.19.1"
|
||||
walkdir = "2.3.2"
|
||||
|
|
|
@ -104,6 +104,7 @@ fn get_object_pattern(array_pattern: &ArrayPat) -> Pat {
|
|||
key: PropName::Num(Number {
|
||||
value: i as f64,
|
||||
span: DUMMY_SP,
|
||||
raw: None,
|
||||
}),
|
||||
value: Box::new(elem.clone()),
|
||||
})
|
||||
|
|
|
@ -48,9 +48,7 @@ use swc_ecmascript::visit::Fold;
|
|||
pub mod amp_attributes;
|
||||
mod auto_cjs;
|
||||
pub mod disallow_re_export_all_in_page;
|
||||
pub mod emotion;
|
||||
pub mod hook_optimizer;
|
||||
pub mod modularize_imports;
|
||||
pub mod next_dynamic;
|
||||
pub mod next_ssg;
|
||||
pub mod page_config;
|
||||
|
@ -59,7 +57,6 @@ pub mod react_remove_properties;
|
|||
pub mod relay;
|
||||
pub mod remove_console;
|
||||
pub mod shake_exports;
|
||||
pub mod styled_jsx;
|
||||
mod top_level_binding_collector;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
@ -103,7 +100,7 @@ pub struct TransformOptions {
|
|||
pub shake_exports: Option<shake_exports::Config>,
|
||||
|
||||
#[serde(default)]
|
||||
pub emotion: Option<emotion::EmotionOptions>,
|
||||
pub emotion: Option<swc_emotion::EmotionOptions>,
|
||||
|
||||
#[serde(default)]
|
||||
pub modularize_imports: Option<modularize_imports::Config>,
|
||||
|
@ -188,7 +185,7 @@ pub fn custom_before_pass<'a, C: Comments + 'a>(
|
|||
}
|
||||
if let FileName::Real(path) = &file.name {
|
||||
path.to_str().map(|_| {
|
||||
Either::Left(emotion::EmotionTransformer::new(
|
||||
Either::Left(swc_emotion::EmotionTransformer::new(
|
||||
config.clone(),
|
||||
path,
|
||||
cm,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use next_swc::{
|
||||
disallow_re_export_all_in_page::disallow_re_export_all_in_page, next_dynamic::next_dynamic,
|
||||
next_ssg::next_ssg, styled_jsx::styled_jsx,
|
||||
next_ssg::next_ssg,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
use swc_common::FileName;
|
||||
|
@ -44,22 +44,6 @@ fn next_dynamic_errors(input: PathBuf) {
|
|||
);
|
||||
}
|
||||
|
||||
#[fixture("tests/errors/styled-jsx/**/input.js")]
|
||||
fn styled_jsx_errors(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.js");
|
||||
let file_name = match input.to_str().unwrap().contains("ts-with-css-resolve") {
|
||||
true => FileName::Real(PathBuf::from("/some-project/src/some-file.ts")),
|
||||
false => FileName::Real(PathBuf::from("/some-project/src/some-file.js")),
|
||||
};
|
||||
|
||||
test_fixture_allowing_error(
|
||||
syntax(),
|
||||
&|t| styled_jsx(t.cm.clone(), file_name.clone()),
|
||||
&input,
|
||||
&output,
|
||||
);
|
||||
}
|
||||
|
||||
#[fixture("tests/errors/next-ssg/**/input.js")]
|
||||
fn next_ssg_errors(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.js");
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use next_swc::{
|
||||
amp_attributes::amp_attributes,
|
||||
emotion::{self, EmotionOptions},
|
||||
modularize_imports::modularize_imports,
|
||||
next_dynamic::next_dynamic,
|
||||
next_ssg::next_ssg,
|
||||
page_config::page_config_test,
|
||||
|
@ -9,17 +7,13 @@ use next_swc::{
|
|||
relay::{relay, Config as RelayConfig, RelayLanguageConfig},
|
||||
remove_console::remove_console,
|
||||
shake_exports::{shake_exports, Config as ShakeExportsConfig},
|
||||
styled_jsx::styled_jsx,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
use swc_common::{chain, comments::SingleThreadedComments, FileName, Mark, Span, DUMMY_SP};
|
||||
use swc_common::{chain, comments::SingleThreadedComments, FileName, Mark};
|
||||
use swc_ecma_transforms_testing::{test, test_fixture};
|
||||
use swc_ecmascript::{
|
||||
parser::{EsConfig, Syntax, TsConfig},
|
||||
transforms::{
|
||||
react::{jsx, Runtime},
|
||||
resolver,
|
||||
},
|
||||
parser::{EsConfig, Syntax},
|
||||
transforms::react::jsx,
|
||||
};
|
||||
use testing::fixture;
|
||||
|
||||
|
@ -30,13 +24,6 @@ fn syntax() -> Syntax {
|
|||
})
|
||||
}
|
||||
|
||||
fn ts_syntax() -> Syntax {
|
||||
Syntax::Typescript(TsConfig {
|
||||
tsx: true,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
#[fixture("tests/fixture/amp/**/input.js")]
|
||||
fn amp_attributes_fixture(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.js");
|
||||
|
@ -120,56 +107,6 @@ fn next_ssg_fixture(input: PathBuf) {
|
|||
);
|
||||
}
|
||||
|
||||
#[fixture("tests/fixture/styled-jsx/**/input.js")]
|
||||
fn styled_jsx_fixture(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.js");
|
||||
test_fixture(
|
||||
syntax(),
|
||||
&|t| {
|
||||
chain!(
|
||||
resolver(),
|
||||
styled_jsx(
|
||||
t.cm.clone(),
|
||||
FileName::Real(PathBuf::from("/some-project/src/some-file.js"))
|
||||
)
|
||||
)
|
||||
},
|
||||
&input,
|
||||
&output,
|
||||
);
|
||||
|
||||
test_fixture(
|
||||
syntax(),
|
||||
&|t| {
|
||||
// `resolver` uses `Mark` which is stored in a thread-local storage (namely
|
||||
// swc_common::GLOBALS), and this loop will make `Mark` to be different from the
|
||||
// invocation above.
|
||||
//
|
||||
// 1000 is used because in future I (kdy1) may optimize logic of resolver.
|
||||
for _ in 0..1000 {
|
||||
let _mark = Mark::fresh(Mark::root());
|
||||
}
|
||||
|
||||
chain!(
|
||||
resolver(),
|
||||
styled_jsx(
|
||||
t.cm.clone(),
|
||||
FileName::Real(PathBuf::from("/some-project/src/some-file.js"))
|
||||
)
|
||||
)
|
||||
},
|
||||
&input,
|
||||
&output,
|
||||
);
|
||||
}
|
||||
|
||||
pub struct DropSpan;
|
||||
impl swc_ecmascript::visit::VisitMut for DropSpan {
|
||||
fn visit_mut_span(&mut self, span: &mut Span) {
|
||||
*span = DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
#[fixture("tests/fixture/page-config/**/input.js")]
|
||||
fn page_config_fixture(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.js");
|
||||
|
@ -272,87 +209,3 @@ fn shake_exports_fixture_default(input: PathBuf) {
|
|||
&output,
|
||||
);
|
||||
}
|
||||
|
||||
#[fixture("tests/fixture/emotion/*/input.tsx")]
|
||||
fn next_emotion_fixture(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.ts");
|
||||
test_fixture(
|
||||
ts_syntax(),
|
||||
&|tr| {
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let jsx = jsx::<SingleThreadedComments>(
|
||||
tr.cm.clone(),
|
||||
Some(tr.comments.as_ref().clone()),
|
||||
swc_ecmascript::transforms::react::Options {
|
||||
next: false,
|
||||
runtime: Some(Runtime::Automatic),
|
||||
throw_if_namespace: false,
|
||||
development: false,
|
||||
use_builtins: true,
|
||||
use_spread: true,
|
||||
..Default::default()
|
||||
},
|
||||
top_level_mark,
|
||||
);
|
||||
chain!(
|
||||
emotion::emotion(
|
||||
EmotionOptions {
|
||||
enabled: Some(true),
|
||||
sourcemap: Some(true),
|
||||
auto_label: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
&PathBuf::from("input.ts"),
|
||||
tr.cm.clone(),
|
||||
tr.comments.as_ref().clone(),
|
||||
),
|
||||
jsx
|
||||
)
|
||||
},
|
||||
&input,
|
||||
&output,
|
||||
);
|
||||
}
|
||||
|
||||
#[fixture("tests/fixture/modularize-imports/**/input.js")]
|
||||
fn modularize_imports_fixture(input: PathBuf) {
|
||||
use next_swc::modularize_imports::PackageConfig;
|
||||
let output = input.parent().unwrap().join("output.js");
|
||||
test_fixture(
|
||||
syntax(),
|
||||
&|_tr| {
|
||||
modularize_imports(next_swc::modularize_imports::Config {
|
||||
packages: vec![
|
||||
(
|
||||
"react-bootstrap".to_string(),
|
||||
PackageConfig {
|
||||
transform: "react-bootstrap/lib/{{member}}".into(),
|
||||
prevent_full_import: false,
|
||||
skip_default_conversion: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
"my-library/?(((\\w*)?/?)*)".to_string(),
|
||||
PackageConfig {
|
||||
transform: "my-library/{{ matches.[1] }}/{{member}}".into(),
|
||||
prevent_full_import: false,
|
||||
skip_default_conversion: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
"my-library-2".to_string(),
|
||||
PackageConfig {
|
||||
transform: "my-library-2/{{ camelCase member }}".into(),
|
||||
prevent_full_import: false,
|
||||
skip_default_conversion: true,
|
||||
},
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
})
|
||||
},
|
||||
&input,
|
||||
&output,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ fn test(input: &Path, minify: bool) {
|
|||
swc: swc::config::Options {
|
||||
swcrc: true,
|
||||
is_module: swc::config::IsModule::Bool(true),
|
||||
output_path: Some(output.to_path_buf()),
|
||||
output_path: Some(output.clone()),
|
||||
|
||||
config: swc::config::Config {
|
||||
jsc: swc::config::JscConfig {
|
||||
|
|
27
packages/next-swc/crates/emotion/Cargo.toml
Normal file
27
packages/next-swc/crates/emotion/Cargo.toml
Normal file
|
@ -0,0 +1,27 @@
|
|||
[package]
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
edition = "2018"
|
||||
description = "AST Transforms for emotion"
|
||||
license = "Apache-2.0"
|
||||
name = "swc_emotion"
|
||||
repository = "https://github.com/vercel/next.js.git"
|
||||
version = "0.2.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13"
|
||||
byteorder = "1"
|
||||
fxhash = "0.2.1"
|
||||
once_cell = "1.8.0"
|
||||
radix_fmt = "1"
|
||||
regex = "1.5"
|
||||
serde = "1"
|
||||
sourcemap = "6.0.1"
|
||||
swc_atoms = "0.2.11"
|
||||
swc_common = { version = "0.17.19", features = ["concurrent", "sourcemap"] }
|
||||
swc_ecmascript = { version = "0.143.0", features = ["codegen", "utils", "visit"] }
|
||||
|
||||
[dev-dependencies]
|
||||
swc_ecma_transforms_testing = "0.77.0"
|
||||
testing = "0.19.1"
|
|
@ -46,8 +46,8 @@ mod test {
|
|||
let s2 = "abcdeg";
|
||||
for i in 0..5 {
|
||||
assert_eq!(
|
||||
murmurhash2(&s1[i..5].as_bytes(), 0),
|
||||
murmurhash2(&s2[i..5].as_bytes(), 0)
|
||||
murmurhash2(s1[i..5].as_bytes(), 0),
|
||||
murmurhash2(s2[i..5].as_bytes(), 0)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -6,14 +6,14 @@ use fxhash::FxHashMap;
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use swc::sourcemap::{RawToken, SourceMap as RawSourcemap};
|
||||
use sourcemap::{RawToken, SourceMap as RawSourcemap};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::comments::Comments;
|
||||
use swc_common::util::take::Take;
|
||||
use swc_common::{BytePos, SourceMap, DUMMY_SP};
|
||||
use swc_ecmascript::ast::{
|
||||
ArrayLit, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElementName, JSXExpr,
|
||||
JSXExprContainer, JSXObject,
|
||||
ArrayLit, CallExpr, JSXAttr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElementName,
|
||||
JSXExpr, JSXExprContainer, JSXObject,
|
||||
};
|
||||
use swc_ecmascript::utils::ident::IdentLike;
|
||||
use swc_ecmascript::utils::{ExprFactory, Id};
|
||||
|
@ -23,7 +23,7 @@ use swc_ecmascript::{
|
|||
MemberProp, ObjectLit, Pat, Prop, PropName, PropOrSpread, Tpl, VarDeclarator,
|
||||
},
|
||||
codegen::util::SourceMapperExt,
|
||||
visit::{swc_ecma_ast::CallExpr, Fold, FoldWith},
|
||||
visit::{Fold, FoldWith},
|
||||
};
|
||||
|
||||
mod hash;
|
58
packages/next-swc/crates/emotion/tests/fixture.rs
Normal file
58
packages/next-swc/crates/emotion/tests/fixture.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use swc_common::{chain, comments::SingleThreadedComments, Mark};
|
||||
use swc_ecma_transforms_testing::test_fixture;
|
||||
use swc_ecmascript::{
|
||||
parser::{Syntax, TsConfig},
|
||||
transforms::react::{jsx, Runtime},
|
||||
};
|
||||
use swc_emotion::EmotionOptions;
|
||||
use testing::fixture;
|
||||
|
||||
fn ts_syntax() -> Syntax {
|
||||
Syntax::Typescript(TsConfig {
|
||||
tsx: true,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
#[fixture("tests/fixture/*/input.tsx")]
|
||||
fn next_emotion_fixture(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.ts");
|
||||
test_fixture(
|
||||
ts_syntax(),
|
||||
&|tr| {
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
let jsx = jsx::<SingleThreadedComments>(
|
||||
tr.cm.clone(),
|
||||
Some(tr.comments.as_ref().clone()),
|
||||
swc_ecmascript::transforms::react::Options {
|
||||
next: false,
|
||||
runtime: Some(Runtime::Automatic),
|
||||
throw_if_namespace: false,
|
||||
development: false,
|
||||
use_builtins: true,
|
||||
use_spread: true,
|
||||
..Default::default()
|
||||
},
|
||||
top_level_mark,
|
||||
);
|
||||
chain!(
|
||||
swc_emotion::emotion(
|
||||
EmotionOptions {
|
||||
enabled: Some(true),
|
||||
sourcemap: Some(true),
|
||||
auto_label: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
&PathBuf::from("input.ts"),
|
||||
tr.cm.clone(),
|
||||
tr.comments.as_ref().clone(),
|
||||
),
|
||||
jsx
|
||||
)
|
||||
},
|
||||
&input,
|
||||
&output,
|
||||
);
|
||||
}
|
22
packages/next-swc/crates/modularize_imports/Cargo.toml
Normal file
22
packages/next-swc/crates/modularize_imports/Cargo.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "AST Transforms for import modularizer"
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
name = "modularize_imports"
|
||||
repository = "https://github.com/vercel/next.js.git"
|
||||
version = "0.1.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
handlebars = "4.2.1"
|
||||
once_cell = "1.8.0"
|
||||
regex = "1.5"
|
||||
serde = "1"
|
||||
swc_cached = "0.1.1"
|
||||
swc_ecmascript = {version = "0.143.0", features = ["visit"]}
|
||||
|
||||
[dev-dependencies]
|
||||
swc_ecma_transforms_testing = "0.77.0"
|
||||
testing = "0.19.1"
|
55
packages/next-swc/crates/modularize_imports/tests/fixture.rs
Normal file
55
packages/next-swc/crates/modularize_imports/tests/fixture.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use modularize_imports::{modularize_imports, PackageConfig};
|
||||
use swc_ecma_transforms_testing::test_fixture;
|
||||
use swc_ecmascript::parser::{EsConfig, Syntax};
|
||||
use testing::fixture;
|
||||
|
||||
fn syntax() -> Syntax {
|
||||
Syntax::Es(EsConfig {
|
||||
jsx: true,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
#[fixture("tests/fixture/**/input.js")]
|
||||
fn modularize_imports_fixture(input: PathBuf) {
|
||||
let output = input.parent().unwrap().join("output.js");
|
||||
test_fixture(
|
||||
syntax(),
|
||||
&|_tr| {
|
||||
modularize_imports(modularize_imports::Config {
|
||||
packages: vec![
|
||||
(
|
||||
"react-bootstrap".to_string(),
|
||||
PackageConfig {
|
||||
transform: "react-bootstrap/lib/{{member}}".into(),
|
||||
prevent_full_import: false,
|
||||
skip_default_conversion: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
"my-library/?(((\\w*)?/?)*)".to_string(),
|
||||
PackageConfig {
|
||||
transform: "my-library/{{ matches.[1] }}/{{member}}".into(),
|
||||
prevent_full_import: false,
|
||||
skip_default_conversion: false,
|
||||
},
|
||||
),
|
||||
(
|
||||
"my-library-2".to_string(),
|
||||
PackageConfig {
|
||||
transform: "my-library-2/{{ camelCase member }}".into(),
|
||||
prevent_full_import: false,
|
||||
skip_default_conversion: true,
|
||||
},
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
})
|
||||
},
|
||||
&input,
|
||||
&output,
|
||||
);
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
edition = "2018"
|
||||
name = "next-swc-napi"
|
||||
version = "0.0.0"
|
||||
publish = false
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
@ -16,13 +17,13 @@ next-swc = {version = "0.0.0", path = "../core"}
|
|||
once_cell = "1.8.0"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
swc = "0.161.1"
|
||||
swc = "0.164.0"
|
||||
swc_atoms = "0.2.11"
|
||||
swc_bundler = { version = "0.130.0", features = ["concurrent"] }
|
||||
swc_common = { version = "0.17.18", features = ["concurrent", "sourcemap"] }
|
||||
swc_bundler = { version = "0.133.0", features = ["concurrent"] }
|
||||
swc_common = { version = "0.17.19", features = ["concurrent", "sourcemap"] }
|
||||
swc_ecma_loader = { version = "0.29.0", features = ["node", "lru"] }
|
||||
swc_ecmascript = { version = "0.140.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] }
|
||||
swc_node_base = "0.5.1"
|
||||
swc_ecmascript = { version = "0.143.0", features = ["codegen", "minifier", "optimization", "parser", "react", "transforms", "typescript", "utils", "visit"] }
|
||||
swc_node_base = "0.5.2"
|
||||
|
||||
[build-dependencies]
|
||||
napi-build = "1"
|
||||
|
|
|
@ -251,7 +251,7 @@ pub fn transform_sync(cx: CallContext) -> napi::Result<JsObject> {
|
|||
fn test_deser() {
|
||||
const JSON_STR: &str = r#"{"jsc":{"parser":{"syntax":"ecmascript","dynamicImport":true,"jsx":true},"transform":{"react":{"runtime":"automatic","pragma":"React.createElement","pragmaFrag":"React.Fragment","throwIfNamespace":true,"development":false,"useBuiltins":true}},"target":"es5"},"filename":"/Users/timneutkens/projects/next.js/packages/next/dist/client/next.js","sourceMaps":false,"sourceFileName":"/Users/timneutkens/projects/next.js/packages/next/dist/client/next.js"}"#;
|
||||
|
||||
let tr: TransformOptions = serde_json::from_str(&JSON_STR).unwrap();
|
||||
let tr: TransformOptions = serde_json::from_str(JSON_STR).unwrap();
|
||||
|
||||
println!("{:#?}", tr);
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ fn test_deser() {
|
|||
fn test_deserialize_transform_regenerator() {
|
||||
const JSON_STR: &str = r#"{"jsc":{"parser":{"syntax":"ecmascript","dynamicImport":true,"jsx":true},"transform":{ "regenerator": { "importPath": "foo" }, "react":{"runtime":"automatic","pragma":"React.createElement","pragmaFrag":"React.Fragment","throwIfNamespace":true,"development":false,"useBuiltins":true}},"target":"es5"},"filename":"/Users/timneutkens/projects/next.js/packages/next/dist/client/next.js","sourceMaps":false,"sourceFileName":"/Users/timneutkens/projects/next.js/packages/next/dist/client/next.js"}"#;
|
||||
|
||||
let tr: TransformOptions = serde_json::from_str(&JSON_STR).unwrap();
|
||||
let tr: TransformOptions = serde_json::from_str(JSON_STR).unwrap();
|
||||
|
||||
println!("{:#?}", tr);
|
||||
}
|
||||
|
|
26
packages/next-swc/crates/styled_components/Cargo.toml
Normal file
26
packages/next-swc/crates/styled_components/Cargo.toml
Normal file
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "AST Transforms for styled-components"
|
||||
edition = "2018"
|
||||
license = "Apache-2.0"
|
||||
name = "styled_components"
|
||||
repository = "https://github.com/vercel/next.js.git"
|
||||
version = "0.26.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
Inflector = "0.11.4"
|
||||
once_cell = "1.10.0"
|
||||
regex = {version = "1.5.4", features = ["std", "perf"], default-features = false}
|
||||
serde = {version = "1.0.130", features = ["derive"]}
|
||||
swc_atoms = "0.2.11"
|
||||
swc_common = { version = "0.17.19", features = ["concurrent"] }
|
||||
swc_ecmascript = { version = "0.143.0", features = ["utils", "visit"] }
|
||||
tracing = "0.1.32"
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1"
|
||||
swc_ecma_transforms_testing = "0.77.0"
|
||||
swc_ecmascript = { version = "0.143.0", features = ["parser", "transforms"] }
|
||||
testing = "0.19.1"
|
1
packages/next-swc/crates/styled_components/src/css.rs
Normal file
1
packages/next-swc/crates/styled_components/src/css.rs
Normal file
|
@ -0,0 +1 @@
|
|||
|
70
packages/next-swc/crates/styled_components/src/lib.rs
Normal file
70
packages/next-swc/crates/styled_components/src/lib.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
pub use crate::{
|
||||
utils::{analyze, analyzer, State},
|
||||
visitors::{
|
||||
display_name_and_id::display_name_and_id, transpile_css_prop::transpile::transpile_css_prop,
|
||||
},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{chain, SourceFile};
|
||||
use swc_ecmascript::visit::{Fold, VisitMut};
|
||||
|
||||
mod css;
|
||||
mod utils;
|
||||
mod visitors;
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct Config {
|
||||
#[serde(default = "true_by_default")]
|
||||
pub display_name: bool,
|
||||
|
||||
#[serde(default = "true_by_default")]
|
||||
pub ssr: bool,
|
||||
|
||||
#[serde(default = "true_by_default")]
|
||||
pub file_name: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub namespace: String,
|
||||
|
||||
#[serde(default)]
|
||||
pub top_level_import_paths: Vec<JsWord>,
|
||||
|
||||
#[serde(default)]
|
||||
pub transpile_template_literals: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub minify: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub css_prop: bool,
|
||||
}
|
||||
|
||||
fn true_by_default() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub(crate) fn use_namespace(&self) -> String {
|
||||
if self.namespace.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
format!("{}__", self.namespace)
|
||||
}
|
||||
}
|
||||
|
||||
/// NOTE: **This is not complete**.
|
||||
///
|
||||
/// Only [analyzer] and [display_name_and_id] is implemented.
|
||||
pub fn styled_components(file: Arc<SourceFile>, config: Config) -> impl Fold + VisitMut {
|
||||
let state: Rc<RefCell<State>> = Default::default();
|
||||
let config = Rc::new(config);
|
||||
|
||||
chain!(
|
||||
analyzer(config.clone(), state.clone()),
|
||||
display_name_and_id(file, config, state),
|
||||
transpile_css_prop()
|
||||
)
|
||||
}
|
129
packages/next-swc/crates/styled_components/src/utils/analyzer.rs
Normal file
129
packages/next-swc/crates/styled_components/src/utils/analyzer.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
use super::State;
|
||||
use crate::Config;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use swc_ecmascript::{
|
||||
ast::*,
|
||||
utils::{ident::IdentLike, ExprExt},
|
||||
visit::{as_folder, noop_visit_mut_type, noop_visit_type, Fold, Visit, VisitMut, VisitWith},
|
||||
};
|
||||
|
||||
pub fn analyzer(config: Rc<Config>, state: Rc<RefCell<State>>) -> impl VisitMut + Fold {
|
||||
as_folder(AsAnalyzer { config, state })
|
||||
}
|
||||
|
||||
struct AsAnalyzer {
|
||||
config: Rc<Config>,
|
||||
state: Rc<RefCell<State>>,
|
||||
}
|
||||
|
||||
impl VisitMut for AsAnalyzer {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module(&mut self, p: &mut Module) {
|
||||
let mut v = Analyzer {
|
||||
config: &self.config,
|
||||
state: &mut *self.state.borrow_mut(),
|
||||
};
|
||||
|
||||
p.visit_with(&mut v);
|
||||
}
|
||||
|
||||
fn visit_mut_script(&mut self, p: &mut Script) {
|
||||
let mut v = Analyzer {
|
||||
config: &self.config,
|
||||
state: &mut *self.state.borrow_mut(),
|
||||
};
|
||||
|
||||
p.visit_with(&mut v);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn analyze(config: &Config, program: &Program) -> State {
|
||||
let mut state = State::default();
|
||||
|
||||
let mut v = Analyzer {
|
||||
config,
|
||||
state: &mut state,
|
||||
};
|
||||
|
||||
program.visit_with(&mut v);
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
struct Analyzer<'a> {
|
||||
config: &'a Config,
|
||||
state: &'a mut State,
|
||||
}
|
||||
|
||||
impl Visit for Analyzer<'_> {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_var_declarator(&mut self, v: &VarDeclarator) {
|
||||
v.visit_children_with(self);
|
||||
|
||||
if let Pat::Ident(name) = &v.name {
|
||||
if let Some(Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
args,
|
||||
..
|
||||
})) = v.init.as_deref()
|
||||
{
|
||||
if callee.is_ident_ref_to("require".into())
|
||||
&& args.len() == 1
|
||||
&& args[0].spread.is_none()
|
||||
{
|
||||
if let Expr::Lit(Lit::Str(v)) = &*args[0].expr {
|
||||
let is_styled = if self.config.top_level_import_paths.is_empty() {
|
||||
&*v.value == "styled-components"
|
||||
|| v.value.starts_with("styled-components/")
|
||||
} else {
|
||||
self.config.top_level_import_paths.contains(&v.value)
|
||||
};
|
||||
|
||||
if is_styled {
|
||||
self.state.styled_required = Some(name.id.to_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_import_decl(&mut self, i: &ImportDecl) {
|
||||
let is_custom = !self.config.top_level_import_paths.is_empty();
|
||||
|
||||
let is_styled = if self.config.top_level_import_paths.is_empty() {
|
||||
&*i.src.value == "styled-components" || i.src.value.starts_with("styled-components/")
|
||||
} else {
|
||||
self.config.top_level_import_paths.contains(&i.src.value)
|
||||
};
|
||||
|
||||
if is_styled {
|
||||
for s in &i.specifiers {
|
||||
match s {
|
||||
ImportSpecifier::Named(s) => {
|
||||
if is_custom
|
||||
&& s.imported
|
||||
.as_ref()
|
||||
.map(|v| match v {
|
||||
ModuleExportName::Ident(v) => &*v.sym,
|
||||
ModuleExportName::Str(v) => &*v.value,
|
||||
})
|
||||
.unwrap_or(&*s.local.sym)
|
||||
== "styled"
|
||||
{
|
||||
self.state.imported_local_name = Some(s.local.to_id());
|
||||
}
|
||||
}
|
||||
ImportSpecifier::Default(s) => {
|
||||
self.state.imported_local_name = Some(s.local.to_id());
|
||||
}
|
||||
ImportSpecifier::Namespace(s) => {
|
||||
self.state.imported_local_ns = Some(s.local.to_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
318
packages/next-swc/crates/styled_components/src/utils/mod.rs
Normal file
318
packages/next-swc/crates/styled_components/src/utils/mod.rs
Normal file
|
@ -0,0 +1,318 @@
|
|||
pub use self::analyzer::{analyze, analyzer};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::{Captures, Regex};
|
||||
use std::{borrow::Cow, cell::RefCell};
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::collections::AHashMap;
|
||||
use swc_ecmascript::{
|
||||
ast::*,
|
||||
utils::{ident::IdentLike, Id},
|
||||
};
|
||||
|
||||
mod analyzer;
|
||||
|
||||
pub(crate) fn get_prop_key_as_expr(p: &Prop) -> Cow<Expr> {
|
||||
match p {
|
||||
Prop::Shorthand(p) => Cow::Owned(Expr::Ident(p.clone())),
|
||||
Prop::KeyValue(p) => prop_name_to_expr(&p.key),
|
||||
Prop::Assign(p) => Cow::Owned(Expr::Ident(p.key.clone())),
|
||||
Prop::Getter(p) => prop_name_to_expr(&p.key),
|
||||
Prop::Setter(p) => prop_name_to_expr(&p.key),
|
||||
Prop::Method(p) => prop_name_to_expr(&p.key),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn prop_name_to_expr(p: &PropName) -> Cow<Expr> {
|
||||
match p {
|
||||
PropName::Ident(p) => Cow::Owned(Expr::Ident(p.clone())),
|
||||
PropName::Str(p) => Cow::Owned(Expr::Lit(Lit::Str(p.clone()))),
|
||||
PropName::Num(p) => Cow::Owned(Expr::Lit(Lit::Num(p.clone()))),
|
||||
PropName::BigInt(p) => Cow::Owned(Expr::Lit(Lit::BigInt(p.clone()))),
|
||||
PropName::Computed(e) => Cow::Borrowed(&e.expr),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_prop_name(p: &Prop) -> Option<&PropName> {
|
||||
match p {
|
||||
Prop::Shorthand(..) => None,
|
||||
Prop::KeyValue(p) => Some(&p.key),
|
||||
Prop::Assign(..) => None,
|
||||
Prop::Getter(p) => Some(&p.key),
|
||||
Prop::Setter(p) => Some(&p.key),
|
||||
Prop::Method(p) => Some(&p.key),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_prop_name2(p: &Prop) -> PropName {
|
||||
match p {
|
||||
Prop::Shorthand(ident) => PropName::Ident(ident.clone()),
|
||||
Prop::KeyValue(p) => p.key.clone(),
|
||||
Prop::Assign(x) => PropName::Ident(x.key.clone()),
|
||||
Prop::Getter(p) => p.key.clone(),
|
||||
Prop::Setter(p) => p.key.clone(),
|
||||
Prop::Method(p) => p.key.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// This is created once per file.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct State {
|
||||
pub(crate) styled_required: Option<Id>,
|
||||
|
||||
imported_local_name: Option<Id>,
|
||||
/// Namespace imports
|
||||
imported_local_ns: Option<Id>,
|
||||
import_name_cache: RefCell<AHashMap<Id, Id>>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub(crate) fn is_styled(&self, tag: &Expr) -> bool {
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) = tag
|
||||
{
|
||||
if let Expr::Member(MemberExpr {
|
||||
obj,
|
||||
prop: MemberProp::Ident(prop),
|
||||
..
|
||||
}) = &**callee
|
||||
{
|
||||
if prop.sym != js_word!("default") {
|
||||
return self.is_styled(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match tag {
|
||||
Expr::Member(MemberExpr {
|
||||
obj,
|
||||
prop: MemberProp::Ident(prop),
|
||||
..
|
||||
}) => {
|
||||
if let Expr::Ident(obj) = &**obj {
|
||||
if Some(obj.to_id()) == self.import_local_name("default", Some(obj))
|
||||
&& !self.is_helper(&Expr::Ident(prop.clone()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) => {
|
||||
if let Expr::Ident(callee) = &**callee {
|
||||
if Some(callee.to_id()) == self.import_local_name("default", Some(callee)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// styled-components might be imported using a require()
|
||||
if let Some(style_required) = self.styled_required.clone() {
|
||||
match tag {
|
||||
Expr::Member(MemberExpr {
|
||||
obj,
|
||||
prop: MemberProp::Ident(..),
|
||||
..
|
||||
}) => {
|
||||
if let Expr::Member(MemberExpr {
|
||||
obj: obj_of_obj,
|
||||
prop: MemberProp::Ident(prop),
|
||||
..
|
||||
}) = &**obj
|
||||
{
|
||||
if let Expr::Ident(obj_of_obj) = &**obj_of_obj {
|
||||
if prop.sym == js_word!("default")
|
||||
&& obj_of_obj.to_id() == style_required
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) => {
|
||||
if let Expr::Member(MemberExpr {
|
||||
obj: tag_callee_object,
|
||||
prop: MemberProp::Ident(tag_callee_property),
|
||||
..
|
||||
}) = &**callee
|
||||
{
|
||||
if let Expr::Ident(tag_callee_object) = &**tag_callee_object {
|
||||
if tag_callee_property.sym == js_word!("default")
|
||||
&& tag_callee_object.to_id() == style_required
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(import_local_name) = self.import_local_name("default", None) {
|
||||
match tag {
|
||||
Expr::Member(MemberExpr {
|
||||
obj,
|
||||
prop: MemberProp::Ident(..),
|
||||
..
|
||||
}) => {
|
||||
if let Expr::Member(MemberExpr {
|
||||
obj: obj_of_obj,
|
||||
prop: MemberProp::Ident(prop),
|
||||
..
|
||||
}) = &**obj
|
||||
{
|
||||
if let Expr::Ident(obj_of_obj) = &**obj_of_obj {
|
||||
if prop.sym == js_word!("default")
|
||||
&& obj_of_obj.to_id() == import_local_name
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) => {
|
||||
if let Expr::Member(MemberExpr {
|
||||
obj: tag_callee_object,
|
||||
prop: MemberProp::Ident(tag_callee_property),
|
||||
..
|
||||
}) = &**callee
|
||||
{
|
||||
if let Expr::Ident(tag_callee_object) = &**tag_callee_object {
|
||||
if tag_callee_property.sym == js_word!("default")
|
||||
&& tag_callee_object.to_id() == import_local_name
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn import_local_name(&self, name: &str, cache_identifier: Option<&Ident>) -> Option<Id> {
|
||||
if name == "default" {
|
||||
if let Some(cached) = self.imported_local_name.clone() {
|
||||
return Some(cached);
|
||||
}
|
||||
if let Some(cached) = self.imported_local_ns.clone() {
|
||||
return Some(cached);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(..) = self.imported_local_ns {
|
||||
return Some((name.into(), Default::default()));
|
||||
}
|
||||
|
||||
let cache_key = cache_identifier.map(|i| i.to_id()).unwrap_or_default();
|
||||
|
||||
let ctxt = self
|
||||
.styled_required
|
||||
.as_ref()
|
||||
.map(|v| v.1)
|
||||
.unwrap_or_default();
|
||||
|
||||
let local_name = if self.styled_required.is_some() {
|
||||
Some(if name == "default" {
|
||||
"styled".into()
|
||||
} else {
|
||||
name.into()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(cached) = self.import_name_cache.borrow().get(&cache_key) {
|
||||
return Some(cached.clone());
|
||||
}
|
||||
|
||||
let name = local_name.map(|word| (word, ctxt));
|
||||
|
||||
if let Some(name) = name.clone() {
|
||||
self.import_name_cache.borrow_mut().insert(cache_key, name);
|
||||
}
|
||||
|
||||
name
|
||||
}
|
||||
|
||||
fn is_helper(&self, e: &Expr) -> bool {
|
||||
self.is_create_global_style_helper(e)
|
||||
|| self.is_css_helper(e)
|
||||
|| self.is_inject_global_helper(e)
|
||||
|| self.is_use_theme(e)
|
||||
|| self.is_keyframes_helper(e)
|
||||
|| self.is_with_theme_helper(e)
|
||||
}
|
||||
|
||||
fn is_css_helper(&self, e: &Expr) -> bool {
|
||||
match e {
|
||||
Expr::Ident(e) => Some(e.to_id()) == self.import_local_name("css", None),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_create_global_style_helper(&self, e: &Expr) -> bool {
|
||||
match e {
|
||||
Expr::Ident(e) => Some(e.to_id()) == self.import_local_name("createGlobalStyle", None),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_inject_global_helper(&self, e: &Expr) -> bool {
|
||||
match e {
|
||||
Expr::Ident(e) => Some(e.to_id()) == self.import_local_name("injectGlobal", None),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_keyframes_helper(&self, e: &Expr) -> bool {
|
||||
match e {
|
||||
Expr::Ident(e) => Some(e.to_id()) == self.import_local_name("keyframes", None),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_with_theme_helper(&self, e: &Expr) -> bool {
|
||||
match e {
|
||||
Expr::Ident(e) => Some(e.to_id()) == self.import_local_name("withTheme", None),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_use_theme(&self, e: &Expr) -> bool {
|
||||
match e {
|
||||
Expr::Ident(e) => Some(e.to_id()) == self.import_local_name("useTheme", None),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prefix_leading_digit(s: &str) -> Cow<str> {
|
||||
static REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(\d)").unwrap());
|
||||
|
||||
REGEX.replace(s, |s: &Captures| {
|
||||
//
|
||||
format!("sc-{}", s.get(0).unwrap().as_str())
|
||||
})
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,467 @@
|
|||
use crate::{
|
||||
utils::{get_prop_name, prefix_leading_digit, State},
|
||||
Config,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use std::{cell::RefCell, convert::TryInto, path::Path, rc::Rc, sync::Arc};
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::{util::take::Take, FileName, SourceFile, DUMMY_SP};
|
||||
use swc_ecmascript::{
|
||||
ast::*,
|
||||
utils::{quote_ident, ExprFactory},
|
||||
visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith},
|
||||
};
|
||||
use tracing::{span, trace, Level};
|
||||
|
||||
pub fn display_name_and_id(
|
||||
file: Arc<SourceFile>,
|
||||
config: Rc<Config>,
|
||||
state: Rc<RefCell<State>>,
|
||||
) -> impl Fold + VisitMut {
|
||||
as_folder(DisplayNameAndId {
|
||||
file,
|
||||
config,
|
||||
state,
|
||||
cur_display_name: Default::default(),
|
||||
component_id: 0,
|
||||
})
|
||||
}
|
||||
|
||||
static DISPLAY_NAME_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^[a-zA-Z][a-zA-Z0-9]$").unwrap());
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DisplayNameAndId {
|
||||
file: Arc<SourceFile>,
|
||||
config: Rc<Config>,
|
||||
state: Rc<RefCell<State>>,
|
||||
|
||||
cur_display_name: Option<JsWord>,
|
||||
|
||||
component_id: usize,
|
||||
}
|
||||
|
||||
impl DisplayNameAndId {
|
||||
fn get_block_name(&self, p: &Path) -> String {
|
||||
let file_stem = p.file_stem();
|
||||
if let Some(file_stem) = file_stem {
|
||||
if file_stem == "index" {
|
||||
} else {
|
||||
return file_stem.to_string_lossy().to_string();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
self.get_block_name(p.parent().expect("/index/index/index?"))
|
||||
}
|
||||
|
||||
fn get_display_name(&mut self, _: &Expr) -> JsWord {
|
||||
let component_name = self.cur_display_name.clone().unwrap_or(js_word!(""));
|
||||
|
||||
match &self.file.name {
|
||||
FileName::Real(f) if self.config.file_name => {
|
||||
let block_name = self.get_block_name(f);
|
||||
|
||||
if block_name == *component_name {
|
||||
return component_name;
|
||||
}
|
||||
|
||||
if component_name.is_empty() {
|
||||
return prefix_leading_digit(&block_name).into();
|
||||
}
|
||||
|
||||
format!("{}__{}", prefix_leading_digit(&block_name), component_name).into()
|
||||
}
|
||||
|
||||
_ => component_name,
|
||||
}
|
||||
}
|
||||
|
||||
fn next_id(&mut self) -> usize {
|
||||
let ret = self.component_id;
|
||||
self.component_id += 1;
|
||||
ret
|
||||
}
|
||||
|
||||
fn get_component_id(&mut self) -> String {
|
||||
// Prefix the identifier with a character because CSS classes cannot start with
|
||||
// a number
|
||||
|
||||
let next_id = self.next_id();
|
||||
|
||||
let hash = {
|
||||
let base = self.file.src_hash;
|
||||
let base = base.to_be_bytes();
|
||||
let a = u32::from_be_bytes(base[0..4].try_into().unwrap());
|
||||
let b = u32::from_be_bytes(base[4..8].try_into().unwrap());
|
||||
let c = u32::from_be_bytes(base[8..12].try_into().unwrap());
|
||||
let d = u32::from_be_bytes(base[12..16].try_into().unwrap());
|
||||
|
||||
a ^ b ^ c ^ d
|
||||
};
|
||||
|
||||
format!("{}sc-{:x}-{}", self.config.use_namespace(), hash, next_id)
|
||||
}
|
||||
|
||||
fn add_config(
|
||||
&mut self,
|
||||
e: &mut Expr,
|
||||
display_name: Option<JsWord>,
|
||||
component_id: Option<JsWord>,
|
||||
) {
|
||||
if display_name.is_none() && component_id.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut with_config_props = vec![];
|
||||
|
||||
if let Some(display_name) = display_name {
|
||||
with_config_props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(quote_ident!("displayName")),
|
||||
value: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: display_name,
|
||||
raw: None,
|
||||
}))),
|
||||
}))))
|
||||
}
|
||||
|
||||
if let Some(component_id) = component_id {
|
||||
with_config_props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(quote_ident!("componentId")),
|
||||
value: Box::new(Expr::Lit(Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: component_id,
|
||||
raw: None,
|
||||
}))),
|
||||
}))))
|
||||
}
|
||||
|
||||
get_existing_config(e, |e| {
|
||||
if let Expr::Call(CallExpr { args, .. }) = e {
|
||||
if let Some(Expr::Object(existing_config)) = args.get_mut(0).map(|v| &mut *v.expr) {
|
||||
if !already_has(existing_config) {
|
||||
existing_config.props.extend(with_config_props.take());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if with_config_props.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
args,
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
if let Expr::Member(MemberExpr {
|
||||
prop: MemberProp::Ident(prop),
|
||||
..
|
||||
}) = &**callee
|
||||
{
|
||||
if &*prop.sym == "withConfig" {
|
||||
if let Some(first_arg) = args.get_mut(0) {
|
||||
if first_arg.spread.is_none() && first_arg.expr.is_object() {
|
||||
if let Expr::Object(obj) = &mut *first_arg.expr {
|
||||
if !already_has(&*obj) {
|
||||
obj.props.extend(with_config_props);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Expr::TaggedTpl(e) = e {
|
||||
e.tag = Box::new(Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: e
|
||||
.tag
|
||||
.take()
|
||||
.make_member(quote_ident!("withConfig"))
|
||||
.as_callee(),
|
||||
args: vec![ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props: with_config_props,
|
||||
}
|
||||
.as_arg()],
|
||||
type_args: Default::default(),
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
*callee = Box::new(Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: callee
|
||||
.take()
|
||||
.make_member(quote_ident!("withConfig"))
|
||||
.as_callee(),
|
||||
args: vec![ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props: with_config_props,
|
||||
}
|
||||
.as_arg()],
|
||||
type_args: Default::default(),
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
unreachable!("expr should be tagged tpl or call expr");
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for DisplayNameAndId {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_assign_expr(&mut self, e: &mut AssignExpr) {
|
||||
let old = self.cur_display_name.clone();
|
||||
|
||||
if old.is_none() {
|
||||
self.cur_display_name = e.left.as_ident().map(|v| v.sym.clone());
|
||||
}
|
||||
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
self.cur_display_name = old;
|
||||
}
|
||||
|
||||
fn visit_mut_class_prop(&mut self, e: &mut ClassProp) {
|
||||
let old = self.cur_display_name.take();
|
||||
|
||||
if let PropName::Ident(i) = &e.key {
|
||||
self.cur_display_name = Some(i.sym.clone());
|
||||
}
|
||||
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
self.cur_display_name = old;
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, expr: &mut Expr) {
|
||||
expr.visit_mut_children_with(self);
|
||||
|
||||
let is_styled = match expr {
|
||||
Expr::TaggedTpl(e) => self.state.borrow().is_styled(&e.tag),
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
args,
|
||||
..
|
||||
}) => {
|
||||
(
|
||||
// styled()
|
||||
self.state.borrow().is_styled(&*callee)
|
||||
&& get_property_as_ident(callee)
|
||||
.map(|v| v == "withConfig")
|
||||
.unwrap_or(false)
|
||||
) || (
|
||||
// styled(x)({})
|
||||
self.state.borrow().is_styled(&*callee)
|
||||
&& !get_callee(callee)
|
||||
.map(|callee| callee.is_member())
|
||||
.unwrap_or(false)
|
||||
) || (
|
||||
// styled(x).attrs()({})
|
||||
self.state.borrow().is_styled(callee)
|
||||
&& get_callee(callee)
|
||||
.map(|callee| {
|
||||
callee.is_member()
|
||||
&& get_property_as_ident(callee)
|
||||
.map(|v| v == "withConfig")
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
) || (
|
||||
// styled(x).withConfig({})
|
||||
self.state.borrow().is_styled(&*callee)
|
||||
&& get_callee(callee)
|
||||
.map(|callee| {
|
||||
callee.is_member()
|
||||
&& get_property_as_ident(callee)
|
||||
.map(|v| v == "withConfig")
|
||||
.unwrap_or(false)
|
||||
&& !args.is_empty()
|
||||
&& args[0].spread.is_none()
|
||||
&& match &*args[0].expr {
|
||||
Expr::Object(first_arg) => {
|
||||
!first_arg.props.iter().any(|prop| match prop {
|
||||
PropOrSpread::Prop(prop) => {
|
||||
match get_prop_name(prop) {
|
||||
Some(PropName::Ident(prop_name)) => {
|
||||
match &*prop_name.sym {
|
||||
"componentId" | "displayName" => {
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
)
|
||||
}
|
||||
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !is_styled {
|
||||
return;
|
||||
}
|
||||
|
||||
let _tracing = if cfg!(debug_assertions) {
|
||||
Some(span!(Level::ERROR, "display_name_and_id").entered())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let display_name = if self.config.display_name {
|
||||
Some(self.get_display_name(expr))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
trace!("display_name: {:?}", display_name);
|
||||
|
||||
let component_id = if self.config.ssr {
|
||||
Some(self.get_component_id().into())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
trace!("component_id: {:?}", display_name);
|
||||
|
||||
self.add_config(
|
||||
expr,
|
||||
display_name.map(|s| DISPLAY_NAME_REGEX.replace_all(&*s, "").into()),
|
||||
component_id,
|
||||
)
|
||||
}
|
||||
|
||||
fn visit_mut_key_value_prop(&mut self, e: &mut KeyValueProp) {
|
||||
let old = self.cur_display_name.take();
|
||||
|
||||
if let PropName::Ident(name) = &e.key {
|
||||
self.cur_display_name = Some(name.sym.clone());
|
||||
}
|
||||
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
self.cur_display_name = old;
|
||||
}
|
||||
|
||||
fn visit_mut_var_declarator(&mut self, v: &mut VarDeclarator) {
|
||||
let old = self.cur_display_name.take();
|
||||
|
||||
if let Pat::Ident(name) = &v.name {
|
||||
self.cur_display_name = Some(name.id.sym.clone());
|
||||
}
|
||||
|
||||
v.visit_mut_children_with(self);
|
||||
|
||||
self.cur_display_name = old;
|
||||
}
|
||||
}
|
||||
|
||||
fn get_callee(e: &Expr) -> Option<&Expr> {
|
||||
match e {
|
||||
Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) => Some(callee),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property_as_ident(e: &Expr) -> Option<&JsWord> {
|
||||
if let Expr::Member(MemberExpr {
|
||||
prop: MemberProp::Ident(p),
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
return Some(&p.sym);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn already_has(obj: &ObjectLit) -> bool {
|
||||
obj.props
|
||||
.iter()
|
||||
.filter_map(|v| match v {
|
||||
PropOrSpread::Prop(p) => Some(p),
|
||||
_ => None,
|
||||
})
|
||||
.filter_map(|v| get_prop_name(v))
|
||||
.any(|prop| match prop {
|
||||
PropName::Ident(ident) => &*ident.sym == "componentId" || &*ident.sym == "displayName",
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_existing_config<F>(e: &mut Expr, op: F)
|
||||
where
|
||||
F: FnOnce(&mut Expr),
|
||||
{
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee_callee),
|
||||
..
|
||||
}) = &mut **callee
|
||||
{
|
||||
if let Expr::Member(MemberExpr {
|
||||
prop: MemberProp::Ident(prop),
|
||||
..
|
||||
}) = &**callee_callee
|
||||
{
|
||||
if &*prop.sym == "withConfig" {
|
||||
return op(callee);
|
||||
}
|
||||
}
|
||||
|
||||
if let Expr::Member(MemberExpr {
|
||||
obj,
|
||||
prop: MemberProp::Ident(..),
|
||||
..
|
||||
}) = &mut **callee_callee
|
||||
{
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
..
|
||||
}) = &**obj
|
||||
{
|
||||
if let Expr::Member(MemberExpr {
|
||||
prop: MemberProp::Ident(prop),
|
||||
..
|
||||
}) = &**callee
|
||||
{
|
||||
if &*prop.sym == "withConfig" {
|
||||
op(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
pub mod assign_style_required;
|
||||
pub mod display_name_and_id;
|
||||
pub mod minify;
|
||||
pub mod transpile_css_prop;
|
|
@ -0,0 +1,2 @@
|
|||
mod top_level_binding_collector;
|
||||
pub mod transpile;
|
|
@ -0,0 +1,94 @@
|
|||
use swc_common::collections::AHashSet;
|
||||
use swc_ecmascript::{
|
||||
ast::{
|
||||
ArrowExpr, ClassDecl, FnDecl, Function, ImportDefaultSpecifier, ImportNamedSpecifier,
|
||||
ImportStarAsSpecifier, ObjectPatProp, Pat, VarDeclarator,
|
||||
},
|
||||
utils::{ident::IdentLike, Id},
|
||||
visit::{noop_visit_type, Visit, VisitWith},
|
||||
};
|
||||
|
||||
// Modified from swc_ecma_utils/src/lib.rs:BindingCollector.
|
||||
pub struct TopLevelBindingCollector {
|
||||
bindings: AHashSet<Id>,
|
||||
in_pat_decl: bool,
|
||||
}
|
||||
|
||||
impl TopLevelBindingCollector {
|
||||
fn add(&mut self, i: &Id) {
|
||||
self.bindings.insert(i.clone());
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for TopLevelBindingCollector {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_class_decl(&mut self, node: &ClassDecl) {
|
||||
self.add(&node.ident.to_id());
|
||||
}
|
||||
|
||||
fn visit_fn_decl(&mut self, node: &FnDecl) {
|
||||
self.add(&node.ident.to_id());
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, node: &Pat) {
|
||||
if !self.in_pat_decl {
|
||||
return;
|
||||
}
|
||||
match node {
|
||||
Pat::Ident(i) => self.add(&i.id.to_id()),
|
||||
Pat::Object(o) => {
|
||||
for prop in o.props.iter() {
|
||||
match prop {
|
||||
ObjectPatProp::Assign(a) => self.add(&a.key.to_id()),
|
||||
ObjectPatProp::KeyValue(k) => k.value.visit_with(self),
|
||||
ObjectPatProp::Rest(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Pat::Array(a) => {
|
||||
for elem in a.elems.iter() {
|
||||
elem.visit_with(self);
|
||||
}
|
||||
}
|
||||
Pat::Assign(a) => {
|
||||
a.left.visit_with(self);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_arrow_expr(&mut self, _: &ArrowExpr) {}
|
||||
fn visit_function(&mut self, _: &Function) {}
|
||||
|
||||
fn visit_import_default_specifier(&mut self, node: &ImportDefaultSpecifier) {
|
||||
self.add(&node.local.to_id());
|
||||
}
|
||||
|
||||
fn visit_import_named_specifier(&mut self, node: &ImportNamedSpecifier) {
|
||||
self.add(&node.local.to_id());
|
||||
}
|
||||
|
||||
fn visit_import_star_as_specifier(&mut self, node: &ImportStarAsSpecifier) {
|
||||
self.add(&node.local.to_id());
|
||||
}
|
||||
|
||||
fn visit_var_declarator(&mut self, node: &VarDeclarator) {
|
||||
let old = self.in_pat_decl;
|
||||
self.in_pat_decl = true;
|
||||
node.name.visit_with(self);
|
||||
self.in_pat_decl = old;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_top_level_decls<N>(n: &N) -> AHashSet<Id>
|
||||
where
|
||||
N: VisitWith<TopLevelBindingCollector>,
|
||||
{
|
||||
let mut v = TopLevelBindingCollector {
|
||||
bindings: Default::default(),
|
||||
in_pat_decl: false,
|
||||
};
|
||||
n.visit_with(&mut v);
|
||||
v.bindings
|
||||
}
|
|
@ -0,0 +1,631 @@
|
|||
//! Port of https://github.com/styled-components/babel-plugin-styled-components/blob/a20c3033508677695953e7a434de4746168eeb4e/src/visitors/transpileCssProp.js
|
||||
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
||||
use inflector::Inflector;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::{
|
||||
collections::{AHashMap, AHashSet},
|
||||
util::take::Take,
|
||||
Spanned, DUMMY_SP,
|
||||
};
|
||||
use swc_ecmascript::{
|
||||
ast::*,
|
||||
utils::{ident::IdentLike, prepend, private_ident, quote_ident, ExprExt, ExprFactory, Id},
|
||||
visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith},
|
||||
};
|
||||
|
||||
use crate::utils::{get_prop_key_as_expr, get_prop_name, get_prop_name2};
|
||||
|
||||
use super::top_level_binding_collector::collect_top_level_decls;
|
||||
|
||||
static TAG_NAME_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new("^[a-z][a-z\\d]*(\\-[a-z][a-z\\d]*)?$").unwrap());
|
||||
|
||||
pub fn transpile_css_prop() -> impl Fold + VisitMut {
|
||||
as_folder(TranspileCssProp::default())
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TranspileCssProp {
|
||||
import_name: Option<Ident>,
|
||||
injected_nodes: Vec<Stmt>,
|
||||
interleaved_injections: AHashMap<Id, Vec<Stmt>>,
|
||||
|
||||
identifier_idx: usize,
|
||||
styled_idx: HashMap<JsWord, usize>,
|
||||
top_level_decls: Option<AHashSet<Id>>,
|
||||
}
|
||||
|
||||
impl TranspileCssProp {
|
||||
fn next_styled_idx(&mut self, key: JsWord) -> usize {
|
||||
let idx = self.styled_idx.entry(key).or_insert(0);
|
||||
*idx += 1;
|
||||
*idx
|
||||
}
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_top_level_ident(&mut self, ident: &Ident) -> bool {
|
||||
self.top_level_decls
|
||||
.as_ref()
|
||||
.map(|decls| decls.contains(&ident.to_id()))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for TranspileCssProp {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_jsx_element(&mut self, elem: &mut JSXElement) {
|
||||
elem.visit_mut_children_with(self);
|
||||
|
||||
let mut extra_attrs = vec![];
|
||||
|
||||
for attr in elem.opening.attrs.iter_mut() {
|
||||
match &mut *attr {
|
||||
JSXAttrOrSpread::JSXAttr(attr) => {
|
||||
if !matches!(&attr.name, JSXAttrName::Ident(i) if &*i.sym == "css") {
|
||||
continue;
|
||||
}
|
||||
|
||||
let import_name = self
|
||||
.import_name
|
||||
.get_or_insert_with(|| private_ident!("_styled"))
|
||||
.clone();
|
||||
|
||||
let name = get_name_ident(&elem.opening.name);
|
||||
let id_sym = name.sym.to_class_case();
|
||||
|
||||
// Match the original plugin's behavior.
|
||||
let id_sym = id_sym.trim_end_matches(char::is_numeric);
|
||||
|
||||
let id_sym = JsWord::from(id_sym);
|
||||
let styled_idx = self.next_styled_idx(id_sym.clone());
|
||||
let id = quote_ident!(
|
||||
elem.opening.name.span(),
|
||||
append_if_gt_one(&format!("_Styled{}", id_sym), styled_idx)
|
||||
);
|
||||
|
||||
let (styled, inject_after) = if TAG_NAME_REGEX.is_match(&name.sym) {
|
||||
(
|
||||
(Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: import_name.as_callee(),
|
||||
args: vec![Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: name.sym,
|
||||
raw: None,
|
||||
})
|
||||
.as_arg()],
|
||||
type_args: Default::default(),
|
||||
})),
|
||||
None::<Ident>,
|
||||
)
|
||||
} else {
|
||||
let name_expr = get_name_expr(&elem.opening.name);
|
||||
|
||||
(
|
||||
Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: import_name.as_callee(),
|
||||
args: vec![name_expr.as_arg()],
|
||||
type_args: Default::default(),
|
||||
}),
|
||||
if self.is_top_level_ident(&name) {
|
||||
Some(name)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
let mut css = match &mut attr.value {
|
||||
Some(css) => {
|
||||
//
|
||||
|
||||
match css {
|
||||
JSXAttrValue::Lit(Lit::Str(v)) => Expr::Tpl(Tpl {
|
||||
span: DUMMY_SP,
|
||||
exprs: Default::default(),
|
||||
quasis: vec![TplElement {
|
||||
span: DUMMY_SP,
|
||||
tail: true,
|
||||
cooked: None,
|
||||
raw: v.value.clone(),
|
||||
}],
|
||||
}),
|
||||
JSXAttrValue::JSXExprContainer(JSXExprContainer {
|
||||
expr: JSXExpr::Expr(v),
|
||||
..
|
||||
}) => match &mut **v {
|
||||
Expr::Tpl(..) => *v.take(),
|
||||
Expr::TaggedTpl(v) if v.tag.is_ident_ref_to("css".into()) => {
|
||||
Expr::Tpl(v.tpl.take())
|
||||
}
|
||||
Expr::Object(..) => *v.take(),
|
||||
_ => Expr::Tpl(Tpl {
|
||||
span: DUMMY_SP,
|
||||
exprs: vec![v.take()],
|
||||
quasis: vec![
|
||||
TplElement {
|
||||
span: DUMMY_SP,
|
||||
tail: false,
|
||||
cooked: None,
|
||||
raw: "".into(),
|
||||
},
|
||||
TplElement {
|
||||
span: DUMMY_SP,
|
||||
tail: true,
|
||||
cooked: None,
|
||||
raw: "".into(),
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
|
||||
_ => continue,
|
||||
}
|
||||
}
|
||||
None => continue,
|
||||
};
|
||||
|
||||
// Remove this attribute
|
||||
attr.name = JSXAttrName::Ident(Take::dummy());
|
||||
|
||||
elem.opening.name = JSXElementName::Ident(id.clone());
|
||||
|
||||
if let Some(closing) = &mut elem.closing {
|
||||
closing.name = JSXElementName::Ident(id.clone());
|
||||
}
|
||||
|
||||
// object syntax
|
||||
if let Expr::Object(css_obj) = &mut css {
|
||||
// Original plugin says
|
||||
//
|
||||
//
|
||||
// for objects as CSS props, we have to recurse through the object and
|
||||
// replace any object key/value scope references with generated props
|
||||
// similar to how the template literal transform above creates dynamic
|
||||
// interpolations
|
||||
let p = quote_ident!("p");
|
||||
|
||||
let mut reducer = PropertyReducer {
|
||||
p: p.clone(),
|
||||
replace_object_with_prop_function: false,
|
||||
extra_attrs: Default::default(),
|
||||
identifier_idx: &mut self.identifier_idx,
|
||||
};
|
||||
|
||||
css_obj.props = css_obj
|
||||
.props
|
||||
.take()
|
||||
.into_iter()
|
||||
.fold(vec![], |acc, property| {
|
||||
reducer.reduce_object_properties(acc, property)
|
||||
});
|
||||
|
||||
extra_attrs.extend(reducer.extra_attrs);
|
||||
|
||||
if reducer.replace_object_with_prop_function {
|
||||
css = Expr::Arrow(ArrowExpr {
|
||||
span: DUMMY_SP,
|
||||
params: vec![Pat::Ident(p.clone().into())],
|
||||
body: BlockStmtOrExpr::Expr(Box::new(css.take())),
|
||||
is_async: false,
|
||||
is_generator: false,
|
||||
type_params: Default::default(),
|
||||
return_type: Default::default(),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// tagged template literal
|
||||
let mut tpl = css.expect_tpl();
|
||||
|
||||
tpl.exprs =
|
||||
tpl.exprs
|
||||
.take()
|
||||
.into_iter()
|
||||
.fold(vec![], |mut acc, mut expr| {
|
||||
if expr.is_fn_expr() || expr.is_arrow() {
|
||||
acc.push(expr);
|
||||
return acc;
|
||||
} else if let Some(root) = trace_root_value(&mut *expr) {
|
||||
let direct_access = match root {
|
||||
Expr::Lit(_) => true,
|
||||
Expr::Ident(id) if self.is_top_level_ident(id) => true,
|
||||
_ => false,
|
||||
};
|
||||
if direct_access {
|
||||
acc.push(expr);
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
|
||||
let identifier =
|
||||
get_local_identifier(&mut self.identifier_idx, &expr);
|
||||
let p = quote_ident!("p");
|
||||
extra_attrs.push(JSXAttrOrSpread::JSXAttr(JSXAttr {
|
||||
span: DUMMY_SP,
|
||||
name: JSXAttrName::Ident(identifier.clone()),
|
||||
value: Some(JSXAttrValue::JSXExprContainer(
|
||||
JSXExprContainer {
|
||||
span: DUMMY_SP,
|
||||
expr: JSXExpr::Expr(expr.take()),
|
||||
},
|
||||
)),
|
||||
}));
|
||||
|
||||
acc.push(Box::new(Expr::Arrow(ArrowExpr {
|
||||
span: DUMMY_SP,
|
||||
params: vec![Pat::Ident(p.clone().into())],
|
||||
body: BlockStmtOrExpr::Expr(Box::new(
|
||||
p.make_member(identifier),
|
||||
)),
|
||||
is_async: false,
|
||||
is_generator: false,
|
||||
type_params: Default::default(),
|
||||
return_type: Default::default(),
|
||||
})));
|
||||
|
||||
acc
|
||||
});
|
||||
|
||||
css = Expr::Tpl(tpl);
|
||||
}
|
||||
|
||||
let var = VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
name: Pat::Ident(id.clone().into()),
|
||||
init: Some(match css {
|
||||
Expr::Object(..) | Expr::Arrow(..) => Box::new(Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: styled.as_callee(),
|
||||
args: vec![css.as_arg()],
|
||||
type_args: Default::default(),
|
||||
})),
|
||||
_ => Box::new(Expr::TaggedTpl(TaggedTpl {
|
||||
span: DUMMY_SP,
|
||||
tag: Box::new(styled),
|
||||
type_params: Default::default(),
|
||||
tpl: css.expect_tpl(),
|
||||
})),
|
||||
}),
|
||||
definite: false,
|
||||
};
|
||||
let stmt = Stmt::Decl(Decl::Var(VarDecl {
|
||||
span: DUMMY_SP,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![var],
|
||||
}));
|
||||
match inject_after {
|
||||
Some(injector) => {
|
||||
let id = injector.to_id();
|
||||
self.interleaved_injections
|
||||
.entry(id)
|
||||
.or_default()
|
||||
.push(stmt);
|
||||
}
|
||||
None => {
|
||||
self.injected_nodes.push(stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
JSXAttrOrSpread::SpreadElement(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
elem.opening.attrs.retain(|attr| {
|
||||
match attr {
|
||||
JSXAttrOrSpread::JSXAttr(attr) => {
|
||||
if matches!(
|
||||
attr.name,
|
||||
JSXAttrName::Ident(Ident {
|
||||
sym: js_word!(""),
|
||||
..
|
||||
})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
JSXAttrOrSpread::SpreadElement(_) => {}
|
||||
}
|
||||
true
|
||||
});
|
||||
|
||||
elem.opening.attrs.extend(extra_attrs);
|
||||
}
|
||||
|
||||
fn visit_mut_module(&mut self, n: &mut Module) {
|
||||
// TODO: Skip if there are no css prop usage
|
||||
self.top_level_decls = Some(collect_top_level_decls(n));
|
||||
n.visit_mut_children_with(self);
|
||||
self.top_level_decls = None;
|
||||
|
||||
if let Some(import_name) = self.import_name.take() {
|
||||
let specifier = ImportSpecifier::Default(ImportDefaultSpecifier {
|
||||
span: DUMMY_SP,
|
||||
local: import_name,
|
||||
});
|
||||
prepend(
|
||||
&mut n.body,
|
||||
ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl {
|
||||
span: DUMMY_SP,
|
||||
specifiers: vec![specifier],
|
||||
src: Str {
|
||||
span: DUMMY_SP,
|
||||
value: "styled-components".into(),
|
||||
raw: None,
|
||||
},
|
||||
type_only: Default::default(),
|
||||
asserts: Default::default(),
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
||||
let mut serialized_body: Vec<ModuleItem> = vec![];
|
||||
let body = std::mem::take(&mut n.body);
|
||||
for item in body {
|
||||
serialized_body.push(item.clone());
|
||||
if let ModuleItem::Stmt(Stmt::Decl(Decl::Var(vd))) = &item {
|
||||
for decl in &vd.decls {
|
||||
if let Pat::Ident(ident) = &decl.name {
|
||||
let id = ident.to_id();
|
||||
let stmts = self.interleaved_injections.remove(&id);
|
||||
if let Some(stmts) = stmts {
|
||||
serialized_body.extend(stmts.into_iter().rev().map(ModuleItem::Stmt));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n.body = serialized_body;
|
||||
|
||||
let mut remaining = std::mem::take(&mut self.interleaved_injections)
|
||||
.into_iter()
|
||||
.collect::<Vec<_>>();
|
||||
remaining.sort_by_key(|x| x.0.clone());
|
||||
|
||||
remaining
|
||||
.into_iter()
|
||||
.for_each(|(_, stmts)| n.body.extend(stmts.into_iter().map(ModuleItem::Stmt)));
|
||||
|
||||
n.body
|
||||
.extend(self.injected_nodes.take().into_iter().map(ModuleItem::Stmt));
|
||||
}
|
||||
}
|
||||
|
||||
fn get_name_expr(name: &JSXElementName) -> Box<Expr> {
|
||||
fn get_name_expr_jsx_object(name: &JSXObject) -> Box<Expr> {
|
||||
match name {
|
||||
JSXObject::Ident(n) => Box::new(Expr::Ident(n.clone())),
|
||||
JSXObject::JSXMemberExpr(n) => Box::new(Expr::Member(MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: get_name_expr_jsx_object(&n.obj),
|
||||
prop: MemberProp::Ident(n.prop.clone()),
|
||||
})),
|
||||
}
|
||||
}
|
||||
match name {
|
||||
JSXElementName::Ident(n) => Box::new(Expr::Ident(n.clone())),
|
||||
JSXElementName::JSXMemberExpr(n) => Box::new(Expr::Member(MemberExpr {
|
||||
span: DUMMY_SP,
|
||||
obj: get_name_expr_jsx_object(&n.obj),
|
||||
prop: MemberProp::Ident(n.prop.clone()),
|
||||
})),
|
||||
JSXElementName::JSXNamespacedName(..) => {
|
||||
unimplemented!("get_name_expr for JSXNamespacedName")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct PropertyReducer<'a> {
|
||||
p: Ident,
|
||||
replace_object_with_prop_function: bool,
|
||||
extra_attrs: Vec<JSXAttrOrSpread>,
|
||||
|
||||
identifier_idx: &'a mut usize,
|
||||
}
|
||||
|
||||
impl PropertyReducer<'_> {
|
||||
fn reduce_object_properties(
|
||||
&mut self,
|
||||
mut acc: Vec<PropOrSpread>,
|
||||
mut property: PropOrSpread,
|
||||
) -> Vec<PropOrSpread> {
|
||||
match property {
|
||||
PropOrSpread::Spread(ref mut prop) => {
|
||||
// handle spread variables and such
|
||||
|
||||
if let Expr::Object(arg) = &mut *prop.expr {
|
||||
arg.props = arg
|
||||
.props
|
||||
.take()
|
||||
.into_iter()
|
||||
.fold(vec![], |acc, p| self.reduce_object_properties(acc, p));
|
||||
} else {
|
||||
self.replace_object_with_prop_function = true;
|
||||
|
||||
let identifier = get_local_identifier(self.identifier_idx, &prop.expr);
|
||||
|
||||
self.extra_attrs.push(JSXAttrOrSpread::JSXAttr(JSXAttr {
|
||||
span: DUMMY_SP,
|
||||
name: JSXAttrName::Ident(identifier.clone()),
|
||||
value: Some(JSXAttrValue::JSXExprContainer(JSXExprContainer {
|
||||
span: DUMMY_SP,
|
||||
expr: JSXExpr::Expr(prop.expr.take()),
|
||||
})),
|
||||
}));
|
||||
|
||||
prop.expr = Box::new(self.p.clone().make_member(identifier));
|
||||
}
|
||||
|
||||
acc.push(property);
|
||||
}
|
||||
PropOrSpread::Prop(ref mut prop) => {
|
||||
let key = get_prop_key_as_expr(prop);
|
||||
let key_pn = get_prop_name(prop);
|
||||
|
||||
if key.is_member()
|
||||
|| key.is_call()
|
||||
|| (key.is_ident()
|
||||
&& key_pn.is_some()
|
||||
&& key_pn.unwrap().is_computed()
|
||||
&& !matches!(&**prop, Prop::Shorthand(..)))
|
||||
{
|
||||
self.replace_object_with_prop_function = true;
|
||||
|
||||
let identifier = get_local_identifier(self.identifier_idx, &key);
|
||||
|
||||
self.extra_attrs.push(JSXAttrOrSpread::JSXAttr(JSXAttr {
|
||||
span: DUMMY_SP,
|
||||
name: identifier.clone().into(),
|
||||
value: Some(JSXAttrValue::JSXExprContainer(JSXExprContainer {
|
||||
span: DUMMY_SP,
|
||||
// TODO: Perf
|
||||
expr: JSXExpr::Expr(Box::new(key.clone().into_owned())),
|
||||
})),
|
||||
}));
|
||||
|
||||
set_key_of_prop(prop, Box::new(self.p.clone().make_member(identifier)));
|
||||
}
|
||||
|
||||
let mut value = take_prop_value(prop);
|
||||
|
||||
if let Expr::Object(value_obj) = &mut *value {
|
||||
value_obj.props = value_obj
|
||||
.props
|
||||
.take()
|
||||
.into_iter()
|
||||
.fold(vec![], |acc, p| self.reduce_object_properties(acc, p));
|
||||
|
||||
set_value_of_prop(prop, value);
|
||||
acc.push(property);
|
||||
} else if !matches!(&*value, Expr::Lit(..)) {
|
||||
// if a non-primitive value we have to interpolate it
|
||||
|
||||
self.replace_object_with_prop_function = true;
|
||||
|
||||
let identifier = get_local_identifier(self.identifier_idx, &value);
|
||||
|
||||
self.extra_attrs.push(JSXAttrOrSpread::JSXAttr(JSXAttr {
|
||||
span: DUMMY_SP,
|
||||
name: JSXAttrName::Ident(identifier.clone()),
|
||||
value: Some(JSXAttrValue::JSXExprContainer(JSXExprContainer {
|
||||
span: DUMMY_SP,
|
||||
expr: JSXExpr::Expr(value.take()),
|
||||
})),
|
||||
}));
|
||||
|
||||
let key = get_prop_name2(prop);
|
||||
|
||||
acc.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp {
|
||||
key,
|
||||
value: Box::new(self.p.clone().make_member(identifier)),
|
||||
}))));
|
||||
} else {
|
||||
set_value_of_prop(prop, value);
|
||||
acc.push(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
acc
|
||||
}
|
||||
}
|
||||
|
||||
fn set_value_of_prop(prop: &mut Prop, value: Box<Expr>) {
|
||||
match prop {
|
||||
Prop::Shorthand(p) => {
|
||||
*prop = Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Ident(p.clone()),
|
||||
value,
|
||||
});
|
||||
}
|
||||
Prop::KeyValue(p) => {
|
||||
p.value = value;
|
||||
}
|
||||
Prop::Assign(..) => unreachable!("assign property is not allowed for object literals"),
|
||||
Prop::Getter(_p) => todo!(),
|
||||
Prop::Setter(_p) => todo!(),
|
||||
Prop::Method(_p) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn take_prop_value(prop: &mut Prop) -> Box<Expr> {
|
||||
match prop {
|
||||
Prop::Shorthand(p) => Box::new(Expr::Ident(p.clone())),
|
||||
Prop::KeyValue(p) => p.value.take(),
|
||||
Prop::Assign(..) => unreachable!("assign property is not allowed for object literals"),
|
||||
Prop::Getter(_p) => todo!(),
|
||||
Prop::Setter(_p) => todo!(),
|
||||
Prop::Method(_p) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_key_of_prop(prop: &mut Prop, key: Box<Expr>) {
|
||||
let value = take_prop_value(prop);
|
||||
|
||||
*prop = Prop::KeyValue(KeyValueProp {
|
||||
key: PropName::Computed(ComputedPropName {
|
||||
span: DUMMY_SP,
|
||||
expr: key,
|
||||
}),
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
fn get_local_identifier(idx: &mut usize, expr: &Expr) -> Ident {
|
||||
*idx += 1;
|
||||
|
||||
let identifier = quote_ident!(expr.span(), append_if_gt_one("$_css", *idx));
|
||||
|
||||
// TODO: Unique identifier
|
||||
|
||||
identifier
|
||||
}
|
||||
|
||||
fn append_if_gt_one(s: &str, suffix: usize) -> Cow<str> {
|
||||
if suffix > 1 {
|
||||
Cow::Owned(format!("{}{}", s, suffix))
|
||||
} else {
|
||||
Cow::Borrowed(s)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_name_ident(el: &JSXElementName) -> Ident {
|
||||
match el {
|
||||
JSXElementName::Ident(v) => v.clone(),
|
||||
JSXElementName::JSXMemberExpr(e) => Ident {
|
||||
sym: format!("{}_{}", get_name_of_jsx_obj(&e.obj), e.prop.sym).into(),
|
||||
span: e.prop.span,
|
||||
optional: false,
|
||||
},
|
||||
_ => {
|
||||
unimplemented!("get_name_ident for namespaced jsx element")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_name_of_jsx_obj(el: &JSXObject) -> JsWord {
|
||||
match el {
|
||||
JSXObject::Ident(v) => v.sym.clone(),
|
||||
JSXObject::JSXMemberExpr(e) => {
|
||||
format!("{}{}", get_name_of_jsx_obj(&e.obj), e.prop.sym).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn trace_root_value(e: &mut Expr) -> Option<&mut Expr> {
|
||||
match e {
|
||||
Expr::Member(e) => trace_root_value(&mut e.obj),
|
||||
Expr::Call(e) => match &mut e.callee {
|
||||
Callee::Expr(e) => trace_root_value(&mut **e),
|
||||
_ => None,
|
||||
},
|
||||
Expr::Ident(_) => Some(e),
|
||||
Expr::Lit(_) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
33
packages/next-swc/crates/styled_components/tests/fixture.rs
Normal file
33
packages/next-swc/crates/styled_components/tests/fixture.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
#![deny(unused)]
|
||||
|
||||
use std::{fs::read_to_string, path::PathBuf};
|
||||
use styled_components::{styled_components, Config};
|
||||
use swc_common::chain;
|
||||
use swc_ecma_transforms_testing::test_fixture;
|
||||
use swc_ecmascript::{
|
||||
parser::{EsConfig, Syntax},
|
||||
transforms::resolver,
|
||||
};
|
||||
|
||||
#[testing::fixture("tests/fixtures/**/code.js")]
|
||||
fn fixture(input: PathBuf) {
|
||||
let dir = input.parent().unwrap();
|
||||
let config = read_to_string(dir.join("config.json")).expect("failed to read config.json");
|
||||
println!("---- Config -----\n{}", config);
|
||||
let config: Config = serde_json::from_str(&config).unwrap();
|
||||
|
||||
test_fixture(
|
||||
Syntax::Es(EsConfig {
|
||||
jsx: true,
|
||||
..Default::default()
|
||||
}),
|
||||
&|t| {
|
||||
//
|
||||
let fm = t.cm.load_file(&input).unwrap();
|
||||
|
||||
chain!(resolver(), styled_components(fm, config.clone()))
|
||||
},
|
||||
&input,
|
||||
&dir.join("output.js"),
|
||||
)
|
||||
}
|
12
packages/next-swc/crates/styled_components/tests/fixtures/.allow-chains-of-member-calls/.babelrc
vendored
Normal file
12
packages/next-swc/crates/styled_components/tests/fixtures/.allow-chains-of-member-calls/.babelrc
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"ssr": false,
|
||||
"fileName": false,
|
||||
"transpileTemplateLiterals": false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
import styled from 'styled-components'
|
||||
|
||||
const WithAttrs = styled.div.attrs({ some: 'value' })``
|
||||
const WithAttrsWrapped = styled(Inner).attrs({ some: 'value' })``
|
|
@ -0,0 +1,11 @@
|
|||
import styled from 'styled-components';
|
||||
const WithAttrs = styled.div.attrs({
|
||||
some: 'value'
|
||||
}).withConfig({
|
||||
displayName: "WithAttrs"
|
||||
})``;
|
||||
const WithAttrsWrapped = styled(Inner).attrs({
|
||||
some: 'value'
|
||||
}).withConfig({
|
||||
displayName: "WithAttrsWrapped"
|
||||
})``;
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"pure": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { createGlobalStyle } from 'styled-components'
|
||||
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
body {
|
||||
color: red;
|
||||
}
|
||||
`
|
|
@ -0,0 +1,2 @@
|
|||
import { createGlobalStyle } from 'styled-components';
|
||||
const GlobalStyle = /*#__PURE__*/createGlobalStyle(["body{color:red;}"]);
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"pure": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import styled, { css } from 'styled-components'
|
||||
|
||||
const partial = css`
|
||||
color: red;
|
||||
`
|
||||
|
||||
const Component = styled.div`
|
||||
${partial};
|
||||
background: blue;
|
||||
`
|
|
@ -0,0 +1,6 @@
|
|||
import styled, { css } from 'styled-components';
|
||||
const partial = /*#__PURE__*/css(["color:red;"]);
|
||||
const Component = /*#__PURE__*/styled.div.withConfig({
|
||||
displayName: "code__Component",
|
||||
componentId: "sc-4wpzk3-0"
|
||||
})(["", ";background:blue;"], partial);
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"pure": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { keyframes } from 'styled-components'
|
||||
|
||||
const Animation = keyframes`
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
`
|
|
@ -0,0 +1,2 @@
|
|||
import { keyframes } from 'styled-components';
|
||||
const Animation = /*#__PURE__*/keyframes(["0%{opacity:0;}100%{opacity:1;}"]);
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"pure": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import styled from 'styled-components'
|
||||
|
||||
const Test = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
const Test2 = styled('div')``
|
||||
const Test3 = true ? styled.div`` : styled.div``
|
||||
const styles = { One: styled.div`` }
|
||||
let Component
|
||||
Component = styled.div``
|
||||
const WrappedComponent = styled(Inner)``
|
||||
const StyledObjectForm = styled.div({ color: red })
|
||||
const StyledFunctionForm = styled.div(p => ({ color: p.color || 'red' }))
|
||||
const normalFunc = add(5, 3)
|
|
@ -0,0 +1,44 @@
|
|||
import styled from 'styled-components';
|
||||
const Test = /*#__PURE__*/styled.div.withConfig({
|
||||
displayName: "code__Test",
|
||||
componentId: "sc-u20i28-0"
|
||||
})(["width:100%;"]);
|
||||
const Test2 = /*#__PURE__*/styled('div').withConfig({
|
||||
displayName: "code__Test2",
|
||||
componentId: "sc-u20i28-1"
|
||||
})([""]);
|
||||
const Test3 = true ? styled.div.withConfig({
|
||||
displayName: "code__Test3",
|
||||
componentId: "sc-u20i28-2"
|
||||
})([""]) : styled.div.withConfig({
|
||||
displayName: "code__Test3",
|
||||
componentId: "sc-u20i28-3"
|
||||
})([""]);
|
||||
const styles = {
|
||||
One: styled.div.withConfig({
|
||||
displayName: "code__One",
|
||||
componentId: "sc-u20i28-4"
|
||||
})([""])
|
||||
};
|
||||
let Component;
|
||||
Component = styled.div.withConfig({
|
||||
displayName: "code__Component",
|
||||
componentId: "sc-u20i28-5"
|
||||
})([""]);
|
||||
const WrappedComponent = /*#__PURE__*/styled(Inner).withConfig({
|
||||
displayName: "code__WrappedComponent",
|
||||
componentId: "sc-u20i28-6"
|
||||
})([""]);
|
||||
const StyledObjectForm = /*#__PURE__*/styled.div.withConfig({
|
||||
displayName: "code__StyledObjectForm",
|
||||
componentId: "sc-u20i28-7"
|
||||
})({
|
||||
color: red
|
||||
});
|
||||
const StyledFunctionForm = /*#__PURE__*/styled.div.withConfig({
|
||||
displayName: "code__StyledFunctionForm",
|
||||
componentId: "sc-u20i28-8"
|
||||
})(p => ({
|
||||
color: p.color || 'red'
|
||||
}));
|
||||
const normalFunc = add(5, 3);
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"pure": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
import { withTheme } from 'styled-components'
|
||||
|
||||
const ThemedComponent = withTheme(() => null)
|
|
@ -0,0 +1,2 @@
|
|||
import { withTheme } from 'styled-components';
|
||||
const ThemedComponent = /*#__PURE__*/withTheme(() => null);
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src"
|
||||
]
|
||||
]
|
||||
}
|
10
packages/next-swc/crates/styled_components/tests/fixtures/.css-declared-after-component/code.js
vendored
Normal file
10
packages/next-swc/crates/styled_components/tests/fixtures/.css-declared-after-component/code.js
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import React from "react"
|
||||
import { css } from "styled-components"
|
||||
|
||||
export default function Example() {
|
||||
return <div css={someCss}>oops</div>
|
||||
}
|
||||
|
||||
const someCss = css`
|
||||
color: red;
|
||||
`
|
|
@ -0,0 +1,12 @@
|
|||
import _styled from "styled-components";
|
||||
import React from "react";
|
||||
import { css } from "styled-components";
|
||||
export default function Example() {
|
||||
return <_StyledDiv>oops</_StyledDiv>;
|
||||
}
|
||||
const someCss = css(["color:red;"]);
|
||||
|
||||
var _StyledDiv = _styled("div").withConfig({
|
||||
displayName: "code___StyledDiv",
|
||||
componentId: "sc-7mydya-0"
|
||||
})(["", ""], someCss);
|
12
packages/next-swc/crates/styled_components/tests/fixtures/.minify-css-in-helpers/.babelrc
vendored
Normal file
12
packages/next-swc/crates/styled_components/tests/fixtures/.minify-css-in-helpers/.babelrc
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"ssr": false,
|
||||
"displayName": false,
|
||||
"transpileTemplateLiterals": false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
17
packages/next-swc/crates/styled_components/tests/fixtures/.minify-css-in-helpers/code.js
vendored
Normal file
17
packages/next-swc/crates/styled_components/tests/fixtures/.minify-css-in-helpers/code.js
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { createGlobalStyle, css, keyframes } from 'styled-components'
|
||||
|
||||
const key = keyframes`
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
`
|
||||
|
||||
const color = css`
|
||||
color: ${theColor};
|
||||
`
|
||||
|
||||
const GlobalStyles = createGlobalStyle`
|
||||
html {
|
||||
color: red;
|
||||
}
|
||||
`
|
4
packages/next-swc/crates/styled_components/tests/fixtures/.minify-css-in-helpers/output.js
vendored
Normal file
4
packages/next-swc/crates/styled_components/tests/fixtures/.minify-css-in-helpers/output.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { createGlobalStyle, css, keyframes } from 'styled-components';
|
||||
const key = keyframes`to{transform:rotate(360deg);}`;
|
||||
const color = css`color:${theColor};`;
|
||||
const GlobalStyles = createGlobalStyle`html{color:red;}`;
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"presets": [
|
||||
"@babel/preset-env"
|
||||
],
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"ssr": false,
|
||||
"displayName": false,
|
||||
"transpileTemplateLiterals": false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import styled from 'styled-components';
|
||||
|
||||
const Simple = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const Interpolation = styled.div`
|
||||
content: " ${props => props.text} ";
|
||||
`;
|
||||
|
||||
const SpecialCharacters = styled.div`
|
||||
content: " ${props => props.text} ";\n color: red;
|
||||
`;
|
||||
|
||||
const Comment = styled.div`
|
||||
// comment
|
||||
color: red;
|
||||
`
|
||||
|
||||
const Parens = styled.div`
|
||||
&:hover {
|
||||
color: blue;
|
||||
}
|
||||
`;
|
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
|
||||
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
||||
|
||||
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
||||
|
||||
var Simple = _styledComponents["default"].div(_templateObject || (_templateObject = _taggedTemplateLiteral(["width:100%;"])));
|
||||
|
||||
var Interpolation = _styledComponents["default"].div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["content:\" ", " \";"])), function (props) {
|
||||
return props.text;
|
||||
});
|
||||
|
||||
var SpecialCharacters = _styledComponents["default"].div(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["content:\" ", " \";color:red;"])), function (props) {
|
||||
return props.text;
|
||||
});
|
||||
|
||||
var Comment = _styledComponents["default"].div(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["color:red;"])));
|
||||
|
||||
var Parens = _styledComponents["default"].div(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["&:hover{color:blue;}"])));
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"ssr": false,
|
||||
"displayName": false,
|
||||
"transpileTemplateLiterals": false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import styled from 'styled-components';
|
||||
|
||||
const Simple = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const Interpolation = styled.div`
|
||||
content: "https://test.com/${props => props.endpoint}";
|
||||
`;
|
||||
|
||||
const SpecialCharacters = styled.div`
|
||||
content: " ${props => props.text} ";\n color: red;
|
||||
`;
|
||||
|
||||
const Comment = styled.div`
|
||||
width: 100%;
|
||||
// comment
|
||||
color: red;
|
||||
`;
|
||||
|
||||
const Parens = styled.div`
|
||||
&:hover {
|
||||
color: blue;
|
||||
}
|
||||
color: red;
|
||||
`;
|
||||
|
||||
const UrlComments = styled.div`
|
||||
color: red;
|
||||
/* // */
|
||||
background: red;
|
||||
/* comment 1 */
|
||||
/* comment 2 */
|
||||
// comment 3
|
||||
border: 1px solid green;
|
||||
`;
|
|
@ -0,0 +1,7 @@
|
|||
import styled from 'styled-components';
|
||||
const Simple = styled.div`width:100%;`;
|
||||
const Interpolation = styled.div`content:"https://test.com/${props => props.endpoint}";`;
|
||||
const SpecialCharacters = styled.div`content:" ${props => props.text} ";color:red;`;
|
||||
const Comment = styled.div`width:100%;color:red;`;
|
||||
const Parens = styled.div`&:hover{color:blue;}color:red;`;
|
||||
const UrlComments = styled.div`color:red;background:red;border:1px solid green;`;
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"minify": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import styled from 'styled-components'
|
||||
|
||||
const Test1 = styled.div`
|
||||
width: 100%;
|
||||
// color: ${'red'};
|
||||
`
|
||||
|
||||
const Test2 = styled.div`
|
||||
width: 100%;
|
||||
// color: pale${'red'};
|
||||
`
|
||||
|
||||
const Test3 = styled.div`
|
||||
width: 100%;
|
||||
// color
|
||||
${'red'};
|
||||
`
|
||||
|
||||
const Test4 = styled.div`
|
||||
width: 100%;
|
||||
// color: ${'red'}-blue;
|
||||
`
|
||||
|
||||
const Test5 = styled.div`
|
||||
width: 100%;
|
||||
// color: ${'red'}${'blue'};
|
||||
`
|
||||
|
||||
const Test6 = styled.div`
|
||||
background: url("https://google.com");
|
||||
width: 100%;
|
||||
${'green'} // color: ${'red'}${'blue'};
|
||||
`
|
||||
|
||||
const Test7 = styled.div`
|
||||
background: url("https://google.com");
|
||||
width: ${p => p.props.width};
|
||||
${'green'} // color: ${'red'}${'blue'};
|
||||
height: ${p => p.props.height};
|
||||
`
|
|
@ -0,0 +1,29 @@
|
|||
import styled from 'styled-components';
|
||||
const Test1 = styled.div.withConfig({
|
||||
displayName: "code__Test1",
|
||||
componentId: "sc-kc0mjf-0"
|
||||
})(["width:100%;"]);
|
||||
const Test2 = styled.div.withConfig({
|
||||
displayName: "code__Test2",
|
||||
componentId: "sc-kc0mjf-1"
|
||||
})(["width:100%;"]);
|
||||
const Test3 = styled.div.withConfig({
|
||||
displayName: "code__Test3",
|
||||
componentId: "sc-kc0mjf-2"
|
||||
})(["width:100%;", ";"], 'red');
|
||||
const Test4 = styled.div.withConfig({
|
||||
displayName: "code__Test4",
|
||||
componentId: "sc-kc0mjf-3"
|
||||
})(["width:100%;"]);
|
||||
const Test5 = styled.div.withConfig({
|
||||
displayName: "code__Test5",
|
||||
componentId: "sc-kc0mjf-4"
|
||||
})(["width:100%;"]);
|
||||
const Test6 = styled.div.withConfig({
|
||||
displayName: "code__Test6",
|
||||
componentId: "sc-kc0mjf-5"
|
||||
})(["background:url(\"https://google.com\");width:100%;", " "], 'green');
|
||||
const Test7 = styled.div.withConfig({
|
||||
displayName: "code__Test7",
|
||||
componentId: "sc-kc0mjf-6"
|
||||
})(["background:url(\"https://google.com\");width:", ";", " height:", ";"], p => p.props.width, 'green', p => p.props.height);
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"plugins": [
|
||||
["@babel/plugin-transform-modules-commonjs"],
|
||||
[
|
||||
"../../../src"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import React from "react";
|
||||
import { css } from "styled-components";
|
||||
import Icons from "./icons";
|
||||
|
||||
const someCss = css` background: purple;`;
|
||||
|
||||
const App1 = () => { return <Icons css={someCss} />; };
|
||||
|
||||
const App2 = () => { return <Icons.Foo css={someCss} />; };
|
||||
|
||||
const App3 = () => { return <Icons.Foo.Bar css={someCss} />; };
|
|
@ -0,0 +1,42 @@
|
|||
"use strict";
|
||||
|
||||
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
||||
|
||||
var _react = _interopRequireDefault(require("react"));
|
||||
|
||||
var _icons = _interopRequireDefault(require("./icons"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
const someCss = (0, _styledComponents.css)([" background:purple;"]);
|
||||
|
||||
const App1 = () => {
|
||||
return <_StyledIcons />;
|
||||
};
|
||||
|
||||
const App2 = () => {
|
||||
return <_StyledIconsFoo />;
|
||||
};
|
||||
|
||||
const App3 = () => {
|
||||
return <_StyledIconsFooBar />;
|
||||
};
|
||||
|
||||
var _StyledIcons = (0, _styledComponents.default)(_icons.default).withConfig({
|
||||
displayName: "code___StyledIcons",
|
||||
componentId: "sc-1wxehft-0"
|
||||
})(["", ""], someCss);
|
||||
|
||||
var _StyledIconsFoo = (0, _styledComponents.default)(_icons.default.Foo).withConfig({
|
||||
displayName: "code___StyledIconsFoo",
|
||||
componentId: "sc-1wxehft-1"
|
||||
})(["", ""], someCss);
|
||||
|
||||
var _StyledIconsFooBar = (0, _styledComponents.default)(_icons.default.Foo.Bar).withConfig({
|
||||
displayName: "code___StyledIconsFooBar",
|
||||
componentId: "sc-1wxehft-2"
|
||||
})(["", ""], someCss);
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"presets": ["@babel/preset-env"],
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"ssr": false,
|
||||
"displayName": true,
|
||||
"transpileTemplateLiterals": true,
|
||||
"minify": false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import styled, { css, createGlobalStyle } from 'styled-components'
|
||||
|
||||
const Named = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
const NamedWithInterpolation = styled.div`
|
||||
color: ${color => props.color};
|
||||
`
|
||||
|
||||
const Wrapped = styled(Inner)`
|
||||
color: red;
|
||||
`
|
||||
|
||||
const Foo = styled.div({
|
||||
color: 'green',
|
||||
})
|
||||
|
||||
const style = css`
|
||||
background: green;
|
||||
`
|
||||
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
html {
|
||||
background: silver;
|
||||
}
|
||||
`
|
|
@ -0,0 +1,32 @@
|
|||
"use strict";
|
||||
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
||||
|
||||
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
||||
|
||||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
||||
|
||||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||||
|
||||
var Named = _styledComponents["default"].div.withConfig({
|
||||
displayName: "code__Named"
|
||||
})(["\n width: 100%;\n"]);
|
||||
|
||||
var NamedWithInterpolation = _styledComponents["default"].div.withConfig({
|
||||
displayName: "code__NamedWithInterpolation"
|
||||
})(["\n color: ", ";\n"], function (color) {
|
||||
return props.color;
|
||||
});
|
||||
|
||||
var Wrapped = (0, _styledComponents["default"])(Inner).withConfig({
|
||||
displayName: "code__Wrapped"
|
||||
})(["\n color: red;\n"]);
|
||||
|
||||
var Foo = _styledComponents["default"].div.withConfig({
|
||||
displayName: "code__Foo"
|
||||
})({
|
||||
color: 'green'
|
||||
});
|
||||
|
||||
var style = (0, _styledComponents.css)(["\n background: green;\n"]);
|
||||
var GlobalStyle = (0, _styledComponents.createGlobalStyle)(["\n html {\n background: silver;\n }\n"]);
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"presets": [
|
||||
"@babel/preset-env"
|
||||
],
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"ssr": false,
|
||||
"displayName": false,
|
||||
"transpileTemplateLiterals": true,
|
||||
"minify": false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import styled from 'styled-components';
|
||||
|
||||
const Named = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const NamedWithInterpolation = styled.div`
|
||||
color: ${color => props.color};
|
||||
`;
|
||||
|
||||
const Wrapped = styled(Inner)`color: red;`;
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
var Named = _styledComponents["default"].div(["\n width: 100%;\n"]);
|
||||
|
||||
var NamedWithInterpolation = _styledComponents["default"].div(["\n color: ", ";\n"], function (color) {
|
||||
return props.color;
|
||||
});
|
||||
|
||||
var Wrapped = (0, _styledComponents["default"])(Inner)(["color: red;"]);
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"../../../src",
|
||||
{
|
||||
"transpileTemplateLiterals": false,
|
||||
"ssr": true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
const Test = s.div`width: 100%;`;
|
||||
import { default as s, css } from 'styled-components';
|
|
@ -0,0 +1,5 @@
|
|||
const Test = s.div.withConfig({
|
||||
displayName: "code__Test",
|
||||
componentId: "sc-1dds9bl-0"
|
||||
})`width:100%;`;
|
||||
import { default as s, css } from 'styled-components';
|
15
packages/next-swc/crates/styled_components/tests/fixtures/add-display-names/code.js
vendored
Normal file
15
packages/next-swc/crates/styled_components/tests/fixtures/add-display-names/code.js
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
import styled from 'styled-components'
|
||||
|
||||
const Test = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
const Test2 = styled('div')``
|
||||
const Test3 = true ? styled.div`` : styled.div``
|
||||
const styles = { One: styled.div`` }
|
||||
let Component
|
||||
Component = styled.div``
|
||||
const WrappedComponent = styled(Inner)``
|
||||
class ClassComponent {
|
||||
static Child = styled.div``
|
||||
}
|
||||
var GoodName = BadName = styled.div``;
|
5
packages/next-swc/crates/styled_components/tests/fixtures/add-display-names/config.json
vendored
Normal file
5
packages/next-swc/crates/styled_components/tests/fixtures/add-display-names/config.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"ssr": false,
|
||||
"fileName": false,
|
||||
"transpileTemplateLiterals": false
|
||||
}
|
34
packages/next-swc/crates/styled_components/tests/fixtures/add-display-names/output.js
vendored
Normal file
34
packages/next-swc/crates/styled_components/tests/fixtures/add-display-names/output.js
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
import styled from 'styled-components';
|
||||
const Test = styled.div.withConfig({
|
||||
displayName: "Test"
|
||||
})`
|
||||
width: 100%;
|
||||
`;
|
||||
const Test2 = styled('div').withConfig({
|
||||
displayName: "Test2"
|
||||
})``;
|
||||
const Test3 = true ? styled.div.withConfig({
|
||||
displayName: "Test3"
|
||||
})`` : styled.div.withConfig({
|
||||
displayName: "Test3"
|
||||
})``;
|
||||
const styles = {
|
||||
One: styled.div.withConfig({
|
||||
displayName: "One"
|
||||
})``
|
||||
};
|
||||
let Component;
|
||||
Component = styled.div.withConfig({
|
||||
displayName: "Component"
|
||||
})``;
|
||||
const WrappedComponent = styled(Inner).withConfig({
|
||||
displayName: "WrappedComponent"
|
||||
})``;
|
||||
class ClassComponent {
|
||||
static Child = styled.div.withConfig({
|
||||
displayName: "Child"
|
||||
})``;
|
||||
}
|
||||
var GoodName = BadName = styled.div.withConfig({
|
||||
displayName: "GoodName"
|
||||
})``;
|
|
@ -0,0 +1,30 @@
|
|||
import styled from 'styled-components'
|
||||
|
||||
const Test = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
const Test2 = true ? styled.div`` : styled.div``
|
||||
const styles = { One: styled.div`` }
|
||||
let Component
|
||||
Component = styled.div``
|
||||
const WrappedComponent = styled(Inner)``
|
||||
const WrappedComponent2 = styled.div({})
|
||||
const WrappedComponent3 = styled(Inner)({})
|
||||
const WrappedComponent4 = styled(Inner).attrs(() => ({ something: 'else' }))({})
|
||||
const WrappedComponent5 = styled.div.attrs(() => ({ something: 'else' }))({})
|
||||
const WrappedComponent6 = styled.div.attrs(() => ({ something: 'else' }))``
|
||||
const WrappedComponent7 = styled.div.withConfig({
|
||||
shouldForwardProp: () => {},
|
||||
})({})
|
||||
|
||||
const WrappedComponent8 = styled.div
|
||||
.withConfig({
|
||||
shouldForwardProp: () => {},
|
||||
})
|
||||
.attrs(() => ({ something: 'else' }))({})
|
||||
|
||||
const WrappedComponent9 = styled.div
|
||||
.attrs(() => ({ something: 'else' }))
|
||||
.withConfig({
|
||||
shouldForwardProp: () => {},
|
||||
})({})
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"fileName": false,
|
||||
"transpileTemplateLiterals": false,
|
||||
"ssr": true
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import styled from 'styled-components';
|
||||
const Test = styled.div.withConfig({
|
||||
displayName: "Test",
|
||||
componentId: "sc-e0d5b7ad-0"
|
||||
})`
|
||||
width: 100%;
|
||||
`;
|
||||
const Test2 = true ? styled.div.withConfig({
|
||||
displayName: "Test2",
|
||||
componentId: "sc-e0d5b7ad-1"
|
||||
})`` : styled.div.withConfig({
|
||||
displayName: "Test2",
|
||||
componentId: "sc-e0d5b7ad-2"
|
||||
})``;
|
||||
const styles = {
|
||||
One: styled.div.withConfig({
|
||||
displayName: "One",
|
||||
componentId: "sc-e0d5b7ad-3"
|
||||
})``
|
||||
};
|
||||
let Component;
|
||||
Component = styled.div.withConfig({
|
||||
displayName: "Component",
|
||||
componentId: "sc-e0d5b7ad-4"
|
||||
})``;
|
||||
const WrappedComponent = styled(Inner).withConfig({
|
||||
displayName: "WrappedComponent",
|
||||
componentId: "sc-e0d5b7ad-5"
|
||||
})``;
|
||||
const WrappedComponent2 = styled.div.withConfig({
|
||||
displayName: "WrappedComponent2",
|
||||
componentId: "sc-e0d5b7ad-6"
|
||||
})({});
|
||||
const WrappedComponent3 = styled(Inner).withConfig({
|
||||
displayName: "WrappedComponent3",
|
||||
componentId: "sc-e0d5b7ad-7"
|
||||
})({});
|
||||
const WrappedComponent4 = styled(Inner).attrs(()=>({
|
||||
something: 'else'
|
||||
})
|
||||
)({});
|
||||
const WrappedComponent5 = styled.div.attrs(()=>({
|
||||
something: 'else'
|
||||
})
|
||||
)({});
|
||||
const WrappedComponent6 = styled.div.attrs(()=>({
|
||||
something: 'else'
|
||||
})
|
||||
).withConfig({
|
||||
displayName: "WrappedComponent6",
|
||||
componentId: "sc-e0d5b7ad-8"
|
||||
})``;
|
||||
const WrappedComponent7 = styled.div.withConfig({
|
||||
shouldForwardProp: ()=>{},
|
||||
displayName: "WrappedComponent7",
|
||||
componentId: "sc-e0d5b7ad-9"
|
||||
})({});
|
||||
const WrappedComponent8 = styled.div.withConfig({
|
||||
shouldForwardProp: ()=>{}
|
||||
}).attrs(()=>({
|
||||
something: 'else'
|
||||
})
|
||||
)({});
|
||||
const WrappedComponent9 = styled.div.attrs(()=>({
|
||||
something: 'else'
|
||||
})
|
||||
).withConfig({
|
||||
shouldForwardProp: ()=>{},
|
||||
displayName: "WrappedComponent9",
|
||||
componentId: "sc-e0d5b7ad-10"
|
||||
})({});
|
|
@ -0,0 +1,10 @@
|
|||
import { styled } from '@example/example'
|
||||
|
||||
const Test = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
const Test2 = true ? styled.div`` : styled.div``
|
||||
const styles = { One: styled.div`` }
|
||||
let Component
|
||||
Component = styled.div``
|
||||
const WrappedComponent = styled(Inner)``
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"displayName": true,
|
||||
"fileName": false,
|
||||
"ssr": true,
|
||||
"topLevelImportPaths": ["@example/example"],
|
||||
"transpileTemplateLiterals": false
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import { styled } from '@example/example';
|
||||
const Test = styled.div.withConfig({
|
||||
displayName: "Test",
|
||||
componentId: "sc-bd3b1624-0"
|
||||
})`
|
||||
width: 100%;
|
||||
`;
|
||||
const Test2 = true ? styled.div.withConfig({
|
||||
displayName: "Test2",
|
||||
componentId: "sc-bd3b1624-1"
|
||||
})`` : styled.div.withConfig({
|
||||
displayName: "Test2",
|
||||
componentId: "sc-bd3b1624-2"
|
||||
})``;
|
||||
const styles = {
|
||||
One: styled.div.withConfig({
|
||||
displayName: "One",
|
||||
componentId: "sc-bd3b1624-3"
|
||||
})``
|
||||
};
|
||||
let Component;
|
||||
Component = styled.div.withConfig({
|
||||
displayName: "Component",
|
||||
componentId: "sc-bd3b1624-4"
|
||||
})``;
|
||||
const WrappedComponent = styled(Inner).withConfig({
|
||||
displayName: "WrappedComponent",
|
||||
componentId: "sc-bd3b1624-5"
|
||||
})``;
|
|
@ -0,0 +1,10 @@
|
|||
import styled from '@xstyled/styled-components'
|
||||
|
||||
const Test = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
const Test2 = true ? styled.div`` : styled.div``
|
||||
const styles = { One: styled.div`` }
|
||||
let Component
|
||||
Component = styled.div``
|
||||
const WrappedComponent = styled(Inner)``
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"displayName": false,
|
||||
"fileName": false,
|
||||
"ssr": true,
|
||||
"topLevelImportPaths": [
|
||||
"@xstyled/styled-components",
|
||||
"@xstyled/styled-components/no-tags",
|
||||
"@xstyled/styled-components/native",
|
||||
"@xstyled/styled-components/primitives"
|
||||
],
|
||||
"transpileTemplateLiterals": false
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import styled from '@xstyled/styled-components';
|
||||
const Test = styled.div.withConfig({
|
||||
componentId: "sc-2fd35b87-0"
|
||||
})`
|
||||
width: 100%;
|
||||
`;
|
||||
const Test2 = true ? styled.div.withConfig({
|
||||
componentId: "sc-2fd35b87-1"
|
||||
})`` : styled.div.withConfig({
|
||||
componentId: "sc-2fd35b87-2"
|
||||
})``;
|
||||
const styles = {
|
||||
One: styled.div.withConfig({
|
||||
componentId: "sc-2fd35b87-3"
|
||||
})``
|
||||
};
|
||||
let Component;
|
||||
Component = styled.div.withConfig({
|
||||
componentId: "sc-2fd35b87-4"
|
||||
})``;
|
||||
const WrappedComponent = styled(Inner).withConfig({
|
||||
componentId: "sc-2fd35b87-5"
|
||||
})``;
|
10
packages/next-swc/crates/styled_components/tests/fixtures/add-identifier/code.js
vendored
Normal file
10
packages/next-swc/crates/styled_components/tests/fixtures/add-identifier/code.js
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
import styled from 'styled-components'
|
||||
|
||||
const Test = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
const Test2 = true ? styled.div`` : styled.div``
|
||||
const styles = { One: styled.div`` }
|
||||
let Component
|
||||
Component = styled.div``
|
||||
const WrappedComponent = styled(Inner)``
|
6
packages/next-swc/crates/styled_components/tests/fixtures/add-identifier/config.json
vendored
Normal file
6
packages/next-swc/crates/styled_components/tests/fixtures/add-identifier/config.json
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"displayName": false,
|
||||
"fileName": false,
|
||||
"transpileTemplateLiterals": false,
|
||||
"ssr": true
|
||||
}
|
23
packages/next-swc/crates/styled_components/tests/fixtures/add-identifier/output.js
vendored
Normal file
23
packages/next-swc/crates/styled_components/tests/fixtures/add-identifier/output.js
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
import styled from 'styled-components';
|
||||
const Test = styled.div.withConfig({
|
||||
componentId: "sc-bc9ba4b0-0"
|
||||
})`
|
||||
width: 100%;
|
||||
`;
|
||||
const Test2 = true ? styled.div.withConfig({
|
||||
componentId: "sc-bc9ba4b0-1"
|
||||
})`` : styled.div.withConfig({
|
||||
componentId: "sc-bc9ba4b0-2"
|
||||
})``;
|
||||
const styles = {
|
||||
One: styled.div.withConfig({
|
||||
componentId: "sc-bc9ba4b0-3"
|
||||
})``
|
||||
};
|
||||
let Component;
|
||||
Component = styled.div.withConfig({
|
||||
componentId: "sc-bc9ba4b0-4"
|
||||
})``;
|
||||
const WrappedComponent = styled(Inner).withConfig({
|
||||
componentId: "sc-bc9ba4b0-5"
|
||||
})``;
|
|
@ -0,0 +1,7 @@
|
|||
const domElements = ['div']
|
||||
|
||||
const styled = () => {}
|
||||
|
||||
domElements.forEach(domElement => {
|
||||
styled[domElement] = styled(domElement)
|
||||
})
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue