diff --git a/.flowconfig b/.flowconfig
index 5f8e969f2bd..522d3c0d306 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -36,4 +36,4 @@ untyped-import
untyped-type-import
[version]
-0.158.0
+0.160.1
diff --git a/Cargo.lock b/Cargo.lock
index 72961081c26..5b8f28ade7b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -55,9 +55,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.43"
+version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf"
+checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
[[package]]
name = "arrayvec"
@@ -155,9 +155,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
-version = "1.0.69"
+version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
+checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
dependencies = [
"jobserver",
]
@@ -228,9 +228,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "cpufeatures"
-version = "0.1.5"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
+checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
dependencies = [
"libc",
]
@@ -533,9 +533,9 @@ dependencies = [
[[package]]
name = "if_chain"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f7280c75fb2e2fc47080ec80ccc481376923acb04501957fc38f935c3de5088"
+checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]]
name = "image"
@@ -596,9 +596,9 @@ dependencies = [
[[package]]
name = "itoa"
-version = "0.4.7"
+version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "jemalloc-sys"
@@ -670,9 +670,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.99"
+version = "0.2.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765"
+checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21"
[[package]]
name = "libdeflate-sys"
@@ -718,9 +718,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "memchr"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "memoffset"
@@ -773,9 +773,9 @@ dependencies = [
[[package]]
name = "napi"
-version = "1.7.6"
+version = "1.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb22375ec7cbd8bee4535126bb323e4e62cbf8088d84f0225d4d3226d1619bd5"
+checksum = "2813a6f24e181eb1faba8bc632e56049901fb71df4bf3e0cd6b4086db6606c78"
dependencies = [
"napi-sys",
"serde",
@@ -907,9 +907,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "ordered-float"
-version = "2.7.0"
+version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "039f02eb0f69271f26abe3202189275d7aa2258b903cb0281b5de710a2570ff3"
+checksum = "97c9d06878b3a851e8026ef94bf7fef9ba93062cd412601da4d9cf369b1cc62d"
dependencies = [
"num-traits",
]
@@ -1128,9 +1128,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
-version = "1.0.28"
+version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
+checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
dependencies = [
"unicode-xid",
]
@@ -1330,18 +1330,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
-version = "1.0.127"
+version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8"
+checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde-wasm-bindgen"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1102fa7714968fcf70fd8efa29fb3b189e20ef0e7701fbab9634384dda034bf3"
+checksum = "618365e8e586c22123d692b72a7d791d5ee697817b65a218cdf12a98870af0f7"
dependencies = [
"fnv",
"js-sys",
@@ -1360,9 +1360,9 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.127"
+version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc"
+checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
dependencies = [
"proc-macro2",
"quote",
@@ -1371,9 +1371,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.66"
+version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
+checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950"
dependencies = [
"itoa",
"ryu",
@@ -1382,9 +1382,9 @@ dependencies = [
[[package]]
name = "sha-1"
-version = "0.9.7"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81"
+checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
dependencies = [
"block-buffer",
"cfg-if 1.0.0",
@@ -1395,9 +1395,9 @@ dependencies = [
[[package]]
name = "siphasher"
-version = "0.3.6"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1"
+checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
[[package]]
name = "smallvec"
@@ -1520,9 +1520,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "swc_atoms"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bcdb70cb6ecee568e5acfda1a8c6e851ecf49443e5fb51f1b13613b5d04d2b0"
+checksum = "837a3ef86c2817228e733b6f173c821fd76f9eb21a0bc9001a826be48b00b4e7"
dependencies = [
"string_cache",
"string_cache_codegen",
@@ -1530,9 +1530,9 @@ dependencies = [
[[package]]
name = "swc_common"
-version = "0.11.6"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fc89b8c9f2fa3fc646e7d1a05ebc2063b1396b3ba5277afc741505bd7414fff"
+checksum = "0100bddbd0b5587223a862dedc9556715d066205e7e1954ca080567693923ee5"
dependencies = [
"ahash",
"ast_node",
@@ -1553,13 +1553,14 @@ dependencies = [
"swc_visit",
"termcolor",
"unicode-width",
+ "url",
]
[[package]]
name = "swc_ecma_ast"
-version = "0.49.4"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3efef728f69665d765c52b233155dcb3290424f56a9f978ecfbd53f136804461"
+checksum = "aa0efb0e13ba6545e2b86336937e1641594f78c48484b85c2dc9582eaccb41e1"
dependencies = [
"is-macro",
"num-bigint",
@@ -1571,9 +1572,9 @@ dependencies = [
[[package]]
name = "swc_ecma_codegen"
-version = "0.67.0"
+version = "0.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96a380bd935ce811c0bc8b961abc97cbf3a8c759213634aa59f5b0601162ba4e"
+checksum = "7940bff62e5caf62fe6732ce4f07e52c3c208cb58cd9299f7f7c92dddab2bf72"
dependencies = [
"bitflags",
"num-bigint",
@@ -1600,9 +1601,9 @@ dependencies = [
[[package]]
name = "swc_ecma_loader"
-version = "0.15.0"
+version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bc6a797d2df5f60cc9ab6a85aa7a49ab1bcaac8150d184f79a27deba2d21983"
+checksum = "c2f718f0335f9ab7437fecf9f3d73ae6a24c03a3d3f46910a68261703d407f03"
dependencies = [
"anyhow",
"dashmap",
@@ -1620,9 +1621,9 @@ dependencies = [
[[package]]
name = "swc_ecma_parser"
-version = "0.67.0"
+version = "0.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0418c8dcb041d74e90c2179290bf3be0e58f2425d1f86843a5e297a13755912"
+checksum = "042a901352b84cefbb64916a010ee33f621a7e341ced2b2fa60035858f3146a5"
dependencies = [
"either",
"enum_kind",
@@ -1641,9 +1642,9 @@ dependencies = [
[[package]]
name = "swc_ecma_preset_env"
-version = "0.38.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "283a609ec84132c2751bdee13a7a81228007206538ef09a1066163602f0d34d8"
+checksum = "7fdb885d7b8ad47fb5f62cff0b36f61d6282b3548a566b8760a800c00de23679"
dependencies = [
"dashmap",
"fxhash",
@@ -1665,9 +1666,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms"
-version = "0.67.0"
+version = "0.71.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c50b45538663ae18d56768c93567312dd5cbf29786678a94cfa610172ba93a4"
+checksum = "b2124504a4203cab8f903b8e8be49dbd6c4bad2b0405ba0c8188f952c224c44b"
dependencies = [
"swc_atoms",
"swc_common",
@@ -1687,9 +1688,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_base"
-version = "0.27.0"
+version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5de480c55ae93eb59715cfc8f66965d192bc62cd4c12e33cff9f940f9431e12"
+checksum = "b26e191df68943565f22059d31b02967e60a62c4f76533b5b5106546785a8e2e"
dependencies = [
"fxhash",
"once_cell",
@@ -1706,9 +1707,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_classes"
-version = "0.13.0"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdcbad381d349cbff95f7602bf2d9ad6a40c7df92a391d4af62221bd0d7633a2"
+checksum = "ad5a845d5ec140ba8580c6b8d0f51ce417b86395a7b74c4280bb6cdae3c042c6"
dependencies = [
"swc_atoms",
"swc_common",
@@ -1720,9 +1721,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_compat"
-version = "0.30.0"
+version = "0.34.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cca0020d15ecb278fcdc4cd55f199f39e0c42ceb9e7f9740416f36120c17ad5"
+checksum = "cda7278fdc9598ec43d40aa795ec7049532194bbcea861dd89bfe0ad3901446d"
dependencies = [
"arrayvec",
"fxhash",
@@ -1757,9 +1758,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_module"
-version = "0.34.0"
+version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac0abb8acb4b72d1ef37971b0bfed8e267ecaab37b3d34bac96205d7b62689e2"
+checksum = "c79229bac86ac213d69c6d5957f9ee281979a9a7c6e5b94ca360a8a4429c6021"
dependencies = [
"Inflector",
"anyhow",
@@ -1779,9 +1780,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_optimization"
-version = "0.37.0"
+version = "0.41.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb3b4c8d2613ce06be5cf8160159eb468117ef6257eba744e1bf18125cca31ad"
+checksum = "ea2600bc3bd557353511cd90b336943ae30e8807bce989a420cb004953fb940a"
dependencies = [
"dashmap",
"fxhash",
@@ -1801,9 +1802,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_proposal"
-version = "0.34.0"
+version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02a8edf26ee1695c0137a829dbb8bb3c6681c1ae55e23ff45e0e0f41308e795f"
+checksum = "637093e49ee993b16fb7bf8918f3d409c986fc77850440a3c779de85d1442cfb"
dependencies = [
"either",
"fxhash",
@@ -1821,9 +1822,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_react"
-version = "0.35.0"
+version = "0.39.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72eabb27291ac7bef4f1f85e3aa7d335138dde1a1606b7d584e7f414882e5f3c"
+checksum = "18bf8799eb49b25f0632b9e60b7871b3f77e18fecb1972e4932ba08005b5c85f"
dependencies = [
"base64 0.13.0",
"dashmap",
@@ -1844,9 +1845,9 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_typescript"
-version = "0.36.0"
+version = "0.40.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc043fd29ceac49f13c1c994ba784f404cca3e189dd6cb771bfe905a0f776592"
+checksum = "98099e3db58fb758715736ea9c8fa68d238e6527f0bfb4a3af0bf7ea063b9162"
dependencies = [
"fxhash",
"serde",
@@ -1861,9 +1862,9 @@ dependencies = [
[[package]]
name = "swc_ecma_utils"
-version = "0.41.3"
+version = "0.44.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50bacaf860e4224e1a12bea8730c94de28f990f92685dad57aa572e3473043f7"
+checksum = "3c811bca37142f7fe21ce800784db1d537645762ffe8d8a52e2a7179d8cc1723"
dependencies = [
"once_cell",
"scoped-tls",
@@ -1876,9 +1877,9 @@ dependencies = [
[[package]]
name = "swc_ecma_visit"
-version = "0.35.2"
+version = "0.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d51ce688b7c984d0325261edb3ced4195790c7ac76982e269d2114ec04e3ae7c"
+checksum = "78c6721dfbcb8bea64383edb0d59ccb02bc1e140024f2e0f8766792a14f5f466"
dependencies = [
"num-bigint",
"swc_atoms",
@@ -1889,9 +1890,9 @@ dependencies = [
[[package]]
name = "swc_ecmascript"
-version = "0.57.0"
+version = "0.63.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e41615d9e65c7b148950211dacd0b2343a646d84493b9c8efa8795ee1a6e2f4f"
+checksum = "ba53c5582d6e5881b093ece9aaa4b561465afab0560abb19948f2c4bbff1bdb9"
dependencies = [
"swc_ecma_ast",
"swc_ecma_codegen",
@@ -1999,9 +2000,9 @@ dependencies = [
[[package]]
name = "tinyvec"
-version = "1.3.1"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
+checksum = "5241dd6f21443a3606b432718b166d3cedc962fd4b8bea54a8bc7f514ebda986"
dependencies = [
"tinyvec_macros",
]
@@ -2020,9 +2021,9 @@ checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
[[package]]
name = "typenum"
-version = "1.13.0"
+version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
+checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
[[package]]
name = "unicode-bidi"
diff --git a/flow-libs/posthtml-parser.js.flow b/flow-libs/posthtml-parser.js.flow
index ae5f4c5d24c..32ae1c9c942 100644
--- a/flow-libs/posthtml-parser.js.flow
+++ b/flow-libs/posthtml-parser.js.flow
@@ -22,5 +22,8 @@ declare module 'posthtml-parser' {
}
) => PostHTMLNode;
- declare module.exports: typeof parser;
+ declare module.exports: {
+ parser: typeof parser;
+ ...
+ }
}
diff --git a/flow-libs/posthtml-render.js.flow b/flow-libs/posthtml-render.js.flow
index be6ab7f4d6e..ad4289c6415 100644
--- a/flow-libs/posthtml-render.js.flow
+++ b/flow-libs/posthtml-render.js.flow
@@ -12,7 +12,7 @@ declare module 'posthtml-render' {
...
};
- declare var parser: (
+ declare var render: (
tree: PostHTMLNode,
options?: {
singleTags?: Array,
@@ -21,5 +21,8 @@ declare module 'posthtml-render' {
}
) => string;
- declare module.exports: typeof parser;
+ declare module.exports: {
+ render: typeof render;
+ ...
+ }
}
diff --git a/package.json b/package.json
index e2e43da8ed5..892dab33b71 100644
--- a/package.json
+++ b/package.json
@@ -43,7 +43,7 @@
"cross-env": "^7.0.0",
"doctoc": "^1.4.0",
"eslint": "^7.20.0",
- "flow-bin": "0.158.0",
+ "flow-bin": "0.160.1",
"glob": "^7.1.6",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
diff --git a/packages/core/core/src/BundleGraph.js b/packages/core/core/src/BundleGraph.js
index b62690d2770..54ae3c0f72f 100644
--- a/packages/core/core/src/BundleGraph.js
+++ b/packages/core/core/src/BundleGraph.js
@@ -64,7 +64,7 @@ export const bundleGraphEdgeTypes = {
internal_async: 5,
};
-type BundleGraphEdgeType = $Values;
+export type BundleGraphEdgeType = $Values;
type InternalSymbolResolution = {|
asset: Asset,
diff --git a/packages/core/core/src/Parcel.js b/packages/core/core/src/Parcel.js
index 9aa0d713faa..70b3b24d79f 100644
--- a/packages/core/core/src/Parcel.js
+++ b/packages/core/core/src/Parcel.js
@@ -31,7 +31,10 @@ import {AbortController} from 'abortcontroller-polyfill/dist/cjs-ponyfill';
import {PromiseQueue} from '@parcel/utils';
import ParcelConfig from './ParcelConfig';
import logger from '@parcel/logger';
-import RequestTracker, {getWatcherOptions} from './RequestTracker';
+import RequestTracker, {
+ getWatcherOptions,
+ requestGraphEdgeTypes,
+} from './RequestTracker';
import createValidationRequest from './requests/ValidationRequest';
import createParcelBuildRequest from './requests/ParcelBuildRequest';
import {Disposable} from '@parcel/events';
@@ -274,8 +277,12 @@ export default class Parcel {
this.#requestedAssetIds.clear();
- // $FlowFixMe
- dumpGraphToGraphViz(this.#requestTracker.graph, 'RequestGraph');
+ dumpGraphToGraphViz(
+ // $FlowFixMe
+ this.#requestTracker.graph,
+ 'RequestGraph',
+ requestGraphEdgeTypes,
+ );
let event = {
type: 'buildSuccess',
diff --git a/packages/core/core/src/RequestTracker.js b/packages/core/core/src/RequestTracker.js
index c705b074609..41def55de58 100644
--- a/packages/core/core/src/RequestTracker.js
+++ b/packages/core/core/src/RequestTracker.js
@@ -59,7 +59,7 @@ export const requestGraphEdgeTypes = {
dirname: 7,
};
-type RequestGraphEdgeType = $Values;
+export type RequestGraphEdgeType = $Values;
type RequestGraphOpts = {|
...ContentGraphOpts,
@@ -70,6 +70,7 @@ type RequestGraphOpts = {|
optionNodeIds: Set,
unpredicatableNodeIds: Set,
|};
+
type SerializedRequestGraph = {|
...SerializedContentGraph,
invalidNodeIds: Set,
diff --git a/packages/core/core/src/dumpGraphToGraphViz.js b/packages/core/core/src/dumpGraphToGraphViz.js
index 1441e5ca3e3..65ec13025cd 100644
--- a/packages/core/core/src/dumpGraphToGraphViz.js
+++ b/packages/core/core/src/dumpGraphToGraphViz.js
@@ -2,6 +2,8 @@
import type {Graph} from '@parcel/graph';
import type {AssetGraphNode, BundleGraphNode, Environment} from './types';
+import {bundleGraphEdgeTypes} from './BundleGraph';
+import {requestGraphEdgeTypes} from './RequestTracker';
import path from 'path';
import {fromProjectPathRelative} from './projectPath';
@@ -32,7 +34,7 @@ export default async function dumpGraphToGraphViz(
// $FlowFixMe
graph: Graph | Graph,
name: string,
- edgeTypes?: any,
+ edgeTypes?: typeof bundleGraphEdgeTypes | typeof requestGraphEdgeTypes,
): Promise {
if (
process.env.PARCEL_BUILD_ENV === 'production' ||
@@ -130,15 +132,20 @@ export default async function dumpGraphToGraphViz(
}
n.set('label', label);
}
+
let edgeNames;
if (edgeTypes) {
edgeNames = Object.fromEntries(
Object.entries(edgeTypes).map(([k, v]) => [v, k]),
);
}
+
for (let edge of graph.getAllEdges()) {
let gEdge = g.addEdge(nodeId(edge.from), nodeId(edge.to));
- let color = edge.type != null ? TYPE_COLORS[edge.type] : null;
+ let color = null;
+ if (edge.type != 1 && edgeNames) {
+ color = TYPE_COLORS[edgeNames[edge.type]];
+ }
if (color != null) {
gEdge.set('color', color);
}
diff --git a/packages/core/core/src/requests/ParcelBuildRequest.js b/packages/core/core/src/requests/ParcelBuildRequest.js
index 56b690afe78..ea5a2a00215 100644
--- a/packages/core/core/src/requests/ParcelBuildRequest.js
+++ b/packages/core/core/src/requests/ParcelBuildRequest.js
@@ -14,6 +14,7 @@ import createBundleGraphRequest from './BundleGraphRequest';
import createWriteBundlesRequest from './WriteBundlesRequest';
import {assertSignalNotAborted} from '../utils';
import dumpGraphToGraphViz from '../dumpGraphToGraphViz';
+import {bundleGraphEdgeTypes} from '../BundleGraph';
type ParcelBuildRequestInput = {|
optionsRef: SharedReference,
@@ -75,7 +76,7 @@ async function run({input, api, options}: RunInput) {
let bundleGraph = await api.runRequest(bundleGraphRequest);
// $FlowFixMe Added in Flow 0.121.0 upgrade in #4381 (Windows only)
- dumpGraphToGraphViz(bundleGraph._graph, 'BundleGraph');
+ dumpGraphToGraphViz(bundleGraph._graph, 'BundleGraph', bundleGraphEdgeTypes);
let writeBundlesRequest = createWriteBundlesRequest({
bundleGraph,
diff --git a/packages/core/core/src/resolveOptions.js b/packages/core/core/src/resolveOptions.js
index b0992beba1d..1ce2e208571 100644
--- a/packages/core/core/src/resolveOptions.js
+++ b/packages/core/core/src/resolveOptions.js
@@ -108,14 +108,14 @@ export default async function resolveOptions(
),
shouldPatchConsole: initialOptions.shouldPatchConsole ?? false,
env: {
- ...process.env,
- ...initialOptions.env,
...(await loadDotEnv(
initialOptions.env ?? {},
inputFS,
path.join(projectRoot, 'index'),
projectRoot,
)),
+ ...process.env,
+ ...initialOptions.env,
},
mode,
shouldAutoInstall: initialOptions.shouldAutoInstall ?? false,
diff --git a/packages/core/graph/src/Graph.js b/packages/core/graph/src/Graph.js
index 5fa0e3ea94b..325296c5378 100644
--- a/packages/core/graph/src/Graph.js
+++ b/packages/core/graph/src/Graph.js
@@ -11,13 +11,13 @@ import nullthrows from 'nullthrows';
export type NullEdgeType = 1;
export type GraphOpts = {|
nodes?: Map,
- adjacencyList?: SerializedAdjacencyList,
+ adjacencyList?: SerializedAdjacencyList,
rootNodeId?: ?NodeId,
|};
export type SerializedGraph = {|
nodes: Map,
- adjacencyList: SerializedAdjacencyList,
+ adjacencyList: SerializedAdjacencyList,
rootNodeId: ?NodeId,
|};
@@ -26,7 +26,7 @@ export const ALL_EDGE_TYPES: AllEdgeTypes = '@@all_edge_types';
export default class Graph {
nodes: Map;
- adjacencyList: AdjacencyList;
+ adjacencyList: AdjacencyList;
rootNodeId: ?NodeId;
constructor(opts: ?GraphOpts) {
diff --git a/packages/core/integration-tests/test/html.js b/packages/core/integration-tests/test/html.js
index 990a8344088..e1fa04cd7f4 100644
--- a/packages/core/integration-tests/test/html.js
+++ b/packages/core/integration-tests/test/html.js
@@ -467,6 +467,38 @@ describe('html', function() {
assert.equal(html.length, 0);
});
+ it('should work with an invalid html file', async function() {
+ let inputFile = path.join(
+ __dirname,
+ '/integration/html-invalid/index.html',
+ );
+ await bundle(inputFile, {
+ defaultTargetOptions: {
+ shouldOptimize: false,
+ },
+ });
+
+ let outputFile = path.join(distDir, 'index.html');
+ let html = await outputFS.readFile(outputFile, 'utf8');
+ assert(html.includes('This is a paragraph'));
+ });
+
+ it("should work with html that doesn't include optional closing tags", async function() {
+ let inputFile = path.join(
+ __dirname,
+ '/integration/html-optional-closing-tags/index.html',
+ );
+ await bundle(inputFile, {
+ defaultTargetOptions: {
+ shouldOptimize: false,
+ },
+ });
+
+ let outputFile = path.join(distDir, 'index.html');
+ let html = await outputFS.readFile(outputFile, 'utf8');
+ assert(html.includes('Paragraph 1'));
+ });
+
it('should read .htmlnanorc.json and minify HTML in production mode', async function() {
await bundle(
path.join(__dirname, '/integration/htmlnano-config/index.html'),
diff --git a/packages/core/integration-tests/test/integration/html-invalid/index.html b/packages/core/integration-tests/test/integration/html-invalid/index.html
new file mode 100644
index 00000000000..60e7ff060bb
--- /dev/null
+++ b/packages/core/integration-tests/test/integration/html-invalid/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+ Invalid HTML file
+
+
+
+
+This is a paragraph.
+
+
+
+
diff --git a/packages/core/integration-tests/test/integration/html-optional-closing-tags/index.html b/packages/core/integration-tests/test/integration/html-optional-closing-tags/index.html
new file mode 100644
index 00000000000..0c6cd109d23
--- /dev/null
+++ b/packages/core/integration-tests/test/integration/html-optional-closing-tags/index.html
@@ -0,0 +1,9 @@
+
+
+Title
+
+Paragraph 1
+
+
+
+Paragraph 2
diff --git a/packages/core/integration-tests/test/integration/sourcemap/.babelrc b/packages/core/integration-tests/test/integration/sourcemap/.babelrc
deleted file mode 100644
index 1320b9a3272..00000000000
--- a/packages/core/integration-tests/test/integration/sourcemap/.babelrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["@babel/preset-env"]
-}
diff --git a/packages/core/integration-tests/test/javascript.js b/packages/core/integration-tests/test/javascript.js
index b9189a79169..e5f3e25ede9 100644
--- a/packages/core/integration-tests/test/javascript.js
+++ b/packages/core/integration-tests/test/javascript.js
@@ -2940,6 +2940,16 @@ describe('javascript', function() {
assert.equal(output, 'productiontest');
});
+ it('should overwrite environment variables from a file if passed', async function() {
+ let b = await bundle(
+ path.join(__dirname, '/integration/env-file/index.js'),
+ {env: {BAR: 'baz'}},
+ );
+
+ let output = await run(b);
+ assert.equal(output, 'barbaz');
+ });
+
it('should error on process.env mutations', async function() {
let filePath = path.join(__dirname, '/integration/env-mutate/index.js');
await assert.rejects(bundle(filePath), {
diff --git a/packages/core/test-utils/package.json b/packages/core/test-utils/package.json
index 8121e6194b2..41746b34ffb 100644
--- a/packages/core/test-utils/package.json
+++ b/packages/core/test-utils/package.json
@@ -21,8 +21,8 @@
"chalk": "^4.1.0",
"ncp": "^2.0.0",
"nullthrows": "^1.1.1",
- "posthtml": "^0.16.4",
- "posthtml-parser": "^0.9.0",
+ "posthtml": "^0.16.5",
+ "posthtml-parser": "^0.10.1",
"resolve": "^1.12.0",
"ws": "^7.0.0"
}
diff --git a/packages/core/test-utils/src/utils.js b/packages/core/test-utils/src/utils.js
index 2177941ff20..e513992b8b0 100644
--- a/packages/core/test-utils/src/utils.js
+++ b/packages/core/test-utils/src/utils.js
@@ -24,7 +24,7 @@ import path from 'path';
import url from 'url';
import WebSocket from 'ws';
import nullthrows from 'nullthrows';
-import postHtmlParse from 'posthtml-parser';
+import {parser as postHtmlParse} from 'posthtml-parser';
import postHtml from 'posthtml';
import EventEmitter from 'events';
diff --git a/packages/optimizers/htmlnano/package.json b/packages/optimizers/htmlnano/package.json
index 6fd2a73bd24..6c738f9ff61 100644
--- a/packages/optimizers/htmlnano/package.json
+++ b/packages/optimizers/htmlnano/package.json
@@ -23,7 +23,7 @@
"@parcel/plugin": "2.0.0-rc.0",
"htmlnano": "^1.0.1",
"nullthrows": "^1.1.1",
- "posthtml": "^0.16.4",
+ "posthtml": "^0.16.5",
"svgo": "^2.4.0"
}
}
diff --git a/packages/packagers/html/package.json b/packages/packagers/html/package.json
index 6123c6495fe..3ad37a5bf89 100644
--- a/packages/packagers/html/package.json
+++ b/packages/packagers/html/package.json
@@ -24,6 +24,6 @@
"@parcel/types": "2.0.0-rc.0",
"@parcel/utils": "2.0.0-rc.0",
"nullthrows": "^1.1.1",
- "posthtml": "^0.16.4"
+ "posthtml": "^0.16.5"
}
}
diff --git a/packages/reporters/cli/src/CLIReporter.js b/packages/reporters/cli/src/CLIReporter.js
index 3f08065018d..246f8175e5b 100644
--- a/packages/reporters/cli/src/CLIReporter.js
+++ b/packages/reporters/cli/src/CLIReporter.js
@@ -200,7 +200,7 @@ async function writeDiagnostic(
writeOut(indentString(codeframe, indent), isError);
}
- if ((stack || codeframe) && hints.length > 0) {
+ if ((stack || codeframe) && (hints.length > 0 || documentation)) {
writeOut('');
}
diff --git a/packages/runtimes/hmr/src/loaders/hmr-runtime.js b/packages/runtimes/hmr/src/loaders/hmr-runtime.js
index 53e2793f9a3..4b8da0d14d1 100644
--- a/packages/runtimes/hmr/src/loaders/hmr-runtime.js
+++ b/packages/runtimes/hmr/src/loaders/hmr-runtime.js
@@ -95,7 +95,9 @@ if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
if (data.type === 'update') {
// Remove error overlay if there is one
- removeErrorOverlay();
+ if (typeof document !== 'undefined') {
+ removeErrorOverlay();
+ }
let assets = data.assets.filter(asset => asset.envHash === HMR_ENV_HASH);
@@ -143,11 +145,13 @@ if ((!parent || !parent.isParcelRequire) && typeof WebSocket !== 'undefined') {
);
}
- // Render the fancy html overlay
- removeErrorOverlay();
- var overlay = createErrorOverlay(data.diagnostics.html);
- // $FlowFixMe
- document.body.appendChild(overlay);
+ if (typeof document !== 'undefined') {
+ // Render the fancy html overlay
+ removeErrorOverlay();
+ var overlay = createErrorOverlay(data.diagnostics.html);
+ // $FlowFixMe
+ document.body.appendChild(overlay);
+ }
}
};
ws.onerror = function(e) {
diff --git a/packages/transformers/html/package.json b/packages/transformers/html/package.json
index a80b37e1773..b1eb1ad5fd5 100644
--- a/packages/transformers/html/package.json
+++ b/packages/transformers/html/package.json
@@ -23,9 +23,9 @@
"@parcel/hash": "2.0.0-rc.0",
"@parcel/plugin": "2.0.0-rc.0",
"nullthrows": "^1.1.1",
- "posthtml": "^0.16.4",
- "posthtml-parser": "^0.9.0",
- "posthtml-render": "^2.0.6",
+ "posthtml": "^0.16.5",
+ "posthtml-parser": "^0.10.1",
+ "posthtml-render": "^3.0.0",
"semver": "^5.4.1"
}
}
diff --git a/packages/transformers/html/src/HTMLTransformer.js b/packages/transformers/html/src/HTMLTransformer.js
index 13b85e80dce..db7bf863f25 100644
--- a/packages/transformers/html/src/HTMLTransformer.js
+++ b/packages/transformers/html/src/HTMLTransformer.js
@@ -1,9 +1,9 @@
// @flow
import {Transformer} from '@parcel/plugin';
-import parse from 'posthtml-parser';
+import {parser as parse} from 'posthtml-parser';
import nullthrows from 'nullthrows';
-import render from 'posthtml-render';
+import {render} from 'posthtml-render';
import semver from 'semver';
import collectDependencies from './dependencies';
import extractInlineAssets from './inline';
diff --git a/packages/transformers/js/core/Cargo.toml b/packages/transformers/js/core/Cargo.toml
index 279d45252d5..27af8cd6b8f 100644
--- a/packages/transformers/js/core/Cargo.toml
+++ b/packages/transformers/js/core/Cargo.toml
@@ -8,10 +8,10 @@ edition = "2018"
crate-type = ["rlib"]
[dependencies]
-swc_ecmascript = { version = "0.57.0", features = ["parser", "transforms", "module", "optimization", "react", "typescript", "utils", "visit", "codegen", "utils"] }
-swc_ecma_preset_env = "0.38.0"
-swc_common = { version = "0.11.6", features = ["tty-emitter", "sourcemap"] }
-swc_atoms = "0.2.6"
+swc_ecmascript = { version = "0.63.1", features = ["parser", "transforms", "module", "optimization", "react", "typescript", "utils", "visit", "codegen", "utils"] }
+swc_ecma_preset_env = "0.42.1"
+swc_common = { version = "0.12.1", features = ["tty-emitter", "sourcemap"] }
+swc_atoms = "0.2.7"
indoc = "1.0.3"
serde = "1.0.123"
serde_bytes = "0.11.5"
diff --git a/packages/transformers/js/core/src/fs.rs b/packages/transformers/js/core/src/fs.rs
index 836c4366313..b0c33849edc 100644
--- a/packages/transformers/js/core/src/fs.rs
+++ b/packages/transformers/js/core/src/fs.rs
@@ -26,7 +26,13 @@ pub fn inline_fs<'a>(
) -> impl Fold + 'a {
InlineFS {
filename: Path::new(filename).to_path_buf(),
- collect: Collect::new(source_map, decls, Mark::fresh(Mark::root()), global_mark),
+ collect: Collect::new(
+ source_map,
+ decls,
+ Mark::fresh(Mark::root()),
+ global_mark,
+ false,
+ ),
global_mark,
project_root,
deps,
diff --git a/packages/transformers/js/core/src/hoist.rs b/packages/transformers/js/core/src/hoist.rs
index 02b5d1d5972..e114daaead7 100644
--- a/packages/transformers/js/core/src/hoist.rs
+++ b/packages/transformers/js/core/src/hoist.rs
@@ -8,8 +8,8 @@ use swc_ecmascript::ast::*;
use swc_ecmascript::visit::{Fold, FoldWith, Node, Visit, VisitWith};
use crate::utils::{
- match_import, match_member_expr, match_require, CodeHighlight, Diagnostic, DiagnosticSeverity,
- SourceLocation,
+ match_import, match_member_expr, match_require, Bailout, BailoutReason, CodeHighlight,
+ Diagnostic, DiagnosticSeverity, SourceLocation,
};
type IdentId = (JsWord, SyntaxContext);
@@ -34,8 +34,9 @@ pub fn hoist(
decls: HashSet,
ignore_mark: Mark,
global_mark: Mark,
-) -> Result<(Module, HoistResult), Vec> {
- let mut collect = Collect::new(source_map, decls, ignore_mark, global_mark);
+ trace_bailouts: bool,
+) -> Result<(Module, HoistResult, Vec), Vec> {
+ let mut collect = Collect::new(source_map, decls, ignore_mark, global_mark, trace_bailouts);
module.visit_with(&Invalid { span: DUMMY_SP } as _, &mut collect);
let mut hoist = Hoist::new(module_id, &collect);
@@ -44,7 +45,14 @@ pub fn hoist(
return Err(hoist.diagnostics);
}
- Ok((module, hoist.get_result()))
+ if let Some(bailouts) = &collect.bailouts {
+ hoist
+ .diagnostics
+ .extend(bailouts.iter().map(|bailout| bailout.to_diagnostic()));
+ }
+
+ let diagnostics = std::mem::take(&mut hoist.diagnostics);
+ Ok((module, hoist.get_result(), diagnostics))
}
struct Hoist<'a> {
@@ -554,7 +562,7 @@ impl<'a> Fold for Hoist<'a> {
// If there are any non-static accesses of the namespace, don't perform any replacement.
// This will be handled in the Ident visitor below, which replaces y -> $id$import$10b1f2ceae7ab64e.
if specifier == "*"
- && !self.collect.non_static_access.contains(&id!(ident))
+ && !self.collect.non_static_access.contains_key(&id!(ident))
&& !self.collect.non_const_bindings.contains_key(&id!(ident))
&& !self.collect.non_static_requires.contains(source)
{
@@ -771,7 +779,7 @@ impl<'a> Fold for Hoist<'a> {
self
.imported_symbols
.insert(name, (source.clone(), specifier.clone(), loc.clone()));
- } else if self.collect.non_static_access.contains(&id!(node)) {
+ } else if self.collect.non_static_access.contains_key(&id!(node)) {
let name: JsWord =
format!("${}$importAsync${:x}", self.module_id, hash!(source)).into();
self
@@ -1101,7 +1109,7 @@ pub struct Collect {
should_wrap: bool,
pub imports: HashMap,
exports: HashMap,
- non_static_access: HashSet,
+ non_static_access: HashMap>,
non_const_bindings: HashMap>,
non_static_requires: HashSet,
wrapped_requires: HashSet,
@@ -1110,6 +1118,7 @@ pub struct Collect {
in_export_decl: bool,
in_function: bool,
in_assign: bool,
+ bailouts: Option>,
}
impl Collect {
@@ -1118,6 +1127,7 @@ impl Collect {
decls: HashSet,
ignore_mark: Mark,
global_mark: Mark,
+ trace_bailouts: bool,
) -> Self {
Collect {
source_map,
@@ -1130,7 +1140,7 @@ impl Collect {
should_wrap: false,
imports: HashMap::new(),
exports: HashMap::new(),
- non_static_access: HashSet::new(),
+ non_static_access: HashMap::new(),
non_const_bindings: HashMap::new(),
non_static_requires: HashSet::new(),
wrapped_requires: HashSet::new(),
@@ -1139,6 +1149,7 @@ impl Collect {
in_export_decl: false,
in_function: false,
in_assign: false,
+ bailouts: if trace_bailouts { Some(vec![]) } else { None },
}
}
}
@@ -1150,6 +1161,21 @@ impl Visit for Collect {
self.in_function = false;
node.visit_children_with(self);
self.in_module_this = false;
+
+ if let Some(bailouts) = &mut self.bailouts {
+ for key in self.imports.keys() {
+ if let Some(spans) = self.non_static_access.get(key) {
+ for span in spans {
+ bailouts.push(Bailout {
+ loc: SourceLocation::from(&self.source_map, *span),
+ reason: BailoutReason::NonStaticAccess,
+ })
+ }
+ }
+ }
+
+ bailouts.sort_by(|a, b| a.loc.partial_cmp(&b.loc).unwrap());
+ }
}
collect_visit_fn!(visit_function, Function);
@@ -1317,6 +1343,7 @@ impl Visit for Collect {
fn visit_return_stmt(&mut self, node: &ReturnStmt, _parent: &dyn Node) {
if !self.in_function {
self.should_wrap = true;
+ self.add_bailout(node.span, BailoutReason::TopLevelReturn);
}
node.visit_children_with(self)
@@ -1378,6 +1405,7 @@ impl Visit for Collect {
self.has_cjs_exports = true;
if !is_static {
self.static_cjs_exports = false;
+ self.add_bailout(node.span, BailoutReason::NonStaticExports);
}
}
return;
@@ -1387,7 +1415,8 @@ impl Visit for Collect {
if ident.sym == exports && !self.decls.contains(&id!(ident)) {
self.has_cjs_exports = true;
if !is_static {
- self.static_cjs_exports = false
+ self.static_cjs_exports = false;
+ self.add_bailout(node.span, BailoutReason::NonStaticExports);
}
}
@@ -1395,11 +1424,16 @@ impl Visit for Collect {
self.has_cjs_exports = true;
self.static_cjs_exports = false;
self.should_wrap = true;
+ self.add_bailout(node.span, BailoutReason::FreeModule);
}
// `import` isn't really an identifier...
if !is_static && ident.sym != js_word!("import") {
- self.non_static_access.insert(id!(ident));
+ self
+ .non_static_access
+ .entry(id!(ident))
+ .or_default()
+ .push(node.span);
}
return;
}
@@ -1408,6 +1442,7 @@ impl Visit for Collect {
self.has_cjs_exports = true;
if !is_static {
self.static_cjs_exports = false;
+ self.add_bailout(node.span, BailoutReason::NonStaticExports);
}
}
return;
@@ -1439,11 +1474,21 @@ impl Visit for Collect {
// declaration. We need to wrap the referenced module to preserve side effect ordering.
if let Some(source) = self.match_require(node) {
self.wrapped_requires.insert(source);
+ let span = match node {
+ Expr::Call(c) => c.span,
+ _ => unreachable!(),
+ };
+ self.add_bailout(span, BailoutReason::NonTopLevelRequire);
}
if let Some(source) = match_import(node, self.ignore_mark) {
self.non_static_requires.insert(source.clone());
self.wrapped_requires.insert(source);
+ let span = match node {
+ Expr::Call(c) => c.span,
+ _ => unreachable!(),
+ };
+ self.add_bailout(span, BailoutReason::NonStaticDynamicImport);
}
match node {
@@ -1457,12 +1502,19 @@ impl Visit for Collect {
self.static_cjs_exports = false;
if is_module {
self.should_wrap = true;
+ self.add_bailout(ident.span, BailoutReason::FreeModule);
+ } else {
+ self.add_bailout(ident.span, BailoutReason::FreeExports);
}
}
// `import` isn't really an identifier...
if ident.sym != js_word!("import") {
- self.non_static_access.insert(id!(ident));
+ self
+ .non_static_access
+ .entry(id!(ident))
+ .or_default()
+ .push(ident.span);
}
}
_ => {
@@ -1471,10 +1523,11 @@ impl Visit for Collect {
}
}
- fn visit_this_expr(&mut self, _node: &ThisExpr, _parent: &dyn Node) {
+ fn visit_this_expr(&mut self, node: &ThisExpr, _parent: &dyn Node) {
if self.in_module_this {
self.has_cjs_exports = true;
self.static_cjs_exports = false;
+ self.add_bailout(node.span, BailoutReason::FreeExports);
}
}
@@ -1504,6 +1557,13 @@ impl Visit for Collect {
self.static_cjs_exports = false;
self.has_cjs_exports = true;
self.should_wrap = true;
+ self.add_bailout(node.span, BailoutReason::ExportsReassignment);
+ } else if has_binding_identifier(pat, &"module".into(), &self.decls) {
+ // Same for `module`. If it is reassigned we can't correctly statically analyze.
+ self.static_cjs_exports = false;
+ self.has_cjs_exports = true;
+ self.should_wrap = true;
+ self.add_bailout(node.span, BailoutReason::ModuleReassignment);
}
}
}
@@ -1582,7 +1642,8 @@ impl Visit for Collect {
match &**expr {
Expr::Ident(ident) => {
if ident.sym == js_word!("eval") && !self.decls.contains(&id!(ident)) {
- self.should_wrap = true
+ self.should_wrap = true;
+ self.add_bailout(node.span, BailoutReason::Eval);
}
}
Expr::Member(member) => {
@@ -1609,6 +1670,7 @@ impl Visit for Collect {
} else {
self.non_static_requires.insert(source.clone());
self.wrapped_requires.insert(source);
+ self.add_bailout(node.span, BailoutReason::NonStaticDynamicImport);
}
expr.visit_with(node, self);
@@ -1636,6 +1698,16 @@ impl Collect {
self.wrapped_requires.insert(src.clone());
if kind != ImportKind::DynamicImport {
self.non_static_requires.insert(src.clone());
+ let span = match node {
+ Pat::Ident(id) => id.id.span,
+ Pat::Array(arr) => arr.span,
+ Pat::Object(obj) => obj.span,
+ Pat::Rest(rest) => rest.span,
+ Pat::Assign(assign) => assign.span,
+ Pat::Invalid(i) => i.span,
+ Pat::Expr(_) => DUMMY_SP,
+ };
+ self.add_bailout(span, BailoutReason::NonTopLevelRequire);
}
}
@@ -1663,6 +1735,7 @@ impl Collect {
_ => {
// Non-static. E.g. computed property.
self.non_static_requires.insert(src.clone());
+ self.add_bailout(object.span, BailoutReason::NonStaticDestructuring);
continue;
}
};
@@ -1692,6 +1765,7 @@ impl Collect {
_ => {
// Non-static.
self.non_static_requires.insert(src.clone());
+ self.add_bailout(object.span, BailoutReason::NonStaticDestructuring);
}
}
}
@@ -1718,6 +1792,7 @@ impl Collect {
// let {x, ...y} = require('y');
// Non-static. We don't know what keys are used.
self.non_static_requires.insert(src.clone());
+ self.add_bailout(object.span, BailoutReason::NonStaticDestructuring);
}
}
}
@@ -1725,6 +1800,16 @@ impl Collect {
_ => {
// Non-static.
self.non_static_requires.insert(src.clone());
+ let span = match node {
+ Pat::Ident(id) => id.id.span,
+ Pat::Array(arr) => arr.span,
+ Pat::Object(obj) => obj.span,
+ Pat::Rest(rest) => rest.span,
+ Pat::Assign(assign) => assign.span,
+ Pat::Invalid(i) => i.span,
+ Pat::Expr(_) => DUMMY_SP,
+ };
+ self.add_bailout(span, BailoutReason::NonStaticDestructuring);
}
}
}
@@ -1761,6 +1846,15 @@ impl Collect {
_ => {}
}
}
+
+ fn add_bailout(&mut self, span: Span, reason: BailoutReason) {
+ if let Some(bailouts) = &mut self.bailouts {
+ bailouts.push(Bailout {
+ loc: SourceLocation::from(&self.source_map, span),
+ reason,
+ })
+ }
+ }
}
fn has_binding_identifier(node: &Pat, sym: &JsWord, decls: &HashSet) -> bool {
@@ -1847,6 +1941,7 @@ mod tests {
collect_decls(&module),
Mark::fresh(Mark::root()),
global_mark,
+ false,
);
module.visit_with(&Invalid { span: DUMMY_SP } as _, &mut collect);
@@ -1990,7 +2085,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), false) }
);
- assert_eq!(collect.non_static_access, set! {});
+ assert_eq!(collect.non_static_access, map! {});
let (_collect, _code, hoist) = parse(
r#"
@@ -2012,7 +2107,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), false) }
);
- assert_eq_set!(collect.non_static_access, set! { w!("x") });
+ assert_eq_set!(collect.non_static_access.into_keys(), set! { w!("x") });
let (collect, _code, _hoist) = parse(
r#"
@@ -2024,7 +2119,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), false) }
);
- assert_eq_set!(collect.non_static_access, set! { w!("x") });
+ assert_eq_set!(collect.non_static_access.into_keys(), set! { w!("x") });
}
#[test]
@@ -2050,6 +2145,13 @@ mod tests {
"#,
);
assert!(collect.should_wrap);
+
+ let (collect, _code, _hoist) = parse(
+ r#"
+ module = 2;
+ "#,
+ );
+ assert!(collect.should_wrap);
}
#[test]
@@ -2228,7 +2330,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), true) }
);
- assert_eq_set!(collect.non_static_access, set! {});
+ assert_eq_set!(collect.non_static_access.into_keys(), set! {});
assert_eq!(collect.non_static_requires, set! {});
assert_eq!(collect.wrapped_requires, set! {w!("other")});
@@ -2244,7 +2346,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), true) }
);
- assert_eq_set!(collect.non_static_access, set! { w!("x") });
+ assert_eq_set!(collect.non_static_access.into_keys(), set! { w!("x") });
assert_eq!(collect.non_static_requires, set! {});
assert_eq!(collect.wrapped_requires, set! {w!("other")});
@@ -2285,7 +2387,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), true) }
);
- assert_eq_set!(collect.non_static_access, set! {});
+ assert_eq_set!(collect.non_static_access.into_keys(), set! {});
assert_eq!(collect.non_static_requires, set! {});
assert_eq!(collect.wrapped_requires, set! {w!("other")});
@@ -2298,7 +2400,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), true) }
);
- assert_eq_set!(collect.non_static_access, set! { w!("x") });
+ assert_eq_set!(collect.non_static_access.into_keys(), set! { w!("x") });
assert_eq!(collect.non_static_requires, set! {});
assert_eq!(collect.wrapped_requires, set! {w!("other")});
@@ -2335,7 +2437,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), true) }
);
- assert_eq_set!(collect.non_static_access, set! {});
+ assert_eq_set!(collect.non_static_access.into_keys(), set! {});
assert_eq!(collect.non_static_requires, set! {});
assert_eq!(collect.wrapped_requires, set! {w!("other")});
@@ -2348,7 +2450,7 @@ mod tests {
collect.imports,
map! { w!("x") => (w!("other"), w!("*"), true) }
);
- assert_eq_set!(collect.non_static_access, set! { w!("x") });
+ assert_eq_set!(collect.non_static_access.into_keys(), set! { w!("x") });
assert_eq!(collect.non_static_requires, set! {});
assert_eq!(collect.wrapped_requires, set! {w!("other")});
diff --git a/packages/transformers/js/core/src/lib.rs b/packages/transformers/js/core/src/lib.rs
index 280d68a22ca..112cb43974b 100644
--- a/packages/transformers/js/core/src/lib.rs
+++ b/packages/transformers/js/core/src/lib.rs
@@ -83,6 +83,7 @@ pub struct Config {
supports_module_workers: bool,
is_library: bool,
is_esm_output: bool,
+ trace_bailouts: bool,
}
#[derive(Serialize, Debug, Deserialize, Default)]
@@ -381,10 +382,12 @@ pub fn transform(config: Config) -> Result {
decls,
ignore_mark,
global_mark,
+ config.trace_bailouts,
);
match res {
- Ok((module, hoist_result)) => {
+ Ok((module, hoist_result, hoist_diagnostics)) => {
result.hoist_result = Some(hoist_result);
+ diagnostics.extend(hoist_diagnostics);
module
}
Err(diagnostics) => {
diff --git a/packages/transformers/js/core/src/utils.rs b/packages/transformers/js/core/src/utils.rs
index 6b55938e4ab..34d22c05017 100644
--- a/packages/transformers/js/core/src/utils.rs
+++ b/packages/transformers/js/core/src/utils.rs
@@ -1,3 +1,4 @@
+use std::cmp::Ordering;
use std::collections::HashSet;
use serde::{Deserialize, Serialize};
@@ -170,6 +171,18 @@ impl SourceLocation {
}
}
+impl PartialOrd for SourceLocation {
+ fn partial_cmp(&self, other: &SourceLocation) -> Option {
+ if self.start_line < other.start_line {
+ Some(Ordering::Less)
+ } else if self.start_line == other.start_line {
+ self.start_col.partial_cmp(&other.start_col)
+ } else {
+ Some(Ordering::Greater)
+ }
+ }
+}
+
#[derive(Serialize, Deserialize, Debug)]
pub struct CodeHighlight {
pub message: Option,
@@ -201,3 +214,90 @@ pub enum SourceType {
Script,
Module,
}
+
+pub struct Bailout {
+ pub loc: SourceLocation,
+ pub reason: BailoutReason,
+}
+
+impl Bailout {
+ pub fn to_diagnostic(&self) -> Diagnostic {
+ let (message, documentation_url) = self.reason.info();
+ Diagnostic {
+ message: message.into(),
+ documentation_url: Some(documentation_url.into()),
+ code_highlights: Some(vec![CodeHighlight {
+ loc: self.loc.clone(),
+ message: None,
+ }]),
+ show_environment: false,
+ severity: DiagnosticSeverity::Warning,
+ hints: None,
+ }
+ }
+}
+
+pub enum BailoutReason {
+ NonTopLevelRequire,
+ NonStaticDestructuring,
+ TopLevelReturn,
+ Eval,
+ NonStaticExports,
+ FreeModule,
+ FreeExports,
+ ExportsReassignment,
+ ModuleReassignment,
+ NonStaticDynamicImport,
+ NonStaticAccess,
+}
+
+impl BailoutReason {
+ fn info(&self) -> (&str, &str) {
+ match self {
+ BailoutReason::NonTopLevelRequire => (
+ "Conditional or non-top-level `require()` call. This causes the resolved module and all dependendencies to be wrapped.",
+ "https://v2.parceljs.org/features/scope-hoisting/#avoid-conditional-require()"
+ ),
+ BailoutReason::NonStaticDestructuring => (
+ "Non-static destructuring of `require` or dynamic `import()`. This causes all exports of the resolved module to be included.",
+ "https://v2.parceljs.org/features/scope-hoisting/#commonjs"
+ ),
+ BailoutReason::TopLevelReturn => (
+ "Module contains a top-level `return` statement. This causes the module to be wrapped in a function and tree shaking to be disabled.",
+ "https://v2.parceljs.org/features/scope-hoisting/#avoid-top-level-return"
+ ),
+ BailoutReason::Eval => (
+ "Module contains usage of `eval`. This causes the module to be wrapped in a function and minification to be disabled.",
+ "https://v2.parceljs.org/features/scope-hoisting/#avoid-eval"
+ ),
+ BailoutReason::NonStaticExports => (
+ "Non-static access of CommonJS `exports` object. This causes tree shaking to be disabled for the module.",
+ "https://v2.parceljs.org/features/scope-hoisting/#commonjs"
+ ),
+ BailoutReason::FreeModule => (
+ "Unknown usage of CommonJS `module` object. This causes the module to be wrapped, and tree shaking to be disabled.",
+ "https://v2.parceljs.org/features/scope-hoisting/#commonjs"
+ ),
+ BailoutReason::FreeExports => (
+ "Unknown usage of CommonJS `exports` object. This causes tree shaking to be disabled.",
+ "https://v2.parceljs.org/features/scope-hoisting/#commonjs"
+ ),
+ BailoutReason::ExportsReassignment => (
+ "Module contains a reassignment of the CommonJS `exports` object. This causes the module to be wrapped and tree-shaking to be disabled.",
+ "https://v2.parceljs.org/features/scope-hoisting/#avoid-module-and-exports-re-assignment"
+ ),
+ BailoutReason::ModuleReassignment => (
+ "Module contains a reassignment of the CommonJS `module` object. This causes the module to be wrapped and tree-shaking to be disabled.",
+ "https://v2.parceljs.org/features/scope-hoisting/#avoid-module-and-exports-re-assignment"
+ ),
+ BailoutReason::NonStaticDynamicImport => (
+ "Unknown dynamic import usage. This causes tree shaking to be disabled for the resolved module.",
+ "https://v2.parceljs.org/features/scope-hoisting/#dynamic-imports"
+ ),
+ BailoutReason::NonStaticAccess => (
+ "Non-static access of an `import` or `require`. This causes tree shaking to be disabled for the resolved module.",
+ "https://v2.parceljs.org/features/scope-hoisting/#dynamic-member-accesses"
+ ),
+ }
+ }
+}
diff --git a/packages/transformers/js/src/JSTransformer.js b/packages/transformers/js/src/JSTransformer.js
index 87b28c401f1..4a3eee31836 100644
--- a/packages/transformers/js/src/JSTransformer.js
+++ b/packages/transformers/js/src/JSTransformer.js
@@ -400,6 +400,7 @@ export default (new Transformer({
supports_module_workers: supportsModuleWorkers,
is_library: asset.env.isLibrary,
is_esm_output: asset.env.outputFormat === 'esmodule',
+ trace_bailouts: options.logLevel === 'verbose',
});
let convertLoc = loc => {
diff --git a/packages/transformers/posthtml/package.json b/packages/transformers/posthtml/package.json
index 64f138a57ae..b9180495d18 100644
--- a/packages/transformers/posthtml/package.json
+++ b/packages/transformers/posthtml/package.json
@@ -23,9 +23,9 @@
"@parcel/plugin": "2.0.0-rc.0",
"@parcel/utils": "2.0.0-rc.0",
"nullthrows": "^1.1.1",
- "posthtml": "^0.16.4",
- "posthtml-parser": "^0.9.0",
- "posthtml-render": "^2.0.6",
+ "posthtml": "^0.16.5",
+ "posthtml-parser": "^0.10.1",
+ "posthtml-render": "^3.0.0",
"semver": "^5.4.1"
}
}
diff --git a/packages/transformers/posthtml/src/PostHTMLTransformer.js b/packages/transformers/posthtml/src/PostHTMLTransformer.js
index c3767d1c175..49d3b3f7606 100644
--- a/packages/transformers/posthtml/src/PostHTMLTransformer.js
+++ b/packages/transformers/posthtml/src/PostHTMLTransformer.js
@@ -4,8 +4,8 @@ import {Transformer} from '@parcel/plugin';
import path from 'path';
import posthtml from 'posthtml';
-import parse from 'posthtml-parser';
-import render from 'posthtml-render';
+import {parser as parse} from 'posthtml-parser';
+import {render} from 'posthtml-render';
import nullthrows from 'nullthrows';
import semver from 'semver';
import {relativePath} from '@parcel/utils';
diff --git a/packages/transformers/svg/package.json b/packages/transformers/svg/package.json
index 86db0487877..6d83419813f 100644
--- a/packages/transformers/svg/package.json
+++ b/packages/transformers/svg/package.json
@@ -23,9 +23,9 @@
"@parcel/hash": "2.0.0-rc.0",
"@parcel/plugin": "2.0.0-rc.0",
"nullthrows": "^1.1.1",
- "posthtml": "^0.16.4",
- "posthtml-parser": "^0.9.0",
- "posthtml-render": "^2.0.6",
+ "posthtml": "^0.16.5",
+ "posthtml-parser": "^0.10.1",
+ "posthtml-render": "^3.0.0",
"semver": "^5.4.1"
}
}
diff --git a/packages/transformers/svg/src/SVGTransformer.js b/packages/transformers/svg/src/SVGTransformer.js
index 21667f797de..2ad54bb13a3 100644
--- a/packages/transformers/svg/src/SVGTransformer.js
+++ b/packages/transformers/svg/src/SVGTransformer.js
@@ -3,8 +3,8 @@
import {Transformer} from '@parcel/plugin';
import nullthrows from 'nullthrows';
import semver from 'semver';
-import parse from 'posthtml-parser';
-import render from 'posthtml-render';
+import {parser as parse} from 'posthtml-parser';
+import {render} from 'posthtml-render';
import collectDependencies from './dependencies';
import extractInlineAssets from './inline';
diff --git a/yarn.lock b/yarn.lock
index 24cfacb8237..c4176549c41 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5029,6 +5029,13 @@ domhandler@^4.0.0, domhandler@^4.2.0:
dependencies:
domelementtype "^2.2.0"
+domhandler@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f"
+ integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==
+ dependencies:
+ domelementtype "^2.2.0"
+
domutils@^1.5.1, domutils@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
@@ -6083,10 +6090,10 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
-flow-bin@0.158.0:
- version "0.158.0"
- resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.158.0.tgz#0a09763d41eb8ec7135ced6a3b9f8fa370a393d8"
- integrity sha512-Gk5md8XTwk/M+J5M+rFyS1LJfFen6ldY60jM9+meWixlKf4b0vwdoUO8R7oo471pze+GY+blrnskUeqLDxFJfg==
+flow-bin@0.160.1:
+ version "0.160.1"
+ resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.160.1.tgz#ae24ad6def1f05ae37789b6cc332b58975d29de0"
+ integrity sha512-LvQ9lB/vwW+lPjYIyACcGQCSLvL9f9hOM9jJJtfHQRrIgIShWqjvyv5V24M57HSxh0+6dBbVDYhUiZjjeArf7A==
flush-write-stream@^1.0.0, flush-write-stream@^1.0.2:
version "1.1.1"
@@ -7046,12 +7053,12 @@ htmlparser2@^6.0.0:
entities "^2.0.0"
htmlparser2@^7.1.1:
- version "7.1.1"
- resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.1.1.tgz#ef251d16e5b40818ba162aa24bc051c297eb3f76"
- integrity sha512-hZb0lfG0hbhR/hB879zbBr8Opv0Be9Zp+JYHgqTw5epF++aotu/zmMTPLy/60iJyR1MaD/3pYRp7xYteXsZMEA==
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.1.2.tgz#587923d38f03bc89e03076e00cba2c7473f37f7c"
+ integrity sha512-d6cqsbJba2nRdg8WW2okyD4ceonFHn9jLFxhwlNcLhQWcFPdxXeJulgOLjLKtAK9T6ahd+GQNZwG9fjmGW7lyg==
dependencies:
domelementtype "^2.0.1"
- domhandler "^4.0.0"
+ domhandler "^4.2.2"
domutils "^2.8.0"
entities "^3.0.1"
@@ -10546,7 +10553,7 @@ posthtml-obfuscate@^0.1.5:
resolved "https://registry.yarnpkg.com/posthtml-obfuscate/-/posthtml-obfuscate-0.1.5.tgz#d65f6642c96349002d33a2208845b2f7517d0fc8"
integrity sha1-1l9mQsljSQAtM6IgiEWy91F9D8g=
-posthtml-parser@^0.10.0:
+posthtml-parser@^0.10.0, posthtml-parser@^0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.10.1.tgz#63c41931a9339cc2c32aba14f06286d98f107abf"
integrity sha512-i7w2QEHqiGtsvNNPty0Mt/+ERch7wkgnFh3+JnBI2VgDbGlBqKW9eDVd3ENUhE1ujGFe3e3E/odf7eKhvLUyDg==