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:
Donny/강동윤 2022-04-11 18:59:16 +09:00 committed by GitHub
parent 01109734ce
commit 16f7084e7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
265 changed files with 4467 additions and 317 deletions

View file

@ -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",

View file

@ -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"

View file

@ -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()),
})

View file

@ -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,

View file

@ -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");

View file

@ -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,
);
}

View file

@ -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 {

View 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"

View file

@ -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)
);
}
}

View file

@ -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;

View 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,
);
}

View 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"

View 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,
);
}

View file

@ -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"

View file

@ -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);
}

View 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"

View file

@ -0,0 +1 @@

View 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()
)
}

View 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());
}
}
}
}
}
}

View 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())
})
}

View file

@ -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)
}
}
}
}
}
}
}

View file

@ -0,0 +1,4 @@
pub mod assign_style_required;
pub mod display_name_and_id;
pub mod minify;
pub mod transpile_css_prop;

View file

@ -0,0 +1,2 @@
mod top_level_binding_collector;
pub mod transpile;

View file

@ -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
}

View file

@ -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,
}
}

View 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"),
)
}

View file

@ -0,0 +1,12 @@
{
"plugins": [
[
"../../../src",
{
"ssr": false,
"fileName": false,
"transpileTemplateLiterals": false
}
]
]
}

View file

@ -0,0 +1,4 @@
import styled from 'styled-components'
const WithAttrs = styled.div.attrs({ some: 'value' })``
const WithAttrsWrapped = styled(Inner).attrs({ some: 'value' })``

View file

@ -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"
})``;

View file

@ -0,0 +1,10 @@
{
"plugins": [
[
"../../../src",
{
"pure": true
}
]
]
}

View file

@ -0,0 +1,7 @@
import { createGlobalStyle } from 'styled-components'
const GlobalStyle = createGlobalStyle`
body {
color: red;
}
`

View file

@ -0,0 +1,2 @@
import { createGlobalStyle } from 'styled-components';
const GlobalStyle = /*#__PURE__*/createGlobalStyle(["body{color:red;}"]);

View file

@ -0,0 +1,10 @@
{
"plugins": [
[
"../../../src",
{
"pure": true
}
]
]
}

View file

@ -0,0 +1,10 @@
import styled, { css } from 'styled-components'
const partial = css`
color: red;
`
const Component = styled.div`
${partial};
background: blue;
`

View file

@ -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);

View file

@ -0,0 +1,10 @@
{
"plugins": [
[
"../../../src",
{
"pure": true
}
]
]
}

View file

@ -0,0 +1,11 @@
import { keyframes } from 'styled-components'
const Animation = keyframes`
0% {
opacity: 0;
}
100% {
opacity: 1;
}
`

View file

@ -0,0 +1,2 @@
import { keyframes } from 'styled-components';
const Animation = /*#__PURE__*/keyframes(["0%{opacity:0;}100%{opacity:1;}"]);

View file

@ -0,0 +1,10 @@
{
"plugins": [
[
"../../../src",
{
"pure": true
}
]
]
}

View file

@ -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)

View file

@ -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);

View file

@ -0,0 +1,10 @@
{
"plugins": [
[
"../../../src",
{
"pure": true
}
]
]
}

View file

@ -0,0 +1,3 @@
import { withTheme } from 'styled-components'
const ThemedComponent = withTheme(() => null)

View file

@ -0,0 +1,2 @@
import { withTheme } from 'styled-components';
const ThemedComponent = /*#__PURE__*/withTheme(() => null);

View file

@ -0,0 +1,7 @@
{
"plugins": [
[
"../../../src"
]
]
}

View 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;
`

View file

@ -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);

View file

@ -0,0 +1,12 @@
{
"plugins": [
[
"../../../src",
{
"ssr": false,
"displayName": false,
"transpileTemplateLiterals": false
}
]
]
}

View 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;
}
`

View 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;}`;

View file

@ -0,0 +1,15 @@
{
"presets": [
"@babel/preset-env"
],
"plugins": [
[
"../../../src",
{
"ssr": false,
"displayName": false,
"transpileTemplateLiterals": false
}
]
]
}

View file

@ -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;
}
`;

View file

@ -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;}"])));

View file

@ -0,0 +1,12 @@
{
"plugins": [
[
"../../../src",
{
"ssr": false,
"displayName": false,
"transpileTemplateLiterals": false
}
]
]
}

View file

@ -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;
`;

View file

@ -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;`;

View file

@ -0,0 +1,10 @@
{
"plugins": [
[
"../../../src",
{
"minify": true
}
]
]
}

View file

@ -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};
`

View file

@ -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);

View file

@ -0,0 +1,8 @@
{
"plugins": [
["@babel/plugin-transform-modules-commonjs"],
[
"../../../src"
]
]
}

View file

@ -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} />; };

View file

@ -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);

View file

@ -0,0 +1,14 @@
{
"presets": ["@babel/preset-env"],
"plugins": [
[
"../../../src",
{
"ssr": false,
"displayName": true,
"transpileTemplateLiterals": true,
"minify": false
}
]
]
}

View file

@ -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;
}
`

View file

@ -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"]);

View file

@ -0,0 +1,16 @@
{
"presets": [
"@babel/preset-env"
],
"plugins": [
[
"../../../src",
{
"ssr": false,
"displayName": false,
"transpileTemplateLiterals": true,
"minify": false
}
]
]
}

View file

@ -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;`;

View file

@ -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;"]);

View file

@ -0,0 +1,11 @@
{
"plugins": [
[
"../../../src",
{
"transpileTemplateLiterals": false,
"ssr": true
}
]
]
}

View file

@ -0,0 +1,2 @@
const Test = s.div`width: 100%;`;
import { default as s, css } from 'styled-components';

View file

@ -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';

View 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``;

View file

@ -0,0 +1,5 @@
{
"ssr": false,
"fileName": false,
"transpileTemplateLiterals": false
}

View 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"
})``;

View file

@ -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: () => {},
})({})

View file

@ -0,0 +1,5 @@
{
"fileName": false,
"transpileTemplateLiterals": false,
"ssr": true
}

View file

@ -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"
})({});

View file

@ -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)``

View file

@ -0,0 +1,7 @@
{
"displayName": true,
"fileName": false,
"ssr": true,
"topLevelImportPaths": ["@example/example"],
"transpileTemplateLiterals": false
}

View file

@ -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"
})``;

View file

@ -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)``

View file

@ -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
}

View file

@ -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"
})``;

View 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)``

View file

@ -0,0 +1,6 @@
{
"displayName": false,
"fileName": false,
"transpileTemplateLiterals": false,
"ssr": true
}

View 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"
})``;

View file

@ -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