diff --git a/.flowconfig b/.flowconfig index 61557139c3d..053b3172d1d 100644 --- a/.flowconfig +++ b/.flowconfig @@ -36,4 +36,4 @@ untyped-import untyped-type-import [version] -0.173.0 +0.174.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 92dbcf0f606..d1f0b398684 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,32 @@ All notable changes to Parcel will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and Parcel adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [2.4.0] - 2022-03-22 + +## Added + +- Replace default CSS transformer and minifier with `@parcel/css` - [Details](https://github.com/parcel-bundler/parcel/pull/7821) +- Replace `typeof` before dead code elimination to improve bundle size - [Details](https://github.com/parcel-bundler/parcel/pull/7788) +- Human readable file size in bundle analyzer report - [Details](https://github.com/parcel-bundler/parcel/pull/7766) +- Improve emoji support detection - [Details](https://github.com/parcel-bundler/parcel/pull/7775) +- Enable parsing static class initialization blocks - [Details](https://github.com/parcel-bundler/parcel/pull/7839) +- Use `PORT` environment variable from `.env` files - [Details](https://github.com/parcel-bundler/parcel/pull/7819) +- Use new react-jsx transform in React 16.14.0 - [Details](https://github.com/parcel-bundler/parcel/pull/7728) +- Use relative path for bundle labels in bundle analysis - [Details](https://github.com/parcel-bundler/parcel/pull/7737) +- Load dynamic imports at higher network priority in non-ESM builds - [Details](https://github.com/parcel-bundler/parcel/pull/7061) + +## Fixed + +- Pin lmdb to 2.2.3 - [Details](https://github.com/parcel-bundler/parcel/pull/7763) +- Prevent term-size from being bundled - [Details](https://github.com/parcel-bundler/parcel/pull/7750) +- Fix cache when non-ascii chars are used in path - [Details](https://github.com/parcel-bundler/parcel/pull/7797) +- Bump SWC. Fixes issue with `String` constructor. - [Details](https://github.com/parcel-bundler/parcel/pull/7777) +- Fix DCE with PURE comments - [Details](https://github.com/parcel-bundler/parcel/pull/7833) +- Escape double quote of url value in CSS `url()` - [Details](https://github.com/parcel-bundler/parcel/pull/7718) +- Fix documentation comment in API - [Details](https://github.com/parcel-bundler/parcel/pull/7689) +- Fix package.json `source` field resolution with pnpm - [Details](https://github.com/parcel-bundler/parcel/pull/7846) +- Fix `errors.map is not a function` - [Details](https://github.com/parcel-bundler/parcel/pull/7672) + ## [2.3.1] - 2022-02-09 ## Fixed diff --git a/Cargo.lock b/Cargo.lock index 15b049bdb7e..67391037b49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.5", "once_cell", "serde", "version_check", @@ -56,9 +56,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.52" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" [[package]] name = "arrayvec" @@ -66,11 +66,17 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "ast_node" -version = "0.7.4" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96d5444b02f3080edac8a144f6baf29b2fb6ff589ad4311559731a7c7529381" +checksum = "bc4c00309ed1c8104732df4a5fa9acc3b796b6f8531dfbd5ce0078c86f997244" dependencies = [ "darling", "pmutil", @@ -93,9 +99,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" @@ -109,6 +115,15 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "better_scoped_tls" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73e8ecdec39e98aa3b19e8cd0b8ed8f77ccb86a6b0b2dc7cd86d105438a2123" +dependencies = [ + "scoped-tls", +] + [[package]] name = "bit-vec" version = "0.6.3" @@ -130,11 +145,20 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + [[package]] name = "browserslist-rs" -version = "0.6.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31071741816efb54c473a6480724b2d31ed44eb460382d37f60cf4655fbe80a6" +checksum = "a0f43be8e0fc9203f6ed7731d2a9a6bf5924cb78907e67e1fe9133617be402be" dependencies = [ "ahash", "anyhow", @@ -162,15 +186,15 @@ checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7" [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "bytemuck" -version = "1.7.3" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" +checksum = "0e851ca7c24871e7336801608a4797d7376545b6928a10d32d75685687141ead" [[package]] name = "byteorder" @@ -180,9 +204,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.72" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" dependencies = [ "jobserver", ] @@ -297,18 +321,18 @@ checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" [[package]] name = "crc32fast" -version = "1.3.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "fdbfe11fe19ff083c48923cf179540e8cd0535903dc35e178a1fdeeb59aef51f" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -327,10 +351,11 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" dependencies = [ + "autocfg", "cfg-if 1.0.0", "crossbeam-utils", "lazy_static", @@ -340,14 +365,24 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ "cfg-if 1.0.0", "lazy_static", ] +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "darling" version = "0.10.2" @@ -393,6 +428,17 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "dashmap" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c" +dependencies = [ + "cfg-if 1.0.0", + "num_cpus", + "parking_lot 0.12.0", +] + [[package]] name = "data-encoding" version = "2.3.2" @@ -427,6 +473,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", +] + [[package]] name = "dunce" version = "1.0.2" @@ -459,7 +515,7 @@ checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.10", + "redox_syscall 0.2.11", "winapi", ] @@ -499,9 +555,9 @@ checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -520,9 +576,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" dependencies = [ "cfg-if 1.0.0", "libc", @@ -590,9 +646,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg", "hashbrown", @@ -601,9 +657,9 @@ dependencies = [ [[package]] name = "indoc" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a75aeaaef0ce18b58056d306c27b07436fbb34b8816c53094b76dd81803136" +checksum = "e7906a9fababaeacb774f72410e497a1d18de916322e33797bb2cd29baa23c9e" dependencies = [ "unindent", ] @@ -619,9 +675,9 @@ dependencies = [ [[package]] name = "is-macro" -version = "0.1.9" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a322dd16d960e322c3d92f541b4c1a4f0a2e81e1fdeee430d8cecc8b72e8015f" +checksum = "94b2c46692aee0d1b3aad44e781ac0f0e7db42ef27adaa0a877b627040019813" dependencies = [ "Inflector", "pmutil", @@ -692,65 +748,115 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "lexical" -version = "5.2.2" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f404a90a744e32e8be729034fc33b90cf2a56418fbf594d69aa3c0214ad414e5" +checksum = "ccd3e434c16f0164124ade12dcdee324fcc3dafb1cad0c7f1d8c2451a1aa6886" dependencies = [ - "cfg-if 1.0.0", "lexical-core", ] [[package]] name = "lexical-core" -version = "0.7.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +checksum = "92912c4af2e7d9075be3e5e3122c4d7263855fa6cce34fbece4dd08e5884624d" dependencies = [ - "arrayvec", - "bitflags", - "cfg-if 1.0.0", - "ryu", + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", +] + +[[package]] +name = "lexical-parse-float" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f518eed87c3be6debe6d26b855c97358d8a11bf05acec137e5f53080f5ad2dd8" +dependencies = [ + "lexical-parse-integer", + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-parse-integer" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc852ec67c6538bbb2b9911116a385b24510e879a69ab516e6a151b15a79168" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-util" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c72a9d52c5c4e62fa2cdc2cb6c694a39ae1382d9c2a17a466f18e272a0930eb1" +dependencies = [ + "static_assertions", +] + +[[package]] +name = "lexical-write-float" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a89ec1d062e481210c309b672f73a0567b7855f21e7d2fae636df44d12e97f9" +dependencies = [ + "lexical-util", + "lexical-write-integer", + "static_assertions", +] + +[[package]] +name = "lexical-write-integer" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "094060bd2a7c2ff3a16d5304a6ae82727cb3cc9d1c70f813cc73f744c319337e" +dependencies = [ + "lexical-util", "static_assertions", ] [[package]] name = "libc" -version = "0.2.112" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" [[package]] name = "libdeflate-sys" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ce0b849741cecad96125e51124570c46741f50db12007224295b63e221f0034" +checksum = "4cceaf6e335d658ec0602685bfe50d0f35248d6d8848b194058bfda37a9eb728" dependencies = [ "cc", ] [[package]] name = "libdeflater" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32b70f071880dd130e410be35f8017892837913374a311e277219d3ead3ab18" +checksum = "15f0c115fd181333eb7a82cf42e2ce2d9fac0ad06babd3ab79a9ec5bd66352fe" dependencies = [ "libdeflate-sys", ] [[package]] name = "libmimalloc-sys" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9636c194f9db483f4d0adf2f99a65011a99f904bd222bbd67fb4df4f37863c30" +checksum = "7705fc40f6ed493f73584abbb324e74f96b358ff60dfe5659a0f8fc12c590a69" dependencies = [ "cc", ] [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" dependencies = [ "scopeguard", ] @@ -787,9 +893,9 @@ dependencies = [ [[package]] name = "mimalloc" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf5f78c1d9892fb5677a8b2f543f967ab891ac0f71feecd961435b74f877283a" +checksum = "b0dfa131390c2f6bdb3242f65ff271fcdaca5ff7b6c08f28398be7f2280e3926" dependencies = [ "libmimalloc-sys", ] @@ -867,9 +973,9 @@ checksum = "67cf20e0081fea04e044aa4adf74cfea8ddc0324eec2894b1c700f4cafc72a56" [[package]] name = "nasm-rs" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06380d23b58dcdaf892fa36c3950cad3110e7d76851275d5f85c22eb9cdd614" +checksum = "ce095842aee9aa3ecbda7a5d2a4df680375fd128a8596b6b56f8e497e231f483" dependencies = [ "rayon", ] @@ -882,13 +988,12 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[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]] @@ -902,9 +1007,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.2.6" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg", "num-integer", @@ -965,9 +1070,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "opaque-debug" @@ -977,22 +1082,13 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "ordered-float" -version = "2.8.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97c9d06878b3a851e8026ef94bf7fef9ba93062cd412601da4d9cf369b1cc62d" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" dependencies = [ "num-traits", ] -[[package]] -name = "owning_ref" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "oxipng" version = "5.0.1" @@ -1063,7 +1159,7 @@ dependencies = [ "pathdiff", "serde", "serde_bytes", - "sha-1", + "sha-1 0.9.8", "swc_atoms", "swc_common", "swc_ecmascript", @@ -1087,7 +1183,7 @@ version = "0.1.0" dependencies = [ "js-sys", "parcel-js-swc-core", - "parking_lot_core", + "parking_lot_core 0.8.0", "serde", "serde-wasm-bindgen", "wasm-bindgen", @@ -1101,7 +1197,17 @@ checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" dependencies = [ "instant", "lock_api", - "parking_lot_core", + "parking_lot_core 0.8.0", +] + +[[package]] +name = "parking_lot" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.1", ] [[package]] @@ -1119,6 +1225,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "parking_lot_core" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.11", + "smallvec", + "windows-sys", +] + [[package]] name = "path-clean" version = "0.1.0" @@ -1145,12 +1264,12 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "phf" -version = "0.8.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ "phf_macros", - "phf_shared", + "phf_shared 0.10.0", "proc-macro-hack", ] @@ -1160,18 +1279,28 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ - "phf_shared", - "rand", + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", "proc-macro-hack", "proc-macro2", "quote", @@ -1187,11 +1316,20 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pmutil" @@ -1218,9 +1356,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "precomputed-hash" @@ -1228,6 +1366,23 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "preset_env_base" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e44b8d534a4ecea4519138ff80780a499691c4e948bc063651487e069966a703" +dependencies = [ + "ahash", + "anyhow", + "browserslist-rs", + "dashmap 4.0.2", + "from_variant", + "once_cell", + "semver 1.0.6", + "serde", + "st-map", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -1245,9 +1400,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -1260,12 +1415,23 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom 0.1.16", "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.2.2", + "rand_core 0.5.1", "rand_hc", "rand_pcg", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -1273,7 +1439,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", ] [[package]] @@ -1285,13 +1461,22 @@ dependencies = [ "getrandom 0.1.16", ] +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.5", +] + [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -1300,7 +1485,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -1336,18 +1521,18 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", @@ -1360,17 +1545,11 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" -[[package]] -name = "retain_mut" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11000e6ba5020e53e7cc26f73b91ae7d5496b4977851479edb66b694c0675c21" - [[package]] name = "rgb" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a374af9a0e5fdcdd98c1c7b64f05004f9ea2555b6c75f211daa81268a3c50f1" +checksum = "e74fdc210d8f24a7dbfedc13b04ba5764f5232754ccebfdf5fff1bad791ccbc6" dependencies = [ "bytemuck", ] @@ -1396,7 +1575,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.4", + "semver 1.0.6", ] [[package]] @@ -1405,15 +1584,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scoped-tls" version = "1.0.0" @@ -1433,14 +1603,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ "semver-parser", - "serde", ] [[package]] name = "semver" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -1450,9 +1622,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] @@ -1480,9 +1652,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -1491,9 +1663,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", @@ -1506,24 +1678,35 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if 1.0.0", "cpufeatures", - "digest", + "digest 0.9.0", "opaque-debug", ] +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.3", +] + [[package]] name = "siphasher" -version = "0.3.7" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "smallvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "sourcemap" @@ -1547,16 +1730,10 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3caeb13a58f859600a7b75fffe66322e1fca0122ca02cfc7262344a7e30502d1" dependencies = [ - "arrayvec", + "arrayvec 0.5.2", "static-map-macro", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - [[package]] name = "static-map-macro" version = "0.2.1" @@ -1590,14 +1767,14 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6" +checksum = "33994d0838dc2d152d17a62adf608a869b5e846b65b389af7f3dbc1de45c5b26" dependencies = [ "lazy_static", "new_debug_unreachable", - "parking_lot", - "phf_shared", + "parking_lot 0.11.1", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -1608,8 +1785,8 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f24c8e5e19d22a726626f1a5e16fe15b132dcf21d10177fa5a45ce7962996b97" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.8.0", + "phf_shared 0.8.0", "proc-macro2", "quote", ] @@ -1649,25 +1826,40 @@ dependencies = [ "string_cache_codegen", ] +[[package]] +name = "swc_cached" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84fed4a980e12c737171a7b17c5e0a2f4272899266fa0632ea4e31264ebdfdb5" +dependencies = [ + "ahash", + "anyhow", + "dashmap 5.2.0", + "once_cell", + "regex", + "serde", + "swc_atoms", +] + [[package]] name = "swc_common" -version = "0.15.1" +version = "0.17.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf33ac965b9ce43b653baa35a5de6ecfd96b9bbab9547a5fb4ce33c46a36fe75" +checksum = "7935aededdf361eb17ba3ddde021ad0df4774c5b5d902e7b0f6faae7c76d748a" dependencies = [ "ahash", "ast_node", "atty", - "cfg-if 0.1.10", + "better_scoped_tls", + "cfg-if 1.0.0", "debug_unreachable", "either", "from_variant", "num-bigint", "once_cell", - "owning_ref", "rustc-hash", - "scoped-tls", "serde", + "siphasher", "sourcemap", "string_cache", "swc_eq_ignore_macros", @@ -1680,9 +1872,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.60.3" +version = "0.71.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ab2356281c38cf629f3cdb165c4d34e17b2757b020dab914bae477ee0fb373" +checksum = "8ae7b943caae6d3fbae0534ce2df9866efa3d0415199ce7d20c6ef7e4e0b233d" dependencies = [ "is-macro", "num-bigint", @@ -1690,33 +1882,33 @@ dependencies = [ "string_enum", "swc_atoms", "swc_common", - "unicode-xid", + "unicode-id", ] [[package]] name = "swc_ecma_codegen" -version = "0.84.1" +version = "0.98.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383ac26d122a9f97a1773ffa6f44366e8ab08ccc14e5698111c698ca17acfa65" +checksum = "ef9691af1a41fbde638594f2b8593560670adab5c2cc0fd3587481040312797d" dependencies = [ "bitflags", "memchr", "num-bigint", "once_cell", + "rustc-hash", "sourcemap", "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_codegen_macros", - "swc_ecma_parser", "tracing", ] [[package]] name = "swc_ecma_codegen_macros" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdbf826c739281cdb3b3c23883fd1a7586ea1c15b1287530e7123a7fad8f0e25" +checksum = "59949619b2ef45eedb6c399d05f2c3c7bc678b5074b3103bb670f9e05bb99042" dependencies = [ "pmutil", "proc-macro2", @@ -1727,28 +1919,27 @@ dependencies = [ [[package]] name = "swc_ecma_loader" -version = "0.25.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645b674e9f537053026670985486004a47c3c168a71de8de0c0d57c2f2cb61f8" +checksum = "f9ab69df5d4de425833e02de111f14b5544b39ad9c9b82c97e4835fc55c8f1b6" dependencies = [ "ahash", "anyhow", - "dashmap", + "dashmap 4.0.2", "normpath", "once_cell", "path-clean", "serde", "serde_json", - "swc_atoms", "swc_common", "tracing", ] [[package]] name = "swc_ecma_parser" -version = "0.82.6" +version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b0455e02c59d53891422593b2e0aaf06548873a1c319ddcf3e9a741d34ce41d" +checksum = "6bbca18d756dddd0a87e101dd07157cd466a22787e9b5447ab85da2faa352bd8" dependencies = [ "either", "enum_kind", @@ -1761,22 +1952,22 @@ dependencies = [ "swc_ecma_ast", "tracing", "typed-arena 2.0.1", - "unicode-xid", + "unicode-id", ] [[package]] name = "swc_ecma_preset_env" -version = "0.76.2" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4ce83d144d995a8362cea85fe7c6adaa728fbe4a8bad05d05f8d3d2b27e37b" +checksum = "13d8929f9552fd9c324a8b22765dfa50b789f0e0069757f3480ececfb11b5136" dependencies = [ "ahash", "anyhow", - "browserslist-rs", - "dashmap", + "dashmap 5.2.0", "indexmap", "once_cell", - "semver 0.9.0", + "preset_env_base", + "semver 1.0.6", "serde", "serde_json", "st-map", @@ -1787,19 +1978,17 @@ dependencies = [ "swc_ecma_transforms", "swc_ecma_utils", "swc_ecma_visit", - "walkdir", ] [[package]] name = "swc_ecma_transforms" -version = "0.103.8" +version = "0.135.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e5d7bbc83aca7b172f18fe1ad713a58490f7420bd4831481e18a3d86e0199f" +checksum = "7e19aa898a63dbee9ae4abb505716bc146c55d6ad9e627d617b16bfc827dd36f" dependencies = [ "swc_atoms", "swc_common", "swc_ecma_ast", - "swc_ecma_parser", "swc_ecma_transforms_base", "swc_ecma_transforms_compat", "swc_ecma_transforms_module", @@ -1809,18 +1998,18 @@ dependencies = [ "swc_ecma_transforms_typescript", "swc_ecma_utils", "swc_ecma_visit", - "unicode-xid", ] [[package]] name = "swc_ecma_transforms_base" -version = "0.49.2" +version = "0.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f401256219e566fc92f637182d20eb04de8cd1bb650dd72d3e0e81851a5367b" +checksum = "0e0e50e1414e15cc7b909fb8c79c8b2d9988b83aabe8114fa09a730123c2558c" dependencies = [ + "better_scoped_tls", "once_cell", "phf", - "scoped-tls", + "serde", "smallvec", "swc_atoms", "swc_common", @@ -1833,9 +2022,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.36.1" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd400da7c4b061a95c38f98d7a72f12c7cf7d49fee33e5bb5ca577e19a344b52" +checksum = "3c16df5d4468e8f54b89eccf0876337c4c672b6434092ec83e71e7c678d1fdd3" dependencies = [ "swc_atoms", "swc_common", @@ -1847,12 +2036,12 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.59.10" +version = "0.83.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d76ac375527f495b5b095e7e32d43e47b57113abe72b75306dcd58b4d15fbde" +checksum = "12cb92c67a689037b6320bb2e0a421b5c74bfd297f59cfd7c71c0128ff23de02" dependencies = [ "ahash", - "arrayvec", + "arrayvec 0.7.2", "indexmap", "is-macro", "num-bigint", @@ -1867,6 +2056,7 @@ dependencies = [ "swc_ecma_transforms_macros", "swc_ecma_utils", "swc_ecma_visit", + "swc_trace_macro", "tracing", ] @@ -1885,9 +2075,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "0.65.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "701c941a6ba8d4e396a3e63031a9d4ee4807dc91b29c30069e88c0276a44a01e" +checksum = "a40c273cd4344955105824da8de90e0dfb4e41f4059c3a9accc0292b6b2590b6" dependencies = [ "Inflector", "ahash", @@ -1896,6 +2086,7 @@ dependencies = [ "pathdiff", "serde", "swc_atoms", + "swc_cached", "swc_common", "swc_ecma_ast", "swc_ecma_loader", @@ -1903,19 +2094,19 @@ dependencies = [ "swc_ecma_transforms_base", "swc_ecma_utils", "swc_ecma_visit", + "tracing", ] [[package]] name = "swc_ecma_transforms_optimization" -version = "0.73.1" +version = "0.105.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37dddf3630b5c60aa4d05e3486099eec7195d96ec17895fa58753d383935b09c" +checksum = "1b4c4832545ccd8a62050629f0bea25a8968af107149d01bf60e5b87c9305136" dependencies = [ "ahash", - "dashmap", + "dashmap 5.2.0", "indexmap", "once_cell", - "retain_mut", "serde_json", "swc_atoms", "swc_common", @@ -1930,9 +2121,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.65.2" +version = "0.91.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1493c6460a5009cff53e5adaac7e2090bde73be9dccb92b01fe132c190824b2" +checksum = "2d5ff5321ecdd0a3e620878e02452a6475b9ffdcaf75a2cf9636c2d31bb85fe0" dependencies = [ "either", "serde", @@ -1940,7 +2131,6 @@ dependencies = [ "swc_atoms", "swc_common", "swc_ecma_ast", - "swc_ecma_parser", "swc_ecma_transforms_base", "swc_ecma_transforms_classes", "swc_ecma_transforms_macros", @@ -1950,18 +2140,18 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.67.1" +version = "0.97.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12a9c3ed9ff2c30faba6851d9287a2b21a9efdc0f4aba234980f8c57028bf2ea" +checksum = "3fbf0ee845da10a4018e7c5c5258de5a0b4289fd5e0b4f2d640858fd29c2afe9" dependencies = [ "ahash", "base64 0.13.0", - "dashmap", + "dashmap 5.2.0", "indexmap", "once_cell", "regex", "serde", - "sha-1", + "sha-1 0.10.0", "string_enum", "swc_atoms", "swc_common", @@ -1975,15 +2165,14 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "0.69.1" +version = "0.100.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d48c902c53d5118ecfa5eb8346d78a9d51f062da425bf03bfc101205b390f6" +checksum = "5c553fe85a8bcb0fcc6c8929770d556d567991f8061f7a47dc6e962b6b87dbf9" dependencies = [ "serde", "swc_atoms", "swc_common", "swc_ecma_ast", - "swc_ecma_parser", "swc_ecma_transforms_base", "swc_ecma_transforms_react", "swc_ecma_utils", @@ -1992,24 +2181,24 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.56.2" +version = "0.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a3cb85935a25f5a78bdcf8252a0423eeb3aa3d027c16d2ae425454e0ab2a4c2" +checksum = "daa3ba57f53fc15882d2ea288f9a4b6c3a6e97c015d7b9603035be424bc19007" dependencies = [ + "indexmap", "once_cell", "swc_atoms", "swc_common", "swc_ecma_ast", "swc_ecma_visit", "tracing", - "unicode-xid", ] [[package]] name = "swc_ecma_visit" -version = "0.46.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c03856f785763e50019ebd70281e9490c5b019f93cfc1dda180d49e30fcb4c" +checksum = "7588bf6b02705a25356a130acdfec125b6a1dcd5390a5718082ae4f2ede85ee3" dependencies = [ "num-bigint", "swc_atoms", @@ -2021,9 +2210,9 @@ dependencies = [ [[package]] name = "swc_ecmascript" -version = "0.99.9" +version = "0.136.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f0c9a2b6acfa0fff19ba80a6bff86240417bd9b1a168af97c3591eea99555" +checksum = "5eb75ac51d44c811e4527ce30873a8ef1bd8f2435e33ec6a5dc62936dbfdc451" dependencies = [ "swc_ecma_ast", "swc_ecma_codegen", @@ -2058,6 +2247,17 @@ dependencies = [ "syn", ] +[[package]] +name = "swc_trace_macro" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d1a05fdb40442d687cb2eff4e5c374886a66ced1436ad87515de7d72b3ec10b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "swc_visit" version = "0.3.0" @@ -2070,9 +2270,9 @@ dependencies = [ [[package]] name = "swc_visit_macros" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e505bbf8e11898fa05a65aa5e773c827ec743fc15aa3c064c9e06164ed0b6630" +checksum = "c3b9b72892df873972549838bf84d6c56234c7502148a7e23b5a3da6e0fedfb8" dependencies = [ "Inflector", "pmutil", @@ -2095,9 +2295,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ "winapi-util", ] @@ -2167,9 +2367,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tracing" -version = "0.1.29" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "4a1bdf54a7c28a2bbf701e1d2233f6c77f473486b94bee4f9678da5a148dca7f" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -2179,9 +2379,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.18" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +checksum = "2e65ce065b4b5c53e73bb28912318cb8c9e9ad3921f1d669eb0e68b4c8143a2b" dependencies = [ "proc-macro2", "quote", @@ -2190,9 +2390,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +checksum = "aa31669fa42c09c34d94d8165dd2012e8ff3c66aca50f3bb226b68f216f2706c" dependencies = [ "lazy_static", ] @@ -2221,6 +2421,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +[[package]] +name = "unicode-id" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4285d92be83dfbc8950a2601178b89ed36f979ebf51bfcf7b272b17001184e6c" + [[package]] name = "unicode-normalization" version = "0.1.19" @@ -2244,9 +2450,9 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "unindent" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" +checksum = "514672a55d7380da379785a4d70ca8386c8883ff7eaae877be4d2081cebe73d8" [[package]] name = "unreachable" @@ -2277,9 +2483,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "void" @@ -2287,17 +2493,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -2406,11 +2601,54 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" + +[[package]] +name = "windows_i686_gnu" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" + +[[package]] +name = "windows_i686_msvc" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" + [[package]] name = "xxhash-rust" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575e15bedf6e57b5c2d763ffc6c3c760143466cbd09d762d539680ab5992ded" +checksum = "83a16b7b403377d61184bb601d8349a4ff2c4cec08a305d004f710b7eaafef24" [[package]] name = "zopfli" diff --git a/package.json b/package.json index d5f53b4c6dd..283cef976fd 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "@types/node": "^15.12.4", "cross-env": "^7.0.0", "eslint": "^7.20.0", - "flow-bin": "0.173.0", + "flow-bin": "0.174.1", "glob": "^7.1.6", "gulp": "^4.0.2", "gulp-babel": "^8.0.0", diff --git a/packages/configs/default/index.json b/packages/configs/default/index.json index bda82bd3089..e6d9a21e2a9 100644 --- a/packages/configs/default/index.json +++ b/packages/configs/default/index.json @@ -53,7 +53,7 @@ ], "optimizers": { "data-url:*": ["...", "@parcel/optimizer-data-url"], - "*.css": ["@parcel/optimizer-cssnano"], + "*.css": ["@parcel/optimizer-css"], "*.{html,xhtml}": ["@parcel/optimizer-htmlnano"], "*.{js,mjs,cjs}": ["@parcel/optimizer-terser"], "*.svg": ["@parcel/optimizer-svgo"], diff --git a/packages/configs/default/package.json b/packages/configs/default/package.json index 88e663d1842..839601e9aea 100644 --- a/packages/configs/default/package.json +++ b/packages/configs/default/package.json @@ -21,7 +21,7 @@ "@parcel/bundler-default": "2.0.20", "@parcel/compressor-raw": "2.0.20", "@parcel/namer-default": "2.0.20", - "@parcel/optimizer-cssnano": "2.0.20", + "@parcel/optimizer-css": "2.0.20", "@parcel/optimizer-htmlnano": "2.0.20", "@parcel/optimizer-image": "2.0.20", "@parcel/optimizer-svgo": "2.0.20", @@ -50,31 +50,31 @@ "@parcel/transformer-svg": "2.0.20" }, "parcelDependencies": { - "@parcel/optimizer-data-url": "2.0.7", - "@parcel/packager-raw-url": "2.0.7", - "@parcel/packager-ts": "2.0.7", - "@parcel/packager-xml": "2.0.10", - "@parcel/transformer-coffeescript": "2.0.7", - "@parcel/transformer-elm": "2.0.7", - "@parcel/transformer-glsl": "2.0.7", - "@parcel/transformer-graphql": "2.0.7", - "@parcel/transformer-inline-string": "2.0.7", - "@parcel/transformer-jsonld": "2.0.7", - "@parcel/transformer-less": "2.0.7", - "@parcel/transformer-mdx": "2.0.7", - "@parcel/transformer-pug": "2.0.7", - "@parcel/transformer-sass": "2.0.7", - "@parcel/transformer-stylus": "2.0.7", - "@parcel/transformer-sugarss": "2.0.7", - "@parcel/transformer-toml": "2.0.7", - "@parcel/transformer-typescript-types": "2.0.7", - "@parcel/transformer-vue": "2.0.7", - "@parcel/transformer-webmanifest": "2.0.7", - "@parcel/transformer-worklet": "2.0.7", - "@parcel/transformer-xml": "2.0.10", - "@parcel/transformer-yaml": "2.0.7" + "@parcel/optimizer-data-url": "2.0.20", + "@parcel/packager-raw-url": "2.0.20", + "@parcel/packager-ts": "2.0.20", + "@parcel/packager-xml": "2.0.20", + "@parcel/transformer-coffeescript": "2.0.20", + "@parcel/transformer-elm": "2.0.20", + "@parcel/transformer-glsl": "2.0.20", + "@parcel/transformer-graphql": "2.0.20", + "@parcel/transformer-inline-string": "2.0.20", + "@parcel/transformer-jsonld": "2.0.20", + "@parcel/transformer-less": "2.0.20", + "@parcel/transformer-mdx": "2.0.20", + "@parcel/transformer-pug": "2.0.20", + "@parcel/transformer-sass": "2.0.20", + "@parcel/transformer-stylus": "2.0.20", + "@parcel/transformer-sugarss": "2.0.20", + "@parcel/transformer-toml": "2.0.20", + "@parcel/transformer-typescript-types": "2.0.20", + "@parcel/transformer-vue": "2.0.20", + "@parcel/transformer-webmanifest": "2.0.20", + "@parcel/transformer-worklet": "2.0.20", + "@parcel/transformer-xml": "2.0.20", + "@parcel/transformer-yaml": "2.0.20" }, "peerDependencies": { - "@parcel/core": "^2.3.2" + "@parcel/core": "^2.0.20" } } diff --git a/packages/core/core/src/AssetGraph.js b/packages/core/core/src/AssetGraph.js index f62b980968e..b0bea578f2c 100644 --- a/packages/core/core/src/AssetGraph.js +++ b/packages/core/core/src/AssetGraph.js @@ -542,11 +542,7 @@ export default class AssetGraph extends ContentGraph { } getIncomingDependencies(asset: Asset): Array { - let nodeId = this._contentKeyToNodeId.get(asset.id); - if (!nodeId) { - return []; - } - + let nodeId = this.getNodeIdByContentKey(asset.id); let assetGroupIds = this.getNodeIdsConnectedTo(nodeId); let dependencies = []; for (let i = 0; i < assetGroupIds.length; i++) { diff --git a/packages/core/core/src/resolveOptions.js b/packages/core/core/src/resolveOptions.js index e8c5104425b..9c1d6f15010 100644 --- a/packages/core/core/src/resolveOptions.js +++ b/packages/core/core/src/resolveOptions.js @@ -4,6 +4,7 @@ import type { FilePath, InitialParcelOptions, DependencySpecifier, + InitialServerOptions, } from '@parcel/types'; import type {FileSystem} from '@parcel/fs'; import type {ParcelOptions} from './types'; @@ -95,6 +96,19 @@ export default async function resolveOptions( throw new Error('Lazy bundling does not work with content hashing'); } + let env = { + ...(await loadDotEnv( + initialOptions.env ?? {}, + inputFS, + path.join(projectRoot, 'index'), + projectRoot, + )), + ...process.env, + ...initialOptions.env, + }; + + let port = determinePort(initialOptions.serveOptions, env.PORT); + return { config: getRelativeConfigSpecifier( inputFS, @@ -107,16 +121,7 @@ export default async function resolveOptions( initialOptions.defaultConfig, ), shouldPatchConsole: initialOptions.shouldPatchConsole ?? false, - env: { - ...(await loadDotEnv( - initialOptions.env ?? {}, - inputFS, - path.join(projectRoot, 'index'), - projectRoot, - )), - ...process.env, - ...initialOptions.env, - }, + env, mode, shouldAutoInstall: initialOptions.shouldAutoInstall ?? false, hmrOptions: initialOptions.hmrOptions ?? null, @@ -128,6 +133,7 @@ export default async function resolveOptions( ? { ...initialOptions.serveOptions, distDir: distDir ?? path.join(outputCwd, 'dist'), + port, } : false, shouldDisableCache: initialOptions.shouldDisableCache ?? false, @@ -180,3 +186,34 @@ function getRelativeConfigSpecifier( return specifier; } } + +function determinePort( + initialServerOptions: InitialServerOptions | false | void, + portInEnv: string | void, + defaultPort: number = 1234, +): number { + function parsePort(port: string): number | void { + let parsedPort = Number(port); + + // return undefined if port number defined in .env is not valid integer + if (!Number.isInteger(parsedPort)) { + return undefined; + } + return parsedPort; + } + + if (!initialServerOptions) { + return typeof portInEnv !== 'undefined' + ? parsePort(portInEnv) ?? defaultPort + : defaultPort; + } + + // if initialServerOptions.port is equal to defaultPort, then this means that port number is provided via PORT=~~~~ on cli. In this case, we should ignore port number defined in .env. + if (initialServerOptions.port !== defaultPort) { + return initialServerOptions.port; + } + + return typeof portInEnv !== 'undefined' + ? parsePort(portInEnv) ?? defaultPort + : defaultPort; +} diff --git a/packages/core/integration-tests/test/css-modules.js b/packages/core/integration-tests/test/css-modules.js index de7a660b36d..f591e517873 100644 --- a/packages/core/integration-tests/test/css-modules.js +++ b/packages/core/integration-tests/test/css-modules.js @@ -1,7 +1,7 @@ import assert from 'assert'; import path from 'path'; import { - bundle as originalBundle, + bundle, run, assertBundles, distDir, @@ -10,486 +10,442 @@ import { import postcss from 'postcss'; describe('css modules', () => { - for (let name of ['old', 'new']) { - describe(name, () => { - let bundle = (entries, opts = {}) => { - if (name === 'new') { - // $FlowFixMe - opts.defaultConfig = - path.dirname(require.resolve('@parcel/test-utils')) + - '/.parcelrc-css'; - } - return originalBundle(entries, opts); - }; - - it('should support transforming css modules (require)', async () => { - let b = await bundle( - path.join(__dirname, '/integration/postcss-modules-cjs/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'foo.module.css'], - }, - { - name: 'index.css', - assets: ['index.css', 'foo.module.css'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - - let value = output(); - assert(/foo_[0-9a-zA-Z]/.test(value)); - - let cssClass = value.match(/(foo_[0-9a-zA-Z])/)[1]; - - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - assert(css.includes(`.${cssClass}`)); - }); - - it('should support transforming css modules (import default)', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/postcss-modules-import-default/index.js', - ), - {mode: 'production'}, - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'style.module.css'], - }, - { - name: 'index.css', - assets: ['style.module.css'], - }, - ]); - - let output = await run(b); - assert(/b-2_[0-9a-zA-Z]/.test(output)); - - let css = await outputFS.readFile( - b.getBundles().find(b => b.type === 'css').filePath, - 'utf8', - ); - let includedRules = new Set(); - postcss.parse(css).walkRules(rule => { - includedRules.add(rule.selector); - }); - assert(includedRules.has('.page')); - assert(includedRules.has(`.${output}`)); - }); - - it('should tree shake unused css modules classes with a namespace import', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/postcss-modules-import-namespace/index.js', - ), - {mode: 'production'}, - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'style.module.css'], - }, - { - name: 'index.css', - assets: ['global.css', 'style.module.css'], - }, - ]); - - let js = await outputFS.readFile( - b.getBundles().find(b => b.type === 'js').filePath, - 'utf8', - ); - assert(!js.includes('unused')); - - let output = await run(b); - assert(/b-2_[0-9a-zA-Z]/.test(output)); - - let css = await outputFS.readFile( - b.getBundles().find(b => b.type === 'css').filePath, - 'utf8', - ); - let includedRules = new Set(); - postcss.parse(css).walkRules(rule => { - includedRules.add(rule.selector); - }); - assert.deepStrictEqual( - includedRules, - new Set(['body', `.${output}`, '.page']), - ); - }); - - it('should produce correct css without symbol propagation for css modules classes with a namespace import', async () => { - let b = await bundle( + it('should support transforming css modules (require)', async () => { + let b = await bundle( + path.join(__dirname, '/integration/postcss-modules-cjs/index.js'), + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'foo.module.css'], + }, + { + name: 'index.css', + assets: ['index.css', 'foo.module.css'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + + let value = output(); + assert(/foo_[0-9a-zA-Z]/.test(value)); + + let cssClass = value.match(/(foo_[0-9a-zA-Z])/)[1]; + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + assert(css.includes(`.${cssClass}`)); + }); + + it('should support transforming css modules (import default)', async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/postcss-modules-import-default/index.js', + ), + {mode: 'production'}, + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'style.module.css'], + }, + { + name: 'index.css', + assets: ['style.module.css'], + }, + ]); + + let output = await run(b); + assert(/b-2_[0-9a-zA-Z]/.test(output)); + + let css = await outputFS.readFile( + b.getBundles().find(b => b.type === 'css').filePath, + 'utf8', + ); + let includedRules = new Set(); + postcss.parse(css).walkRules(rule => { + includedRules.add(rule.selector); + }); + assert(includedRules.has('.page')); + assert(includedRules.has(`.${output}`)); + }); + + it('should tree shake unused css modules classes with a namespace import', async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/postcss-modules-import-namespace/index.js', + ), + {mode: 'production'}, + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'style.module.css'], + }, + { + name: 'index.css', + assets: ['global.css', 'style.module.css'], + }, + ]); + + let js = await outputFS.readFile( + b.getBundles().find(b => b.type === 'js').filePath, + 'utf8', + ); + assert(!js.includes('unused')); + + let output = await run(b); + assert(/b-2_[0-9a-zA-Z]/.test(output)); + + let css = await outputFS.readFile( + b.getBundles().find(b => b.type === 'css').filePath, + 'utf8', + ); + let includedRules = new Set(); + postcss.parse(css).walkRules(rule => { + includedRules.add(rule.selector); + }); + assert.deepStrictEqual( + includedRules, + new Set(['body', `.${output}`, '.page']), + ); + }); + + it('should produce correct css without symbol propagation for css modules classes with a namespace import', async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/postcss-modules-import-namespace/index.js', + ), + { + mode: 'production', + defaultTargetOptions: { + shouldScopeHoist: false, + }, + }, + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'style.module.css'], + }, + { + name: 'index.css', + assets: ['global.css', 'style.module.css'], + }, + ]); + + let {output} = await run(b, null, {require: false}); + assert(/b-2_[0-9a-zA-Z]/.test(output)); + + let css = await outputFS.readFile( + b.getBundles().find(b => b.type === 'css').filePath, + 'utf8', + ); + let includedRules = new Set(); + postcss.parse(css).walkRules(rule => { + includedRules.add(rule.selector); + }); + assert(includedRules.has('body')); + assert(includedRules.has(`.${output}`)); + assert(includedRules.has('.page')); + }); + + it('should support importing css modules with a non-static namespace import', async () => { + let b = await bundle( + path.join( + __dirname, + '/integration/postcss-modules-import-namespace-whole/index.js', + ), + {mode: 'production'}, + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'style.module.css'], + }, + { + name: 'index.css', + assets: ['global.css', 'style.module.css'], + }, + ]); + + let js = await outputFS.readFile( + b.getBundles().find(b => b.type === 'js').filePath, + 'utf8', + ); + assert(js.includes('unused')); + + let output = await run(b); + assert(/b-2_[0-9a-zA-Z]/.test(output['b-2'])); + assert(/unused_[0-9a-zA-Z]/.test(output['unused'])); + + let css = await outputFS.readFile( + b.getBundles().find(b => b.type === 'css').filePath, + 'utf8', + ); + let includedRules = new Set(); + postcss.parse(css).walkRules(rule => { + includedRules.add(rule.selector); + }); + assert.deepStrictEqual( + includedRules, + new Set(['body', `.${output['b-2']}`, `.${output['unused']}`, '.page']), + ); + }); + + it('should support css modules composes imports', async () => { + let b = await bundle( + path.join(__dirname, '/integration/postcss-composes/index.js'), + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'index.js', + 'composes-1.module.css', + 'composes-2.module.css', + 'mixins.module.css', + ], + }, + { + name: 'index.css', + assets: [ + 'composes-1.module.css', + 'composes-2.module.css', + 'mixins.module.css', + ], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + + let value = output(); + const composes1Classes = value.composes1.split(' '); + const composes2Classes = value.composes2.split(' '); + assert(composes1Classes[0].startsWith('composes1_')); + assert(composes1Classes[1].startsWith('test_')); + assert(composes2Classes[0].startsWith('composes2_')); + assert(composes2Classes[1].startsWith('test_')); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + let cssClass1 = value.composes1.match(/(composes1_[0-9a-zA-Z]+)/)[1]; + assert(css.includes(`.${cssClass1}`)); + let cssClass2 = value.composes2.match(/(composes2_[0-9a-zA-Z]+)/)[1]; + assert(css.includes(`.${cssClass2}`)); + }); + + it('should not include css twice for composes imports', async () => { + let b = await bundle( + path.join(__dirname, '/integration/postcss-composes/index.js'), + ); + + await run(b); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + assert.equal( + css.indexOf('height: 100px;'), + css.lastIndexOf('height: 100px;'), + ); + }); + + it('should support composes imports for sass', async () => { + let b = await bundle( + path.join(__dirname, '/integration/postcss-composes/index2.js'), + ); + + assertBundles(b, [ + { + name: 'index2.js', + assets: ['index2.js', 'composes-3.module.css', 'mixins.module.scss'], + }, + { + name: 'index2.css', + assets: ['composes-3.module.css', 'mixins.module.scss'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + + let value = output(); + const composes3Classes = value.composes3.split(' '); + assert(composes3Classes[0].startsWith('composes3_')); + assert(composes3Classes[1].startsWith('test_')); + + let css = await outputFS.readFile(path.join(distDir, 'index2.css'), 'utf8'); + assert(css.includes('height: 200px;')); + }); + + it('should support composes imports with custom path names', async () => { + let b = await bundle( + path.join(__dirname, '/integration/postcss-composes/index3.js'), + ); + + assertBundles(b, [ + { + name: 'index3.js', + assets: ['index3.js', 'composes-4.module.css', 'mixins.module.css'], + }, + { + name: 'index3.css', + assets: ['composes-4.module.css', 'mixins.module.css'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + + let value = output(); + const composes4Classes = value.composes4.split(' '); + assert(composes4Classes[0].startsWith('composes4_')); + assert(composes4Classes[1].startsWith('test_')); + + let css = await outputFS.readFile(path.join(distDir, 'index3.css'), 'utf8'); + assert(css.includes('height: 100px;')); + }); + + it('should support deep nested composes imports', async () => { + let b = await bundle( + path.join(__dirname, '/integration/postcss-composes/index4.js'), + ); + + assertBundles(b, [ + { + name: 'index4.js', + assets: [ + 'index4.js', + 'composes-5.module.css', + 'mixins-intermediate.module.css', + 'mixins.module.css', + ], + }, + { + name: 'index4.css', + assets: [ + 'composes-5.module.css', + 'mixins-intermediate.module.css', + 'mixins.module.css', + ], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + + let value = output(); + const composes5Classes = value.composes5.split(' '); + assert(composes5Classes[0].startsWith('composes5_')); + assert(composes5Classes[1].startsWith('intermediate_')); + assert(composes5Classes[2].startsWith('test_')); + + let css = await outputFS.readFile(path.join(distDir, 'index4.css'), 'utf8'); + assert(css.includes('height: 100px;')); + assert(css.includes('height: 300px;')); + assert(css.indexOf('.test_') < css.indexOf('.intermediate_')); + }); + + it('should support composes imports for multiple selectors', async () => { + let b = await bundle( + path.join(__dirname, '/integration/postcss-composes/index5.js'), + ); + + assertBundles(b, [ + { + name: 'index5.js', + assets: ['index5.js', 'composes-6.module.css', 'mixins.module.css'], + }, + { + name: 'index5.css', + assets: ['composes-6.module.css', 'mixins.module.css'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + + let value = output(); + const composes6Classes = value.composes6.split(' '); + assert(composes6Classes[0].startsWith('composes6_')); + assert(composes6Classes[1].startsWith('test_')); + assert(composes6Classes[2].startsWith('test-2_')); + }); + + it('should throw an error when importing a missing class', async function () { + await assert.rejects( + () => + bundle( path.join( __dirname, - '/integration/postcss-modules-import-namespace/index.js', + '/integration/no-export-error-with-correct-filetype/src/App.jsx', ), { - mode: 'production', + shouldDisableCache: true, defaultTargetOptions: { - shouldScopeHoist: false, + shouldScopeHoist: true, }, }, - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'style.module.css'], - }, - { - name: 'index.css', - assets: ['global.css', 'style.module.css'], - }, - ]); - - let {output} = await run(b, null, {require: false}); - assert(/b-2_[0-9a-zA-Z]/.test(output)); - - let css = await outputFS.readFile( - b.getBundles().find(b => b.type === 'css').filePath, - 'utf8', - ); - let includedRules = new Set(); - postcss.parse(css).walkRules(rule => { - includedRules.add(rule.selector); - }); - assert(includedRules.has('body')); - assert(includedRules.has(`.${output}`)); - assert(includedRules.has('.page')); - }); - - it('should support importing css modules with a non-static namespace import', async () => { - let b = await bundle( - path.join( - __dirname, - '/integration/postcss-modules-import-namespace-whole/index.js', - ), - {mode: 'production'}, - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'style.module.css'], - }, - { - name: 'index.css', - assets: ['global.css', 'style.module.css'], - }, - ]); - - let js = await outputFS.readFile( - b.getBundles().find(b => b.type === 'js').filePath, - 'utf8', - ); - assert(js.includes('unused')); - - let output = await run(b); - assert(/b-2_[0-9a-zA-Z]/.test(output['b-2'])); - assert(/unused_[0-9a-zA-Z]/.test(output['unused'])); - - let css = await outputFS.readFile( - b.getBundles().find(b => b.type === 'css').filePath, - 'utf8', - ); - let includedRules = new Set(); - postcss.parse(css).walkRules(rule => { - includedRules.add(rule.selector); - }); - assert.deepStrictEqual( - includedRules, - new Set([ - 'body', - `.${output['b-2']}`, - `.${output['unused']}`, - '.page', - ]), - ); - }); - - it('should support css modules composes imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/postcss-composes/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'index.js', - 'composes-1.module.css', - 'composes-2.module.css', - 'mixins.module.css', - ], - }, - { - name: 'index.css', - assets: [ - 'composes-1.module.css', - 'composes-2.module.css', - 'mixins.module.css', - ], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - - let value = output(); - const composes1Classes = value.composes1.split(' '); - const composes2Classes = value.composes2.split(' '); - assert(composes1Classes[0].startsWith('composes1_')); - assert(composes1Classes[1].startsWith('test_')); - assert(composes2Classes[0].startsWith('composes2_')); - assert(composes2Classes[1].startsWith('test_')); - - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - let cssClass1 = value.composes1.match(/(composes1_[0-9a-zA-Z]+)/)[1]; - assert(css.includes(`.${cssClass1}`)); - let cssClass2 = value.composes2.match(/(composes2_[0-9a-zA-Z]+)/)[1]; - assert(css.includes(`.${cssClass2}`)); - }); - - it('should not include css twice for composes imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/postcss-composes/index.js'), - ); - - await run(b); - - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - assert.equal( - css.indexOf('height: 100px;'), - css.lastIndexOf('height: 100px;'), - ); - }); - - it('should support composes imports for sass', async () => { - let b = await bundle( - path.join(__dirname, '/integration/postcss-composes/index2.js'), - ); - - assertBundles(b, [ - { - name: 'index2.js', - assets: [ - 'index2.js', - 'composes-3.module.css', - 'mixins.module.scss', - ], - }, - { - name: 'index2.css', - assets: ['composes-3.module.css', 'mixins.module.scss'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - - let value = output(); - const composes3Classes = value.composes3.split(' '); - assert(composes3Classes[0].startsWith('composes3_')); - assert(composes3Classes[1].startsWith('test_')); - - let css = await outputFS.readFile( - path.join(distDir, 'index2.css'), - 'utf8', - ); - assert(css.includes('height: 200px;')); - }); - - it('should support composes imports with custom path names', async () => { - let b = await bundle( - path.join(__dirname, '/integration/postcss-composes/index3.js'), - ); - - assertBundles(b, [ - { - name: 'index3.js', - assets: ['index3.js', 'composes-4.module.css', 'mixins.module.css'], - }, + ), + { + name: 'BuildError', + diagnostics: [ { - name: 'index3.css', - assets: ['composes-4.module.css', 'mixins.module.css'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - - let value = output(); - const composes4Classes = value.composes4.split(' '); - assert(composes4Classes[0].startsWith('composes4_')); - assert(composes4Classes[1].startsWith('test_')); - - let css = await outputFS.readFile( - path.join(distDir, 'index3.css'), - 'utf8', - ); - assert(css.includes('height: 100px;')); - }); - - it('should support deep nested composes imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/postcss-composes/index4.js'), - ); - - assertBundles(b, [ - { - name: 'index4.js', - assets: [ - 'index4.js', - 'composes-5.module.css', - 'mixins-intermediate.module.css', - 'mixins.module.css', - ], - }, - { - name: 'index4.css', - assets: [ - 'composes-5.module.css', - 'mixins-intermediate.module.css', - 'mixins.module.css', - ], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - - let value = output(); - const composes5Classes = value.composes5.split(' '); - assert(composes5Classes[0].startsWith('composes5_')); - assert(composes5Classes[1].startsWith('intermediate_')); - assert(composes5Classes[2].startsWith('test_')); - - let css = await outputFS.readFile( - path.join(distDir, 'index4.css'), - 'utf8', - ); - assert(css.includes('height: 100px;')); - assert(css.includes('height: 300px;')); - assert(css.indexOf('.test_') < css.indexOf('.intermediate_')); - }); - - it('should support composes imports for multiple selectors', async () => { - let b = await bundle( - path.join(__dirname, '/integration/postcss-composes/index5.js'), - ); - - assertBundles(b, [ - { - name: 'index5.js', - assets: ['index5.js', 'composes-6.module.css', 'mixins.module.css'], - }, - { - name: 'index5.css', - assets: ['composes-6.module.css', 'mixins.module.css'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - - let value = output(); - const composes6Classes = value.composes6.split(' '); - assert(composes6Classes[0].startsWith('composes6_')); - assert(composes6Classes[1].startsWith('test_')); - assert(composes6Classes[2].startsWith('test-2_')); - }); - - it('should throw an error when importing a missing class', async function () { - await assert.rejects( - () => - bundle( - path.join( - __dirname, - '/integration/no-export-error-with-correct-filetype/src/App.jsx', - ), + codeFrames: [ { - shouldDisableCache: true, - defaultTargetOptions: { - shouldScopeHoist: true, - }, - }, - ), - { - name: 'BuildError', - diagnostics: [ - { - codeFrames: [ + filePath: path.join( + __dirname, + '/integration/no-export-error-with-correct-filetype/src/App.jsx', + ), + language: 'js', + codeHighlights: [ { - filePath: path.join( - __dirname, - '/integration/no-export-error-with-correct-filetype/src/App.jsx', - ), - language: 'js', - codeHighlights: [ - { - end: { - column: 45, - line: 7, - }, - start: { - column: 28, - line: 7, - }, - }, - ], + end: { + column: 45, + line: 7, + }, + start: { + column: 28, + line: 7, + }, }, ], - message: - "integration/no-export-error-with-correct-filetype/src/app.module.css does not export 'notExisting'", - origin: '@parcel/core', }, ], + message: + "integration/no-export-error-with-correct-filetype/src/app.module.css does not export 'notExisting'", + origin: '@parcel/core', }, - ); - }); - - it('should fall back to postcss for legacy css modules', async function () { - let b = await bundle( - path.join(__dirname, '/integration/css-modules-legacy/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'index.module.css'], - }, - { - name: 'index.css', - assets: ['index.module.css'], - }, - ]); - - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - assert(css.includes('color: red')); - }); - }); - } + ], + }, + ); + }); + + it('should fall back to postcss for legacy css modules', async function () { + let b = await bundle( + path.join(__dirname, '/integration/css-modules-legacy/index.js'), + ); + + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'index.module.css'], + }, + { + name: 'index.css', + assets: ['index.module.css'], + }, + ]); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + assert(css.includes('color: red')); + }); }); diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index 45e575a0874..128a08c1619 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -2,7 +2,7 @@ import assert from 'assert'; import path from 'path'; import { - bundle as originalBundle, + bundle, run, assertBundles, distDir, @@ -16,467 +16,473 @@ describe('css', () => { await removeDistDirectory(); }); - for (let name of ['old', 'new']) { - describe(name, () => { - let bundle = (entries, opts = {}) => { - if (name === 'new') { - // $FlowFixMe - opts.defaultConfig = - path.dirname(require.resolve('@parcel/test-utils')) + - '/.parcelrc-css'; - } - return originalBundle(entries, opts); - }; - - it('should produce two bundles when importing a CSS file', async () => { - let b = await bundle(path.join(__dirname, '/integration/css/index.js')); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js', 'local.js'], - }, - { - name: 'index.css', - assets: ['index.css', 'local.css'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); - }); - - it('should bundle css dependencies in the correct, postorder traversal order', async () => { - let b = await bundle( - path.join(__dirname, '/integration/css-order/a.css'), - ); - - // Given a tree of css with imports: - // A - // / \ - // B E - // / \ - // C D - // - // (A imports B (which imports C and D) and E) - // - // ...styles should be applied in the order C, D, B, E, A - - assertBundles(b, [ - { - name: 'a.css', - assets: ['a.css', 'b.css', 'c.css', 'd.css', 'e.css'], - }, - ]); - - let css = await outputFS.readFile(path.join(distDir, 'a.css'), 'utf8'); - assert.ok( - css.indexOf('.c {') < css.indexOf('.d {') && - css.indexOf('.d {') < css.indexOf('.b {') && - css.indexOf('.b {') < css.indexOf('.e {') && - css.indexOf('.e {') < css.indexOf('.a {'), - ); - }); - - it('should support loading a CSS bundle along side dynamic imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/dynamic-css/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: [ - 'bundle-url.js', - 'cacheLoader.js', - 'css-loader.js', - 'index.js', - 'js-loader.js', - ], - }, - {name: /local\.[0-9a-f]{8}\.js/, assets: ['local.js']}, - {name: /local\.[0-9a-f]{8}\.css/, assets: ['local.css']}, - {name: 'index.css', assets: ['index.css']}, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(await output(), 3); - }); - - it('should support importing CSS from a CSS file', async function () { - let b = await bundle( - path.join(__dirname, '/integration/css-import/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - name: 'index.css', - assets: ['index.css', 'other.css', 'local.css'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 2); - - let css = await outputFS.readFile( - path.join(distDir, '/index.css'), - 'utf8', - ); - assert(css.includes('.local')); - assert(css.includes('.other')); - assert(/@media print {\s*.other/.test(css)); - assert(css.includes('.index')); - }); - - it('should support linking to assets with url() from CSS', async function () { - let b = await bundle( - path.join(__dirname, '/integration/css-url/index.js'), - ); - - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - name: 'index.css', - assets: ['index.css'], - }, - { - type: 'woff2', - assets: ['test.woff2'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 2); - - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - assert(/url\("test\.[0-9a-f]+\.woff2"\)/.test(css)); - assert(css.includes('url("http://google.com")')); - assert(css.includes('.index')); - assert(css.includes('url("data:image/gif;base64,quotes")')); - assert(css.includes('.quotes')); - assert(css.includes('url("data:image/gif;base64,no-quote")')); - assert(css.includes('.no-quote')); - - assert( - await outputFS.exists( - path.join( - distDir, - css.match(/url\("(test\.[0-9a-f]+\.woff2)"\)/)[1], - ), - ), - ); - }); - - it('should support linking to assets with url() from CSS in production', async function () { - let b = await bundle( - path.join(__dirname, '/integration/css-url/index.js'), - { - defaultTargetOptions: { - shouldOptimize: true, - }, - }, - ); + it('should produce two bundles when importing a CSS file', async () => { + let b = await bundle(path.join(__dirname, '/integration/css/index.js')); - assertBundles(b, [ - { - name: 'index.js', - assets: ['index.js'], - }, - { - name: 'index.css', - assets: ['index.css'], - }, - { - type: 'woff2', - assets: ['test.woff2'], - }, - ]); - - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 2); - - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - assert( - /url\(test\.[0-9a-f]+\.woff2\)/.test(css), - 'woff ext found in css', - ); - assert(css.includes('url(http://google.com)'), 'url() found'); - assert(css.includes('.index'), '.index found'); - assert(/url\("?data:image\/gif;base64,quotes"?\)/.test(css)); - assert(css.includes('.quotes')); - assert(/url\("?data:image\/gif;base64,no-quote"?\)/.test(css)); - assert(css.includes('.no-quote')); - - assert( - await outputFS.exists( - path.join(distDir, css.match(/url\((test\.[0-9a-f]+\.woff2)\)/)[1]), - ), - ); - }); - - it('should support linking to assets in parent folders with url() from CSS', async function () { - let b = await bundle( - [ - path.join( - __dirname, - '/integration/css-url-relative/src/a/style1.css', - ), - path.join( - __dirname, - '/integration/css-url-relative/src/b/style2.css', - ), - ], - { - defaultTargetOptions: { - shouldOptimize: true, - sourceMaps: false, - }, - }, - ); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js', 'local.js'], + }, + { + name: 'index.css', + assets: ['index.css', 'local.css'], + }, + ]); - assertBundles(b, [ - { - type: 'css', - assets: ['style1.css'], - }, - { - type: 'css', - assets: ['style2.css'], - }, - { - type: 'png', - assets: ['foo.png'], - }, - ]); + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(output(), 3); + }); + + it('should bundle css dependencies in the correct, postorder traversal order', async () => { + let b = await bundle(path.join(__dirname, '/integration/css-order/a.css')); + + // Given a tree of css with imports: + // A + // / \ + // B E + // / \ + // C D + // + // (A imports B (which imports C and D) and E) + // + // ...styles should be applied in the order C, D, B, E, A + + assertBundles(b, [ + { + name: 'a.css', + assets: ['a.css', 'b.css', 'c.css', 'd.css', 'e.css'], + }, + ]); + + let css = await outputFS.readFile(path.join(distDir, 'a.css'), 'utf8'); + assert.ok( + css.indexOf('.c {') < css.indexOf('.d {') && + css.indexOf('.d {') < css.indexOf('.b {') && + css.indexOf('.b {') < css.indexOf('.e {') && + css.indexOf('.e {') < css.indexOf('.a {'), + ); + }); - let cssPath = path.join(distDir, 'a', 'style1.css'); - let css = await outputFS.readFile(cssPath, 'utf8'); + it('should support loading a CSS bundle along side dynamic imports', async () => { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-css/index.js'), + ); - assert(css.includes('background-image'), 'includes `background-image`'); - assert(/url\([^)]*\)/.test(css), 'includes url()'); + assertBundles(b, [ + { + name: 'index.js', + assets: [ + 'bundle-url.js', + 'cacheLoader.js', + 'css-loader.js', + 'index.js', + 'js-loader.js', + ], + }, + {name: /local\.[0-9a-f]{8}\.js/, assets: ['local.js']}, + {name: /local\.[0-9a-f]{8}\.css/, assets: ['local.css']}, + {name: 'index.css', assets: ['index.css']}, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(await output(), 3); + }); - assert( - await outputFS.exists( - path.resolve(path.dirname(cssPath), css.match(/url\(([^)]*)\)/)[1]), - ), - 'path specified in url() exists', - ); - }); + it('should support importing CSS from a CSS file', async function () { + let b = await bundle( + path.join(__dirname, '/integration/css-import/index.js'), + ); - it('should ignore url() with IE behavior specifiers', async function () { - let b = await bundle( - path.join(__dirname, '/integration/css-url-behavior/index.css'), - ); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + { + name: 'index.css', + assets: ['index.css', 'other.css', 'local.css'], + }, + ]); - assertBundles(b, [ - { - name: 'index.css', - assets: ['index.css'], - }, - ]); + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(output(), 2); - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); + let css = await outputFS.readFile(path.join(distDir, '/index.css'), 'utf8'); + assert(css.includes('.local')); + assert(css.includes('.other')); + assert(/@media print {\s*.other/.test(css)); + assert(css.includes('.index')); + }); - assert(css.includes('url(#default#VML)')); - }); + it('should support linking to assets with url() from CSS', async function () { + let b = await bundle(path.join(__dirname, '/integration/css-url/index.js')); - it('should minify CSS when minify is set', async function () { - let b = await bundle( - path.join(__dirname, '/integration/cssnano/index.js'), - { - defaultTargetOptions: { - shouldOptimize: true, - sourceMaps: false, - }, - }, - ); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + { + name: 'index.css', + assets: ['index.css'], + }, + { + type: 'woff2', + assets: ['test.woff2'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(output(), 2); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + assert(/url\("test\.[0-9a-f]+\.woff2"\)/.test(css)); + assert(css.includes('url("http://google.com")')); + assert(css.includes('.index')); + assert(css.includes('url("data:image/gif;base64,quotes")')); + assert(css.includes('.quotes')); + assert(css.includes('url("data:image/gif;base64,no-quote")')); + assert(css.includes('.no-quote')); + + assert( + await outputFS.exists( + path.join(distDir, css.match(/url\("(test\.[0-9a-f]+\.woff2)"\)/)[1]), + ), + ); + }); - let output = await run(b); - assert.equal(typeof output, 'function'); - assert.equal(output(), 3); + it('should support linking to assets with url() from CSS in production', async function () { + let b = await bundle( + path.join(__dirname, '/integration/css-url/index.js'), + { + defaultTargetOptions: { + shouldOptimize: true, + }, + }, + ); - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - assert(css.includes('.local')); - assert(css.includes('.index')); + assertBundles(b, [ + { + name: 'index.js', + assets: ['index.js'], + }, + { + name: 'index.css', + assets: ['index.css'], + }, + { + type: 'woff2', + assets: ['test.woff2'], + }, + ]); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(output(), 2); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + assert(/url\(test\.[0-9a-f]+\.woff2\)/.test(css), 'woff ext found in css'); + assert(css.includes('url(http://google.com)'), 'url() found'); + assert(css.includes('.index'), '.index found'); + assert(/url\("?data:image\/gif;base64,quotes"?\)/.test(css)); + assert(css.includes('.quotes')); + assert(/url\("?data:image\/gif;base64,no-quote"?\)/.test(css)); + assert(css.includes('.no-quote')); + + assert( + await outputFS.exists( + path.join(distDir, css.match(/url\((test\.[0-9a-f]+\.woff2)\)/)[1]), + ), + ); + }); - assert.equal(css.split('\n').length, 1); - }); + it('should support linking to assets in parent folders with url() from CSS', async function () { + let b = await bundle( + [ + path.join(__dirname, '/integration/css-url-relative/src/a/style1.css'), + path.join(__dirname, '/integration/css-url-relative/src/b/style2.css'), + ], + { + defaultTargetOptions: { + shouldOptimize: true, + sourceMaps: false, + }, + }, + ); - it('should produce a sourcemap when sourceMaps are used', async function () { - await bundle(path.join(__dirname, '/integration/cssnano/index.js'), { + assertBundles(b, [ + { + type: 'css', + assets: ['style1.css'], + }, + { + type: 'css', + assets: ['style2.css'], + }, + { + type: 'png', + assets: ['foo.png'], + }, + ]); + + let cssPath = path.join(distDir, 'a', 'style1.css'); + let css = await outputFS.readFile(cssPath, 'utf8'); + + assert(css.includes('background-image'), 'includes `background-image`'); + assert(/url\([^)]*\)/.test(css), 'includes url()'); + + assert( + await outputFS.exists( + path.resolve(path.dirname(cssPath), css.match(/url\(([^)]*)\)/)[1]), + ), + 'path specified in url() exists', + ); + }); + + it('should handle quote in CSS URL correctly', async function () { + await bundle(path.join(__dirname, '/integration/css-url-quote/index.css')); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + + assert( + css.includes( + 'url("data:image/svg+xml;utf8,with quote \\" and escape \\\\");', + ), + ); + }); + + it('should ignore url() with IE behavior specifiers', async function () { + let b = await bundle( + path.join(__dirname, '/integration/css-url-behavior/index.css'), + ); + + assertBundles(b, [ + { + name: 'index.css', + assets: ['index.css'], + }, + ]); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + + assert(css.includes('url("#default#VML")')); + }); + + it('should throw a diagnostic for relative url() dependencies in custom properties', async function () { + let fixture = path.join( + __dirname, + 'integration/css-url-custom-property/index.css', + ); + let code = await inputFS.readFileSync(fixture, 'utf8'); + // $FlowFixMe + await assert.rejects( + () => + bundle(fixture, { defaultTargetOptions: { shouldOptimize: true, }, - }); - - let css = await outputFS.readFile( - path.join(distDir, 'index.css'), - 'utf8', - ); - assert(css.includes('.local')); - assert(css.includes('.index')); - - let lines = css.trim().split('\n'); - assert.equal(lines.length, 2); - assert.equal(lines[1], '/*# sourceMappingURL=index.css.map */'); - - let map = JSON.parse( - await outputFS.readFile(path.join(distDir, 'index.css.map'), 'utf8'), - ); - assert.equal(map.file, 'index.css.map'); - assert(map.sources.includes('integration/cssnano/local.css')); - assert(map.sources.includes('integration/cssnano/index.css')); - }); - - it('should inline data-urls for text-encoded files', async () => { - await bundle(path.join(__dirname, '/integration/data-url/text.css'), { - defaultTargetOptions: { - sourceMaps: false, + }), + { + name: 'BuildError', + diagnostics: [ + { + message: + 'Ambiguous url() in custom property. Relative paths are resolved from the location the var() is used, not where the custom property is defined. Use an absolute URL instead.', + origin: '@parcel/transformer-css', + name: 'SyntaxError', + stack: undefined, + codeFrames: [ + { + filePath: fixture, + code, + codeHighlights: [ + { + start: { + line: 2, + column: 11, + }, + end: { + line: 2, + column: 11, + }, + }, + ], + }, + ], + hints: [ + 'Replace with: url(/integration/css-url-custom-property/foo.png)', + ], + documentationURL: 'https://parceljs.org/languages/css/#url()', }, - }); - let css = await outputFS.readFile( - path.join(distDir, 'text.css'), - 'utf8', - ); - assert.equal( - css.trim(), - `.svg-img { + ], + }, + ); + }); + + it('should minify CSS when minify is set', async function () { + let b = await bundle( + path.join(__dirname, '/integration/cssnano/index.js'), + { + defaultTargetOptions: { + shouldOptimize: true, + sourceMaps: false, + }, + }, + ); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert.equal(output(), 3); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + assert(css.includes('.local')); + assert(css.includes('.index')); + + assert.equal(css.split('\n').length, 1); + }); + + it('should produce a sourcemap when sourceMaps are used', async function () { + await bundle(path.join(__dirname, '/integration/cssnano/index.js'), { + defaultTargetOptions: { + shouldOptimize: true, + }, + }); + + let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8'); + assert(css.includes('.local')); + assert(css.includes('.index')); + + let lines = css.trim().split('\n'); + assert.equal(lines.length, 2); + assert.equal(lines[1], '/*# sourceMappingURL=index.css.map */'); + + let map = JSON.parse( + await outputFS.readFile(path.join(distDir, 'index.css.map'), 'utf8'), + ); + assert.equal(map.file, 'index.css.map'); + assert(map.sources.includes('integration/cssnano/local.css')); + assert(map.sources.includes('integration/cssnano/index.css')); + }); + + it('should inline data-urls for text-encoded files', async () => { + await bundle(path.join(__dirname, '/integration/data-url/text.css'), { + defaultTargetOptions: { + sourceMaps: false, + }, + }); + let css = await outputFS.readFile(path.join(distDir, 'text.css'), 'utf8'); + assert.equal( + css.trim(), + `.svg-img { background-image: url("data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Cfilter%20id%3D%22blur-_.%21~%2a%22%3E%0A%20%20%20%20%3CfeGaussianBlur%20stdDeviation%3D%225%22%3E%3C%2FfeGaussianBlur%3E%0A%20%20%3C%2Ffilter%3E%0A%20%20%3Ccircle%20cx%3D%2260%22%20cy%3D%2260%22%20r%3D%2250%22%20fill%3D%22green%22%20filter%3D%22url%28%27%23blur-_.%21~%2a%27%29%22%3E%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A"); }`, - ); - }); - - it('should inline data-urls for binary files', async () => { - await bundle(path.join(__dirname, '/integration/data-url/binary.css')); - let css = await outputFS.readFile( - path.join(distDir, 'binary.css'), - 'utf8', - ); - assert( - css.startsWith(`.webp-img { + ); + }); + + it('should inline data-urls for binary files', async () => { + await bundle(path.join(__dirname, '/integration/data-url/binary.css')); + let css = await outputFS.readFile(path.join(distDir, 'binary.css'), 'utf8'); + assert( + css.startsWith(`.webp-img { background-image: url("data:image/webp;base64,UklGR`), - ); - }); - - it('should remap locations in diagnostics using the input source map', async () => { - let fixture = path.join( - __dirname, - 'integration/diagnostic-sourcemap/index.scss', - ); - let code = await inputFS.readFileSync(fixture, 'utf8'); - // $FlowFixMe - await assert.rejects( - () => - bundle(fixture, { - defaultTargetOptions: { - shouldOptimize: true, - }, - }), + ); + }); + + it('should remap locations in diagnostics using the input source map', async () => { + let fixture = path.join( + __dirname, + 'integration/diagnostic-sourcemap/index.scss', + ); + let code = await inputFS.readFileSync(fixture, 'utf8'); + // $FlowFixMe + await assert.rejects( + () => + bundle(fixture, { + defaultTargetOptions: { + shouldOptimize: true, + }, + }), + { + name: 'BuildError', + diagnostics: [ { - name: 'BuildError', - diagnostics: [ + message: "Failed to resolve 'x.png' from './index.scss'", + origin: '@parcel/core', + codeFrames: [ { - message: "Failed to resolve 'x.png' from './index.scss'", - origin: '@parcel/core', - codeFrames: [ + filePath: fixture, + code, + codeHighlights: [ { - filePath: fixture, - code, - codeHighlights: [ - { - start: { - line: 5, - column: 3, - }, - end: { - line: 5, - column: 3, - }, - }, - ], + start: { + line: 5, + column: 3, + }, + end: { + line: 5, + column: 3, + }, }, ], }, - { - message: "Cannot load file './x.png' in './'.", - origin: '@parcel/resolver-default', - hints: [], - }, ], }, - ); - }); - - it('should support importing CSS from node_modules with the npm: scheme', async () => { - let b = await bundle( - path.join(__dirname, '/integration/css-node-modules/index.css'), - ); - - assertBundles(b, [ { - name: 'index.css', - assets: ['index.css', 'foo.css'], + message: "Cannot load file './x.png' in './'.", + origin: '@parcel/resolver-default', + hints: [], }, - ]); - }); + ], + }, + ); + }); - it('should support external CSS imports', async () => { - let b = await bundle( - path.join(__dirname, '/integration/css-external/a.css'), - ); + it('should support importing CSS from node_modules with the npm: scheme', async () => { + let b = await bundle( + path.join(__dirname, '/integration/css-node-modules/index.css'), + ); - assertBundles(b, [ - { - name: 'a.css', - assets: ['a.css', 'b.css'], - }, - ]); + assertBundles(b, [ + { + name: 'index.css', + assets: ['index.css', 'foo.css'], + }, + ]); + }); + + it('should support external CSS imports', async () => { + let b = await bundle( + path.join(__dirname, '/integration/css-external/a.css'), + ); - let res = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); - assert( - new RegExp(`@import "http://example.com/external.css"; + assertBundles(b, [ + { + name: 'a.css', + assets: ['a.css', 'b.css'], + }, + ]); + + let res = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); + assert( + new RegExp(`@import "http://example.com/external.css"; .b { color: red; }\n? .a { color: green; }`).test(res), - ); - }); - }); - } + ); + }); it('should support css nesting with @parcel/css', async function () { - let b = await originalBundle( + let b = await bundle( path.join(__dirname, '/integration/css-nesting/a.css'), { - defaultConfig: - path.dirname(require.resolve('@parcel/test-utils')) + - '/.parcelrc-css', defaultTargetOptions: { engines: {}, }, diff --git a/packages/core/integration-tests/test/integration/css-url-custom-property/index.css b/packages/core/integration-tests/test/integration/css-url-custom-property/index.css new file mode 100644 index 00000000000..e64216d79ae --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-url-custom-property/index.css @@ -0,0 +1,3 @@ +.foo { + --test: url(foo.png); +} diff --git a/packages/core/integration-tests/test/integration/css-url-quote/index.css b/packages/core/integration-tests/test/integration/css-url-quote/index.css new file mode 100644 index 00000000000..0da4f256ed0 --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-url-quote/index.css @@ -0,0 +1,5 @@ +.quotes { + background-image: url('data:image/svg+xml;utf8,with quote " and escape \\'); + width: 100px; + height: 100px; +} diff --git a/packages/core/integration-tests/test/integration/css-url-quote/index.js b/packages/core/integration-tests/test/integration/css-url-quote/index.js new file mode 100644 index 00000000000..14400a424cd --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-url-quote/index.js @@ -0,0 +1,5 @@ +require('./index.css'); + +module.exports = function () { + return 2; +}; diff --git a/packages/core/integration-tests/test/integration/dynamic-imports-high-prio/async.js b/packages/core/integration-tests/test/integration/dynamic-imports-high-prio/async.js new file mode 100644 index 00000000000..7c645e42fb7 --- /dev/null +++ b/packages/core/integration-tests/test/integration/dynamic-imports-high-prio/async.js @@ -0,0 +1 @@ +export default {}; \ No newline at end of file diff --git a/packages/core/integration-tests/test/integration/dynamic-imports-high-prio/index.js b/packages/core/integration-tests/test/integration/dynamic-imports-high-prio/index.js new file mode 100644 index 00000000000..0a0f551e1ca --- /dev/null +++ b/packages/core/integration-tests/test/integration/dynamic-imports-high-prio/index.js @@ -0,0 +1 @@ +export default import('./async').then(() => document.head.children); diff --git a/packages/core/integration-tests/test/integration/jsx-automatic-16/index.js b/packages/core/integration-tests/test/integration/jsx-automatic-16/index.js new file mode 100644 index 00000000000..8d097d55d7f --- /dev/null +++ b/packages/core/integration-tests/test/integration/jsx-automatic-16/index.js @@ -0,0 +1 @@ +module.exports =
; diff --git a/packages/core/integration-tests/test/integration/jsx-automatic-16/node_modules/react/jsx-dev-runtime.js b/packages/core/integration-tests/test/integration/jsx-automatic-16/node_modules/react/jsx-dev-runtime.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/integration-tests/test/integration/jsx-automatic-16/node_modules/react/jsx-runtime.js b/packages/core/integration-tests/test/integration/jsx-automatic-16/node_modules/react/jsx-runtime.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/integration-tests/test/integration/jsx-automatic-16/node_modules/react/package.json b/packages/core/integration-tests/test/integration/jsx-automatic-16/node_modules/react/package.json new file mode 100644 index 00000000000..bcbea4166f7 --- /dev/null +++ b/packages/core/integration-tests/test/integration/jsx-automatic-16/node_modules/react/package.json @@ -0,0 +1,3 @@ +{ + "name": "react" +} diff --git a/packages/core/integration-tests/test/integration/jsx-automatic-16/package.json b/packages/core/integration-tests/test/integration/jsx-automatic-16/package.json new file mode 100644 index 00000000000..8716e63d8d1 --- /dev/null +++ b/packages/core/integration-tests/test/integration/jsx-automatic-16/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "dependencies": { + "react": "16.14.0" + } +} diff --git a/packages/core/integration-tests/test/integration/jsx-automatic-16/yarn.lock b/packages/core/integration-tests/test/integration/jsx-automatic-16/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css b/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css index 01ef4f07c71..5e2dc1491de 100644 --- a/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css +++ b/packages/core/integration-tests/test/integration/sourcemap-css-import/style.css @@ -1,8 +1,7 @@ @import "./other-style.css"; +@import "./another-style.css"; body { background-color: red; -} - -@import "./another-style.css"; +} \ No newline at end of file diff --git a/packages/core/integration-tests/test/javascript.js b/packages/core/integration-tests/test/javascript.js index f8ee074e7f5..9f8342fe72f 100644 --- a/packages/core/integration-tests/test/javascript.js +++ b/packages/core/integration-tests/test/javascript.js @@ -23,6 +23,7 @@ import {makeDeferredWithPromise, normalizePath} from '@parcel/utils'; import vm from 'vm'; import Logger from '@parcel/logger'; import nullthrows from 'nullthrows'; +import {md} from '@parcel/diagnostic'; describe('javascript', function () { beforeEach(async () => { @@ -593,20 +594,20 @@ describe('javascript', function () { let output = await run(b); let headChildren = await output.default; - assert.equal(headChildren.length, 3); + assert.strictEqual(headChildren.length, 4); - assert(headChildren[0].tag === 'script'); - assert(headChildren[0].src.match(/async\..*\.js/)); + assert.strictEqual(headChildren[1].tag, 'script'); + assert(headChildren[1].src.match(/async\..*\.js/)); - assert(headChildren[1].tag === 'link'); - assert(headChildren[1].rel === 'prefetch'); - assert(headChildren[1].as === 'script'); - assert(headChildren[1].href.match(/prefetched\..*\.js/)); + assert.strictEqual(headChildren[2].tag, 'link'); + assert.strictEqual(headChildren[2].rel, 'prefetch'); + assert.strictEqual(headChildren[2].as, 'script'); + assert(headChildren[2].href.match(/prefetched\..*\.js/)); - assert(headChildren[2].tag === 'link'); - assert(headChildren[2].rel === 'prefetch'); - assert(headChildren[2].as === 'style'); - assert(headChildren[2].href.match(/prefetched\..*\.css/)); + assert.strictEqual(headChildren[3].tag, 'link'); + assert.strictEqual(headChildren[3].rel, 'prefetch'); + assert.strictEqual(headChildren[3].as, 'style'); + assert(headChildren[3].href.match(/prefetched\..*\.css/)); }); it('should load additional links that were prefetched', async function () { @@ -622,7 +623,7 @@ describe('javascript', function () { await outputReturn.loadDependency(); let headChildren = outputReturn.children; - assert.equal(headChildren.length, 5); + assert.equal(headChildren.length, 7); let cssBundles = headChildren.filter(child => child.href?.match(/prefetched-loaded\..*\.css/), ); @@ -646,20 +647,17 @@ describe('javascript', function () { let output = await run(b); let headChildren = await output.default; - assert(headChildren.length === 3); - - assert(headChildren[0].tag === 'script'); - assert(headChildren[0].src.match(/async\..*\.js/)); - - assert(headChildren[1].tag === 'link'); - assert(headChildren[1].rel === 'preload'); - assert(headChildren[1].as === 'script'); - assert(headChildren[1].href.match(/preloaded\..*\.js/)); + assert(headChildren.length === 4); assert(headChildren[2].tag === 'link'); assert(headChildren[2].rel === 'preload'); - assert(headChildren[2].as === 'style'); - assert(headChildren[2].href.match(/preloaded\..*\.css/)); + assert(headChildren[2].as === 'script'); + assert(headChildren[2].href.match(/preloaded\..*\.js/)); + + assert(headChildren[3].tag === 'link'); + assert(headChildren[3].rel === 'preload'); + assert(headChildren[3].as === 'style'); + assert(headChildren[3].href.match(/preloaded\..*\.css/)); }); // TODO: Implement when we can evaluate bundles against esmodule targets @@ -873,6 +871,31 @@ describe('javascript', function () { assert.deepEqual(res, {default: 42}); }); + it('dynamic imports loaded as high-priority scripts when not all engines support esmodules natively', async function () { + let b = await bundle( + path.join(__dirname, '/integration/dynamic-imports-high-prio/index.js'), + { + defaultTargetOptions: { + engines: { + browsers: 'IE 11', + }, + }, + }, + ); + + let output = await run(b); + let headChildren = await output.default; + + assert(headChildren[0].tag === 'link'); + assert(headChildren[0].rel === 'preload'); + assert(headChildren[0].as === 'script'); + + assert(headChildren[1].tag === 'script'); + assert(headChildren[1].src.match(/async\..*\.js/)); + + assert(headChildren[0].href === headChildren[1].src); + }); + it('should support bundling workers with dynamic import in both page and worker', async function () { let b = await bundle( path.join(__dirname, '/integration/worker-dynamic/index-async.js'), @@ -5307,7 +5330,7 @@ describe('javascript', function () { name: 'BuildError', diagnostics: [ { - message: `Failed to resolve '@swc/helpers' from '${normalizePath( + message: md`Failed to resolve '@swc/helpers' from '${normalizePath( require.resolve('@parcel/transformer-js/src/JSTransformer.js'), )}'`, origin: '@parcel/core', diff --git a/packages/core/integration-tests/test/transpilation.js b/packages/core/integration-tests/test/transpilation.js index c5e52a89bc7..a630267eee5 100644 --- a/packages/core/integration-tests/test/transpilation.js +++ b/packages/core/integration-tests/test/transpilation.js @@ -203,6 +203,16 @@ describe('transpilation', function () { assert(file.includes('_jsxDevRuntime.jsxDEV("div"')); }); + it('should support the automatic JSX runtime with React ^16.14.0', async function () { + let b = await bundle( + path.join(__dirname, '/integration/jsx-automatic-16/index.js'), + ); + + let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); + assert(file.includes('react/jsx-dev-runtime')); + assert(file.includes('_jsxDevRuntime.jsxDEV("div"')); + }); + it('should support the automatic JSX runtime with React 18 prereleases', async function () { let b = await bundle( path.join(__dirname, '/integration/jsx-automatic-18/index.js'), diff --git a/packages/core/test-utils/src/.parcelrc-css b/packages/core/test-utils/src/.parcelrc-css deleted file mode 100644 index 1d8a4120038..00000000000 --- a/packages/core/test-utils/src/.parcelrc-css +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@parcel/config-default", - "transformers": { - "*.css": ["@parcel/transformer-postcss", "@parcel/transformer-css-experimental"] - }, - "optimizers": { - "*.css": ["@parcel/optimizer-css"] - }, - "reporters": [] -} diff --git a/packages/core/types/index.js b/packages/core/types/index.js index 6ae22521e31..69990255f32 100644 --- a/packages/core/types/index.js +++ b/packages/core/types/index.js @@ -747,9 +747,9 @@ export interface MutableAsset extends BaseAsset { setBuffer(Buffer): void; /** Sets the asset contents as a stream. */ setStream(Readable): void; - /** Returns whether the AST has been modified. */ - setAST(AST): void; /** Sets the asset's AST. */ + setAST(AST): void; + /** Returns whether the AST has been modified. */ isASTDirty(): boolean; /** Sets the asset's source map. */ setMap(?SourceMap): void; diff --git a/packages/core/utils/src/replaceBundleReferences.js b/packages/core/utils/src/replaceBundleReferences.js index 8161ac299ad..25eaf2c996c 100644 --- a/packages/core/utils/src/replaceBundleReferences.js +++ b/packages/core/utils/src/replaceBundleReferences.js @@ -33,6 +33,7 @@ export function replaceURLReferences({ bundleGraph, contents, map, + getReplacement = s => s, relative = true, }: {| bundle: NamedBundle, @@ -40,6 +41,7 @@ export function replaceURLReferences({ contents: string, relative?: boolean, map?: ?SourceMap, + getReplacement?: string => string, |}): {|+contents: string, +map: ?SourceMap|} { let replacements = new Map(); let urlDependencies = []; @@ -61,7 +63,7 @@ export function replaceURLReferences({ if (resolved == null) { replacements.set(placeholder, { from: placeholder, - to: dependency.specifier, + to: getReplacement(dependency.specifier), }); continue; } @@ -79,6 +81,7 @@ export function replaceURLReferences({ fromBundle: bundle, toBundle: resolved, relative, + getReplacement, }), ); } @@ -156,11 +159,13 @@ export function getURLReplacement({ fromBundle, toBundle, relative, + getReplacement, }: {| dependency: Dependency, fromBundle: NamedBundle, toBundle: NamedBundle, relative: boolean, + getReplacement?: string => string, |}): {|from: string, to: string|} { let to; @@ -191,9 +196,10 @@ export function getURLReplacement({ let placeholder = dependency.meta?.placeholder ?? dependency.id; invariant(typeof placeholder === 'string'); + return { from: placeholder, - to, + to: getReplacement ? getReplacement(to) : to, }; } diff --git a/packages/optimizers/css/package.json b/packages/optimizers/css/package.json index 2dbbde8d247..7f84fdc7275 100644 --- a/packages/optimizers/css/package.json +++ b/packages/optimizers/css/package.json @@ -20,7 +20,8 @@ "parcel": "^2.0.1" }, "dependencies": { - "@parcel/css": "^1.0.3", + "@parcel/css": "^1.7.2", + "@parcel/diagnostic": "2.0.20", "@parcel/plugin": "2.0.20", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.0.20", diff --git a/packages/optimizers/css/src/CSSOptimizer.js b/packages/optimizers/css/src/CSSOptimizer.js index d6b415eb2c6..7e4507a609a 100644 --- a/packages/optimizers/css/src/CSSOptimizer.js +++ b/packages/optimizers/css/src/CSSOptimizer.js @@ -10,8 +10,54 @@ import { import {blobToBuffer} from '@parcel/utils'; import browserslist from 'browserslist'; import nullthrows from 'nullthrows'; +import path from 'path'; +import {md, generateJSONCodeHighlights} from '@parcel/diagnostic'; export default (new Optimizer({ + async loadConfig({config, logger, options}) { + const configFile = await config.getConfig( + ['.cssnanorc', 'cssnano.config.json', 'cssnano.config.js'], + { + packageKey: 'cssnano', + }, + ); + if (configFile) { + let filename = path.basename(configFile.filePath); + let codeHighlights; + let message; + if (filename === 'package.json') { + message = md` +Parcel\'s default CSS minifer changed from cssnano to @parcel/css, but a "cssnano" key was found in **package.json**. Either remove this configuration, or configure Parcel to use @parcel/optimizer-cssnano instead. + `; + let contents = await options.inputFS.readFile( + configFile.filePath, + 'utf8', + ); + codeHighlights = generateJSONCodeHighlights(contents, [ + {key: '/cssnano', type: 'key'}, + ]); + } else { + message = md`Parcel\'s default CSS minifer changed from cssnano to @parcel/css, but a __${filename}__ config file was found. Either remove this config file, or configure Parcel to use @parcel/optimizer-cssnano instead.`; + codeHighlights = [ + { + start: {line: 1, column: 1}, + end: {line: 1, column: 1}, + }, + ]; + } + + logger.warn({ + message, + documentationURL: 'https://parceljs.org/languages/css/#minification', + codeFrames: [ + { + filePath: configFile.filePath, + codeHighlights, + }, + ], + }); + } + }, async optimize({ bundle, bundleGraph, diff --git a/packages/optimizers/image/package.json b/packages/optimizers/image/package.json index 364ea394919..442270c748e 100644 --- a/packages/optimizers/image/package.json +++ b/packages/optimizers/image/package.json @@ -37,7 +37,7 @@ "@parcel/utils": "2.0.20", "@parcel/workers": "2.0.20", "detect-libc": "^1.0.3", - "self-published": "npm:@parcel/optimizer-image@2.3.3-nightly.2635" + "self-published": "npm:@parcel/optimizer-image@2.4.1-nightly.2654" }, "devDependencies": { "@napi-rs/cli": "1.0.4", diff --git a/packages/packagers/css/src/CSSPackager.js b/packages/packagers/css/src/CSSPackager.js index 23be7bae163..ae2fbbef49b 100644 --- a/packages/packagers/css/src/CSSPackager.js +++ b/packages/packagers/css/src/CSSPackager.js @@ -129,6 +129,7 @@ export default (new Packager({ bundleGraph, contents, map, + getReplacement: escapeString, })); return replaceInlineReferences({ @@ -138,7 +139,7 @@ export default (new Packager({ getInlineBundleContents, getInlineReplacement: (dep, inlineType, contents) => ({ from: getSpecifier(dep), - to: contents, + to: escapeString(contents), }), map, }); @@ -153,6 +154,10 @@ export function getSpecifier(dep: Dependency): string { return dep.id; } +function escapeString(contents: string): string { + return contents.replace(/(["\\])/g, '\\$1'); +} + async function processCSSModule( options, logger, diff --git a/packages/packagers/html/src/HTMLPackager.js b/packages/packagers/html/src/HTMLPackager.js index b30faf3a110..f92089f5f12 100644 --- a/packages/packagers/html/src/HTMLPackager.js +++ b/packages/packagers/html/src/HTMLPackager.js @@ -74,6 +74,7 @@ export default (new Packager({ bundleGraph, contents: html, relative: false, + getReplacement: contents => contents.replace(/"/g, '"'), }); return replaceInlineReferences({ diff --git a/packages/packagers/js/src/index.js b/packages/packagers/js/src/index.js index 58c96fa4fb8..73f1ebc0aa6 100644 --- a/packages/packagers/js/src/index.js +++ b/packages/packagers/js/src/index.js @@ -72,6 +72,7 @@ export default (new Packager({ bundleGraph, contents, map, + getReplacement: s => JSON.stringify(s).slice(1, -1), })); } diff --git a/packages/packagers/raw-url/src/RawUrlPackager.js b/packages/packagers/raw-url/src/RawUrlPackager.js index cd73ce2bac2..e6641bf415b 100644 --- a/packages/packagers/raw-url/src/RawUrlPackager.js +++ b/packages/packagers/raw-url/src/RawUrlPackager.js @@ -17,6 +17,7 @@ export default (new Packager({ bundleGraph, contents: await assets[0].getCode(), relative: false, + getReplacement: s => s, }); return {contents}; }, diff --git a/packages/packagers/svg/src/SVGPackager.js b/packages/packagers/svg/src/SVGPackager.js index a2dd81e9004..3ee06bd7d20 100644 --- a/packages/packagers/svg/src/SVGPackager.js +++ b/packages/packagers/svg/src/SVGPackager.js @@ -58,6 +58,7 @@ export default (new Packager({ bundleGraph, contents: svg, relative: false, + getReplacement: contents => contents.replace(/"/g, '"'), }); return replaceInlineReferences({ diff --git a/packages/packagers/xml/src/XMLPackager.js b/packages/packagers/xml/src/XMLPackager.js index 7e267a2fb41..290c0c73ad9 100644 --- a/packages/packagers/xml/src/XMLPackager.js +++ b/packages/packagers/xml/src/XMLPackager.js @@ -68,6 +68,7 @@ export default (new Packager({ bundleGraph, contents: code, relative: false, + getReplacement: contents => contents.replace(/"/g, '"'), }); return replaceInlineReferences({ diff --git a/packages/reporters/bundle-analyzer/client/index.js b/packages/reporters/bundle-analyzer/client/index.js index 59d87017ce4..618f85af94b 100644 --- a/packages/reporters/bundle-analyzer/client/index.js +++ b/packages/reporters/bundle-analyzer/client/index.js @@ -53,7 +53,7 @@ let foamtree = new CarrotSearchFoamTree({
Size
-
${e.group.weight} bytes
+
${formatSize(e.group.weight)}
@@ -86,7 +86,7 @@ window.addEventListener( function debounce(fn, delay) { let timeout; - return function(...args) { + return function (...args) { if (timeout) { clearTimeout(timeout); } @@ -100,3 +100,13 @@ function debounce(fn, delay) { function translate3d(x, y, z) { return `translate3d(${x}px, ${y}px, ${z}px)`; } + +const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; +function formatSize(x) { + let l = 0, + n = parseInt(x, 10) || 0; + while (n >= 1000 && ++l) { + n /= 1000; + } + return `${n.toFixed(l > 0 ? 2 : 0)} ${UNITS[l]}`; +} diff --git a/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js b/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js index 908df07d739..6889353c657 100644 --- a/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js +++ b/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js @@ -158,7 +158,7 @@ async function getBundleNode(bundle: PackagedBundle, options: PluginOptions) { } return { - label: bundle.filePath, + label: path.relative(options.projectRoot, bundle.filePath), weight: bundle.stats.size, groups: generateGroups(dirMap), }; diff --git a/packages/reporters/cli/src/emoji.js b/packages/reporters/cli/src/emoji.js index aa3a16190ba..6b05521ce52 100644 --- a/packages/reporters/cli/src/emoji.js +++ b/packages/reporters/cli/src/emoji.js @@ -1,7 +1,23 @@ // @flow strict-local -const supportsEmoji = - process.platform !== 'win32' || process.env.TERM === 'xterm-256color'; +// From https://github.com/sindresorhus/is-unicode-supported/blob/8f123916d5c25a87c4f966dcc248b7ca5df2b4ca/index.js +// This package is ESM-only so it has to be vendored +function isUnicodeSupported() { + if (process.platform !== 'win32') { + return process.env.TERM !== 'linux'; // Linux console (kernel) + } + + return ( + Boolean(process.env.CI) || + Boolean(process.env.WT_SESSION) || // Windows Terminal + process.env.ConEmuTask === '{cmd::Cmder}' || // ConEmu and cmder + process.env.TERM_PROGRAM === 'vscode' || + process.env.TERM === 'xterm-256color' || + process.env.TERM === 'alacritty' + ); +} + +const supportsEmoji = isUnicodeSupported(); // Fallback symbols for Windows from https://en.wikipedia.org/wiki/Code_page_437 export const progress: string = supportsEmoji ? '⏳' : '∞'; diff --git a/packages/runtimes/js/src/helpers/browser/js-loader.js b/packages/runtimes/js/src/helpers/browser/js-loader.js index 867fa4f4d2b..0ab0f33f63e 100644 --- a/packages/runtimes/js/src/helpers/browser/js-loader.js +++ b/packages/runtimes/js/src/helpers/browser/js-loader.js @@ -13,6 +13,12 @@ module.exports = cacheLoader(function loadJSBundle(bundle) { return; } + var preloadLink = document.createElement('link'); + preloadLink.href = bundle; + preloadLink.rel = 'preload'; + preloadLink.as = 'script'; + document.head.appendChild(preloadLink); + var script = document.createElement('script'); script.async = true; script.type = 'text/javascript'; diff --git a/packages/transformers/css-experimental/package.json b/packages/transformers/css-experimental/package.json deleted file mode 100644 index 1260a8af6d5..00000000000 --- a/packages/transformers/css-experimental/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "@parcel/transformer-css-experimental", - "version": "2.0.20", - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "repository": { - "type": "git", - "url": "https://github.com/parcel-bundler/parcel.git" - }, - "main": "lib/CSSTransformer.js", - "source": "src/CSSTransformer.js", - "engines": { - "node": ">= 12.0.0", - "parcel": "^2.0.1" - }, - "dependencies": { - "@parcel/css": "^1.0.3", - "@parcel/plugin": "2.0.20", - "@parcel/source-map": "^2.0.0", - "@parcel/utils": "2.0.20", - "browserslist": "^4.6.6", - "nullthrows": "^1.1.1" - } -} diff --git a/packages/transformers/css-experimental/src/CSSTransformer.js b/packages/transformers/css-experimental/src/CSSTransformer.js deleted file mode 100644 index 58f1638f331..00000000000 --- a/packages/transformers/css-experimental/src/CSSTransformer.js +++ /dev/null @@ -1,232 +0,0 @@ -// @flow strict-local - -import path from 'path'; -import SourceMap from '@parcel/source-map'; -import {Transformer} from '@parcel/plugin'; -import { - transform, - transformStyleAttribute, - browserslistToTargets, -} from '@parcel/css'; -import {remapSourceLocation} from '@parcel/utils'; -import browserslist from 'browserslist'; -import nullthrows from 'nullthrows'; - -export default (new Transformer({ - async loadConfig({config, options}) { - let conf = await config.getConfigFrom(options.projectRoot + '/index', [], { - packageKey: '@parcel/transformer-css', - }); - return conf?.contents; - }, - async transform({asset, config, options}) { - let [code, originalMap] = await Promise.all([ - asset.getBuffer(), - asset.getMap(), - ]); - - let targets = getTargets(asset.env.engines.browsers); - let res; - if (asset.meta.type === 'attr') { - res = transformStyleAttribute({ - code, - analyzeDependencies: true, - targets, - }); - } else { - res = transform({ - filename: path.relative(options.projectRoot, asset.filePath), - code, - cssModules: - config?.cssModules ?? - (asset.meta.cssModulesCompiled !== true && - /\.module\./.test(asset.filePath)), - analyzeDependencies: asset.meta.hasDependencies !== false, - sourceMap: !!asset.env.sourceMap, - drafts: config?.drafts, - pseudoClasses: config?.pseudoClasses, - targets, - }); - } - - asset.setBuffer(res.code); - - if (res.map != null) { - let vlqMap = JSON.parse(res.map.toString()); - let map = new SourceMap(options.projectRoot); - map.addVLQMap(vlqMap); - - if (originalMap) { - map.extends(originalMap); - } - - asset.setMap(map); - } - - if (res.dependencies) { - for (let dep of res.dependencies) { - let loc = dep.loc; - if (originalMap) { - loc = remapSourceLocation(loc, originalMap); - } - - if (dep.type === 'import') { - asset.addDependency({ - specifier: dep.url, - specifierType: 'url', - loc, - meta: { - // For the glob resolver to distinguish between `@import` and other URL dependencies. - isCSSImport: true, - media: dep.media, - }, - symbols: new Map([['*', {local: '*', isWeak: true, loc}]]), - }); - } else if (dep.type === 'url') { - asset.addURLDependency(dep.url, { - loc, - meta: { - placeholder: dep.placeholder, - }, - }); - } - } - } - - let assets = [asset]; - - if (res.exports != null) { - let exports = res.exports; - asset.symbols.ensure(); - asset.symbols.set('default', 'default'); - - let dependencies = new Map(); - let selfReferences = new Set(); - let locals = new Map(); - let c = 0; - let depjs = ''; - let js = ''; - - let jsDeps = []; - for (let dep of asset.getDependencies()) { - if (dep.priority === 'sync') { - // TODO: Figure out how to treeshake this - let d = `dep_$${c++}`; - depjs += `import * as ${d} from ${JSON.stringify(dep.specifier)};\n`; - depjs += `for (let key in ${d}) { if (key in module.exports) module.exports[key] += ' ' + ${d}[key]; else module.exports[key] = ${d}[key]; }\n`; - } - } - - for (let key in exports) { - locals.set(exports[key].name, key); - } - - let seen = new Set(); - let add = key => { - if (seen.has(key)) { - return; - } - seen.add(key); - - let e = exports[key]; - let s = `module.exports[${JSON.stringify(key)}] = \`${e.name}`; - - if (e.isReferenced) { - selfReferences.add(e.name); - } - - for (let ref of e.composes) { - s += ' '; - if (ref.type === 'local') { - add(nullthrows(locals.get(ref.name))); - s += - '${' + - `module.exports[${JSON.stringify( - nullthrows(locals.get(ref.name)), - )}]` + - '}'; - } else if (ref.type === 'global') { - s += ref.name; - } else if (ref.type === 'dependency') { - let d = dependencies.get(ref.specifier); - if (d == null) { - d = `dep_${c++}`; - depjs += `import * as ${d} from ${JSON.stringify( - ref.specifier, - )};\n`; - dependencies.set(ref.specifier, d); - - asset.addDependency({ - specifier: ref.specifier, - specifierType: 'url', - }); - } - s += '${' + `${d}[${JSON.stringify(ref.name)}]` + '}'; - } - } - - s += '`;\n'; - js += s; - }; - - for (let key in exports) { - asset.symbols.set(key, exports[key].name); - add(key); - } - - assets.push({ - type: 'js', - content: depjs + js, - dependencies: jsDeps, - env: asset.env, - }); - - if (selfReferences.size > 0) { - asset.addDependency({ - specifier: `./${path.basename(asset.filePath)}`, - specifierType: 'url', - symbols: new Map( - [...locals] - .filter(([local]) => selfReferences.has(local)) - .map(([local, exported]) => [ - exported, - {local, isWeak: false, loc: null}, - ]), - ), - }); - } - } - - // Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated. - // For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced. - asset.setEnvironment({ - context: 'browser', - engines: { - browsers: asset.env.engines.browsers, - }, - shouldOptimize: asset.env.shouldOptimize, - shouldScopeHoist: asset.env.shouldScopeHoist, - sourceMap: asset.env.sourceMap, - }); - - return assets; - }, -}): Transformer); - -let cache = new Map(); - -function getTargets(browsers) { - if (browsers == null) { - return undefined; - } - - let cached = cache.get(browsers); - if (cached != null) { - return cached; - } - - let targets = browserslistToTargets(browserslist(browsers)); - - cache.set(browsers, targets); - return targets; -} diff --git a/packages/transformers/css/package.json b/packages/transformers/css/package.json index 60990427154..55ecf70bf3d 100644 --- a/packages/transformers/css/package.json +++ b/packages/transformers/css/package.json @@ -17,19 +17,15 @@ "source": "src/CSSTransformer.js", "engines": { "node": ">= 12.0.0", - "parcel": "^2.0.1" + "parcel": "^2.0.20" }, "dependencies": { - "@parcel/hash": "2.0.20", + "@parcel/css": "^1.7.2", + "@parcel/diagnostic": "2.0.20", "@parcel/plugin": "2.0.20", "@parcel/source-map": "^2.0.0", "@parcel/utils": "2.0.20", - "nullthrows": "^1.1.1", - "postcss": "^8.4.5", - "postcss-value-parser": "^4.2.0", - "semver": "^5.7.1" - }, - "devDependencies": { - "postcss-modules": "^4.3.0" + "browserslist": "^4.6.6", + "nullthrows": "^1.1.1" } } diff --git a/packages/transformers/css/src/CSSTransformer.js b/packages/transformers/css/src/CSSTransformer.js index 8aff146b660..0cf252b731b 100644 --- a/packages/transformers/css/src/CSSTransformer.js +++ b/packages/transformers/css/src/CSSTransformer.js @@ -1,376 +1,257 @@ -// @flow +// @flow strict-local -import type {Root} from 'postcss'; -import type {FilePath, MutableAsset, PluginOptions} from '@parcel/types'; - -import {hashString} from '@parcel/hash'; +import path from 'path'; import SourceMap from '@parcel/source-map'; import {Transformer} from '@parcel/plugin'; -import {createDependencyLocation, remapSourceLocation} from '@parcel/utils'; -import postcss from 'postcss'; +import { + transform, + transformStyleAttribute, + browserslistToTargets, +} from '@parcel/css'; +import {remapSourceLocation, relativePath} from '@parcel/utils'; +import browserslist from 'browserslist'; import nullthrows from 'nullthrows'; -import valueParser from 'postcss-value-parser'; -import semver from 'semver'; -import path from 'path'; - -const URL_RE = /url\s*\(/; -const IMPORT_RE = /@import/; -const COMPOSES_RE = /composes:.+from\s*("|').*("|')\s*;?/; -const FROM_IMPORT_RE = /.+from\s*(?:"|')(.*)(?:"|')\s*;?/; -const MODULE_BY_NAME_RE = /\.module\./; - -function canHaveDependencies(filePath: FilePath, code: string) { - return !/\.css$/.test(filePath) || IMPORT_RE.test(code) || URL_RE.test(code); -} +import ThrowableDiagnostic, {errorToDiagnostic} from '@parcel/diagnostic'; export default (new Transformer({ - canReuseAST({ast}) { - return ast.type === 'postcss' && semver.satisfies(ast.version, '^8.2.1'); + async loadConfig({config, options}) { + let conf = await config.getConfigFrom(options.projectRoot + '/index', [], { + packageKey: '@parcel/transformer-css', + }); + return conf?.contents; }, + async transform({asset, config, options}) { + let [code, originalMap] = await Promise.all([ + asset.getBuffer(), + asset.getMap(), + ]); + + let targets = getTargets(asset.env.engines.browsers); + let res; + try { + if (asset.meta.type === 'attr') { + res = transformStyleAttribute({ + code, + analyzeDependencies: true, + targets, + }); + } else { + res = transform({ + filename: path.relative(options.projectRoot, asset.filePath), + code, + cssModules: + config?.cssModules ?? + (asset.meta.cssModulesCompiled !== true && + /\.module\./.test(asset.filePath)), + analyzeDependencies: asset.meta.hasDependencies !== false, + sourceMap: !!asset.env.sourceMap, + drafts: config?.drafts, + pseudoClasses: config?.pseudoClasses, + targets, + }); + } + } catch (err) { + err.filePath = asset.filePath; + let diagnostic = errorToDiagnostic(err, { + origin: '@parcel/transformer-css', + }); + if (err.data?.type === 'AmbiguousUrlInCustomProperty' && err.data.url) { + let p = + '/' + + relativePath( + options.projectRoot, + path.resolve(path.dirname(asset.filePath), err.data.url), + false, + ); + diagnostic[0].hints = [`Replace with: url(${p})`]; + diagnostic[0].documentationURL = + 'https://parceljs.org/languages/css/#url()'; + } - async parse({asset}) { - // This is set by other transformers (e.g. Stylus) to indicate that it has already processed - // all dependencies, and that the CSS transformer can skip this asset completely. This is - // required because when stylus processes e.g. url() it replaces them with a dependency id - // to be filled in later. When the CSS transformer runs, it would pick that up and try to - // resolve a dependency for the id which obviously doesn't exist. Also, it's faster to do - // it this way since the resulting CSS doesn't need to be re-parsed. - let isCSSModule = - asset.meta.cssModulesCompiled !== true && - MODULE_BY_NAME_RE.test(asset.filePath); - if (asset.meta.hasDependencies === false && !isCSSModule) { - return null; + throw new ThrowableDiagnostic({ + diagnostic, + }); } - let code = await asset.getCode(); - if ( - code != null && - !canHaveDependencies(asset.filePath, code) && - !isCSSModule - ) { - return null; - } + asset.setBuffer(res.code); - return { - type: 'postcss', - version: '8.2.1', - program: postcss - .parse(code, { - from: asset.filePath, - }) - .toJSON(), - }; - }, + if (res.map != null) { + let vlqMap = JSON.parse(res.map.toString()); + let map = new SourceMap(options.projectRoot); + map.addVLQMap(vlqMap); - async transform({asset, resolve, options}) { - // Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated. - // For example, with ESModule and CommonJS targets, only a single shared CSS bundle should be produced. - let env = asset.env; - asset.setEnvironment({ - context: 'browser', - engines: { - browsers: asset.env.engines.browsers, - }, - shouldOptimize: asset.env.shouldOptimize, - sourceMap: asset.env.sourceMap, - }); + if (originalMap) { + map.extends(originalMap); + } - let isCSSModule = - asset.meta.cssModulesCompiled !== true && - MODULE_BY_NAME_RE.test(asset.filePath); + asset.setMap(map); + } + + if (res.dependencies) { + for (let dep of res.dependencies) { + let loc = dep.loc; + if (originalMap) { + loc = remapSourceLocation(loc, originalMap); + } - // Check for `hasDependencies` being false here as well, as it's possible - // another transformer (such as PostCSSTransformer) has already parsed an - // ast and CSSTransformer's parse was never called. - let ast = await asset.getAST(); - if (!ast || (asset.meta.hasDependencies === false && !isCSSModule)) { - return [asset]; + if (dep.type === 'import') { + asset.addDependency({ + specifier: dep.url, + specifierType: 'url', + loc, + meta: { + // For the glob resolver to distinguish between `@import` and other URL dependencies. + isCSSImport: true, + media: dep.media, + }, + symbols: new Map([['*', {local: '*', isWeak: true, loc}]]), + }); + } else if (dep.type === 'url') { + asset.addURLDependency(dep.url, { + loc, + meta: { + placeholder: dep.placeholder, + }, + }); + } + } } - let program: Root = postcss.fromJSON(ast.program); let assets = [asset]; - if (isCSSModule) { - assets = await compileCSSModules(asset, env, program, resolve, options); - } - if (asset.meta.hasDependencies === false) { - return assets; - } + if (res.exports != null) { + let exports = res.exports; + asset.symbols.ensure(); + asset.symbols.set('default', 'default'); - let originalSourceMap = await asset.getMap(); - let createLoc = (start, specifier, lineOffset, colOffset, o) => { - let loc = createDependencyLocation( - start, - specifier, - lineOffset, - colOffset, - o, - ); - if (originalSourceMap) { - loc = remapSourceLocation(loc, originalSourceMap); - } - return loc; - }; - - let isDirty = false; - program.walkAtRules('import', rule => { - let params = valueParser(rule.params); - let [name, ...media] = params.nodes; - let specifier; - if ( - name.type === 'function' && - name.value === 'url' && - name.nodes.length - ) { - name = name.nodes[0]; - } + let dependencies = new Map(); + let selfReferences = new Set(); + let locals = new Map(); + let c = 0; + let depjs = ''; + let js = ''; - specifier = name.value; + let jsDeps = []; - if (!specifier) { - throw new Error('Could not find import name for ' + String(rule)); + for (let key in exports) { + locals.set(exports[key].name, key); } - // If this came from an inline