From 6dc8e68c496f61dd31de3f1d753f9bc976845f7a Mon Sep 17 00:00:00 2001
From: Devon Govett
Date: Mon, 13 Sep 2021 22:12:08 -0700
Subject: [PATCH 1/7] Print diagnostics for scope hoisting bailouts at verbose
log level (#6918)
---
packages/reporters/cli/src/CLIReporter.js | 2 +-
packages/transformers/js/core/src/fs.rs | 8 +-
packages/transformers/js/core/src/hoist.rs | 148 +++++++++++++++---
packages/transformers/js/core/src/lib.rs | 5 +-
packages/transformers/js/core/src/utils.rs | 100 ++++++++++++
packages/transformers/js/src/JSTransformer.js | 1 +
6 files changed, 238 insertions(+), 26 deletions(-)
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/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 => {
From 6f6759e5c2140aa8d7c3be70d56432258439ff19 Mon Sep 17 00:00:00 2001
From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Date: Wed, 15 Sep 2021 06:45:01 +0200
Subject: [PATCH 2/7] Bump swc (#6848)
---
Cargo.lock | 149 +++++++++---------
.../test/integration/sourcemap/.babelrc | 3 -
packages/transformers/js/core/Cargo.toml | 8 +-
3 files changed, 79 insertions(+), 81 deletions(-)
delete mode 100644 packages/core/integration-tests/test/integration/sourcemap/.babelrc
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/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/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"
From b9294c48bdbf8b7603c112c9a324d9dfe83d2a93 Mon Sep 17 00:00:00 2001
From: Brian Do
Date: Wed, 15 Sep 2021 18:05:01 -0700
Subject: [PATCH 3/7] Change edge types to numbers (#6126)
* change edgetypes to numbers
* clean up comments
* fix edge colors in graphviz
* camelCase edge type objects
* add NullEdgeType to generic in Array edge types
* Change NullEdgeType to 1
* Fix colors in graphviz
* Fix types
Co-authored-by: Devon Govett
Co-authored-by: Eric Eldredge
---
packages/core/core/src/BundleGraph.js | 196 +++++++++++++-----
packages/core/core/src/Parcel.js | 13 +-
packages/core/core/src/RequestTracker.js | 194 +++++++++++++----
packages/core/core/src/applyRuntimes.js | 8 +-
packages/core/core/src/dumpGraphToGraphViz.js | 16 +-
.../core/src/public/MutableBundleGraph.js | 14 +-
.../core/src/requests/BundleGraphRequest.js | 34 ++-
.../core/src/requests/ParcelBuildRequest.js | 3 +-
packages/core/core/test/AssetGraph.test.js | 12 +-
packages/core/graph/src/ContentGraph.js | 8 +-
packages/core/graph/src/Graph.js | 41 ++--
packages/core/graph/src/types.js | 2 +-
packages/core/graph/test/Graph.test.js | 34 ++-
13 files changed, 414 insertions(+), 161 deletions(-)
diff --git a/packages/core/core/src/BundleGraph.js b/packages/core/core/src/BundleGraph.js
index ca6aebbad01..6436d994b51 100644
--- a/packages/core/core/src/BundleGraph.js
+++ b/packages/core/core/src/BundleGraph.js
@@ -35,16 +35,16 @@ import {getBundleGroupId, getPublicId} from './utils';
import {ISOLATED_ENVS} from './public/Environment';
import {fromProjectPath} from './projectPath';
-type BundleGraphEdgeTypes =
+export const bundleGraphEdgeTypes = {
// A lack of an edge type indicates to follow the edge while traversing
// the bundle's contents, e.g. `bundle.traverse()` during packaging.
- | null
+ null: 1,
// Used for constant-time checks of presence of a dependency or asset in a bundle,
// avoiding bundle traversal in cases like `isAssetInAncestors`
- | 'contains'
+ contains: 2,
// Connections between bundles and bundle groups, for quick traversal of the
// bundle hierarchy.
- | 'bundle'
+ bundle: 3,
// When dependency -> asset: Indicates that the asset a dependency references
// is contained in another bundle.
// When dependency -> bundle: Indicates the bundle is necessary for any bundles
@@ -54,10 +54,13 @@ type BundleGraphEdgeTypes =
// This type prevents referenced assets from being traversed from dependencies
// along the untyped edge, and enables traversal to referenced bundles that are
// not directly connected to bundle group nodes.
- | 'references'
+ references: 4,
// Signals that the dependency is internally resolvable via the bundle's ancestry,
// and that the bundle connected to the dependency is not necessary for the source bundle.
- | 'internal_async';
+ internal_async: 5,
+};
+
+export type BundleGraphEdgeType = $Values;
type InternalSymbolResolution = {|
asset: Asset,
@@ -73,7 +76,7 @@ type InternalExportSymbolResolution = {|
type SerializedBundleGraph = {|
$$raw: true,
- graph: SerializedContentGraph,
+ graph: SerializedContentGraph,
bundleContentHashes: Map,
assetPublicIds: Set,
publicIdByAssetId: Map,
@@ -102,7 +105,7 @@ export default class BundleGraph {
// BundlerRunner takes care of invalidating hashes when runtimes are applied, but this is not ideal.
_bundleContentHashes: Map;
_targetEntryRoots: Map = new Map();
- _graph: ContentGraph;
+ _graph: ContentGraph;
constructor({
graph,
@@ -110,7 +113,7 @@ export default class BundleGraph {
assetPublicIds,
bundleContentHashes,
}: {|
- graph: ContentGraph,
+ graph: ContentGraph,
publicIdByAssetId: Map,
assetPublicIds: Set,
bundleContentHashes: Map,
@@ -126,7 +129,7 @@ export default class BundleGraph {
publicIdByAssetId: Map = new Map(),
assetPublicIds: Set = new Set(),
): BundleGraph {
- let graph = new ContentGraph();
+ let graph = new ContentGraph();
let assetGroupIds = new Set();
let assetGraphNodeIdToBundleGraphNodeId = new Map();
@@ -166,14 +169,22 @@ export default class BundleGraph {
for (let edge of assetGraph.getAllEdges()) {
let fromIds;
if (assetGroupIds.has(edge.from)) {
- fromIds = [...assetGraph.inboundEdges.getEdges(edge.from, null)];
+ fromIds = [
+ ...assetGraph.inboundEdges.getEdges(
+ edge.from,
+ bundleGraphEdgeTypes.null,
+ ),
+ ];
} else {
fromIds = [edge.from];
}
for (let from of fromIds) {
if (assetGroupIds.has(edge.to)) {
- for (let to of assetGraph.outboundEdges.getEdges(edge.to, null)) {
+ for (let to of assetGraph.outboundEdges.getEdges(
+ edge.to,
+ bundleGraphEdgeTypes.null,
+ )) {
graph.addEdge(
nullthrows(assetGraphNodeIdToBundleGraphNodeId.get(from)),
nullthrows(assetGraphNodeIdToBundleGraphNodeId.get(to)),
@@ -240,7 +251,11 @@ export default class BundleGraph {
}
if (node.type === 'asset' || node.type === 'dependency') {
- this._graph.addEdge(bundleNodeId, nodeId, 'contains');
+ this._graph.addEdge(
+ bundleNodeId,
+ nodeId,
+ bundleGraphEdgeTypes.contains,
+ );
}
if (node.type === 'dependency') {
@@ -249,18 +264,26 @@ export default class BundleGraph {
.map(id => [id, nullthrows(this._graph.getNode(id))])
.filter(([, node]) => node.type === 'bundle_group')) {
invariant(bundleGroupNode.type === 'bundle_group');
- this._graph.addEdge(bundleNodeId, bundleGroupNodeId, 'bundle');
+ this._graph.addEdge(
+ bundleNodeId,
+ bundleGroupNodeId,
+ bundleGraphEdgeTypes.bundle,
+ );
}
// If the dependency references a target bundle, add a reference edge from
// the source bundle to the dependency for easy traversal.
if (
this._graph
- .getNodeIdsConnectedFrom(nodeId, 'references')
+ .getNodeIdsConnectedFrom(nodeId, bundleGraphEdgeTypes.references)
.map(id => nullthrows(this._graph.getNode(id)))
.some(node => node.type === 'bundle')
) {
- this._graph.addEdge(bundleNodeId, nodeId, 'references');
+ this._graph.addEdge(
+ bundleNodeId,
+ nodeId,
+ bundleGraphEdgeTypes.references,
+ );
}
}
}, assetNodeId);
@@ -286,7 +309,7 @@ export default class BundleGraph {
this._graph.addEdge(
this._graph.getNodeIdByContentKey(bundle.id),
this._graph.getNodeIdByContentKey(dependency.id),
- 'internal_async',
+ bundleGraphEdgeTypes.internal_async,
);
this.removeExternalDependency(bundle, dependency);
}
@@ -301,7 +324,7 @@ export default class BundleGraph {
return this._graph
.getNodeIdsConnectedTo(
this._graph.getNodeIdByContentKey(getBundleGroupId(bundleGroup)),
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
)
.map(id => nullthrows(this._graph.getNode(id)))
.filter(node => node.type === 'bundle')
@@ -324,11 +347,15 @@ export default class BundleGraph {
if (
bundleNodeId != null &&
- this._graph.hasEdge(bundleNodeId, depNodeId, 'internal_async')
+ this._graph.hasEdge(
+ bundleNodeId,
+ depNodeId,
+ bundleGraphEdgeTypes.internal_async,
+ )
) {
let referencedAssetNodeIds = this._graph.getNodeIdsConnectedFrom(
depNodeId,
- 'references',
+ bundleGraphEdgeTypes.references,
);
let resolved;
@@ -396,7 +423,10 @@ export default class BundleGraph {
includeInline: true,
});
let referenced = this._graph
- .getNodeIdsConnectedFrom(dependencyNodeId, 'references')
+ .getNodeIdsConnectedFrom(
+ dependencyNodeId,
+ bundleGraphEdgeTypes.references,
+ )
.map(id => nullthrows(this._graph.getNode(id)))
.find(node => node.type === 'asset');
@@ -426,11 +456,13 @@ export default class BundleGraph {
return;
}
- if (this._graph.hasEdge(bundleNodeId, nodeId, 'contains')) {
+ if (
+ this._graph.hasEdge(bundleNodeId, nodeId, bundleGraphEdgeTypes.contains)
+ ) {
this._graph.removeEdge(
bundleNodeId,
nodeId,
- 'contains',
+ bundleGraphEdgeTypes.contains,
// Removing this contains edge should not orphan the connected node. This
// is disabled for performance reasons as these edges are removed as part
// of a traversal, and checking for orphans becomes quite expensive in
@@ -455,11 +487,31 @@ export default class BundleGraph {
if (node.type === 'dependency') {
this.removeExternalDependency(bundle, node.value);
- if (this._graph.hasEdge(bundleNodeId, nodeId, 'references')) {
- this._graph.addEdge(bundleNodeId, nodeId, 'references');
+ if (
+ this._graph.hasEdge(
+ bundleNodeId,
+ nodeId,
+ bundleGraphEdgeTypes.references,
+ )
+ ) {
+ this._graph.addEdge(
+ bundleNodeId,
+ nodeId,
+ bundleGraphEdgeTypes.references,
+ );
}
- if (this._graph.hasEdge(bundleNodeId, nodeId, 'internal_async')) {
- this._graph.removeEdge(bundleNodeId, nodeId, 'internal_async');
+ if (
+ this._graph.hasEdge(
+ bundleNodeId,
+ nodeId,
+ bundleGraphEdgeTypes.internal_async,
+ )
+ ) {
+ this._graph.removeEdge(
+ bundleNodeId,
+ nodeId,
+ bundleGraphEdgeTypes.internal_async,
+ );
}
}
}, assetNodeId);
@@ -478,7 +530,7 @@ export default class BundleGraph {
let bundleGroupNodeIds = this._graph.getNodeIdsConnectedTo(
bundleNodeId,
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
);
this._graph.removeNode(bundleNodeId);
@@ -551,7 +603,13 @@ export default class BundleGraph {
bundleGroupNode.id,
);
- if (!this._graph.hasEdge(bundleNodeId, bundleGroupNodeId, 'bundle')) {
+ if (
+ !this._graph.hasEdge(
+ bundleNodeId,
+ bundleGroupNodeId,
+ bundleGraphEdgeTypes.bundle,
+ )
+ ) {
continue;
}
@@ -574,11 +632,15 @@ export default class BundleGraph {
this._graph.hasEdge(
bundleNodeId,
this._graph.getNodeIdByContentKey(dependency.id),
- 'internal_async',
+ bundleGraphEdgeTypes.internal_async,
),
)
) {
- this._graph.removeEdge(bundleNodeId, bundleGroupNodeId, 'bundle');
+ this._graph.removeEdge(
+ bundleNodeId,
+ bundleGroupNodeId,
+ bundleGraphEdgeTypes.bundle,
+ );
}
}
}
@@ -591,9 +653,13 @@ export default class BundleGraph {
let dependencyId = this._graph.getNodeIdByContentKey(dependency.id);
let assetId = this._graph.getNodeIdByContentKey(asset.id);
let bundleId = this._graph.getNodeIdByContentKey(bundle.id);
- this._graph.addEdge(dependencyId, assetId, 'references');
+ this._graph.addEdge(dependencyId, assetId, bundleGraphEdgeTypes.references);
- this._graph.addEdge(dependencyId, bundleId, 'references');
+ this._graph.addEdge(
+ dependencyId,
+ bundleId,
+ bundleGraphEdgeTypes.references,
+ );
if (this._graph.hasEdge(dependencyId, assetId)) {
this._graph.removeEdge(dependencyId, assetId);
}
@@ -603,7 +669,7 @@ export default class BundleGraph {
this._graph.addEdge(
this._graph.getNodeIdByContentKey(from.id),
this._graph.getNodeIdByContentKey(to.id),
- 'references',
+ bundleGraphEdgeTypes.references,
);
}
@@ -611,7 +677,7 @@ export default class BundleGraph {
return this._graph
.getNodeIdsConnectedTo(
this._graph.getNodeIdByContentKey(asset.id),
- 'contains',
+ bundleGraphEdgeTypes.contains,
)
.map(id => nullthrows(this._graph.getNode(id)))
.filter(node => node.type === 'bundle')
@@ -625,7 +691,7 @@ export default class BundleGraph {
return this._graph
.getNodeIdsConnectedTo(
nullthrows(this._graph.getNodeIdByContentKey(dependency.id)),
- 'contains',
+ bundleGraphEdgeTypes.contains,
)
.map(id => nullthrows(this._graph.getNode(id)))
.filter(node => node.type === 'bundle')
@@ -670,7 +736,7 @@ export default class BundleGraph {
}
},
this._graph.getNodeIdByContentKey(dep.id),
- 'references',
+ bundleGraphEdgeTypes.references,
);
}
@@ -701,7 +767,7 @@ export default class BundleGraph {
if (
this._graph
- .getNodeIdsConnectedTo(assetNodeId, 'references')
+ .getNodeIdsConnectedTo(assetNodeId, bundleGraphEdgeTypes.references)
.map(id => this._graph.getNode(id))
.some(
node =>
@@ -827,7 +893,7 @@ export default class BundleGraph {
// Get a list of parent bundle nodes pointing to the bundle group
let parentBundleNodes = this._graph.getNodeIdsConnectedTo(
this._graph.getNodeIdByContentKey(getBundleGroupId(bundleGroup)),
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
);
// Check that every parent bundle has a bundle group in its ancestry that contains the asset.
@@ -875,7 +941,7 @@ export default class BundleGraph {
}
}
},
- ['references', 'bundle'],
+ [bundleGraphEdgeTypes.references, bundleGraphEdgeTypes.bundle],
);
return isReachable;
@@ -901,7 +967,13 @@ export default class BundleGraph {
}
if (node.type === 'dependency' || node.type === 'asset') {
- if (this._graph.hasEdge(bundleNodeId, nodeId, 'contains')) {
+ if (
+ this._graph.hasEdge(
+ bundleNodeId,
+ nodeId,
+ bundleGraphEdgeTypes.contains,
+ )
+ ) {
return node;
}
}
@@ -985,7 +1057,7 @@ export default class BundleGraph {
},
visit,
startBundle ? this._graph.getNodeIdByContentKey(startBundle.id) : null,
- ['bundle', 'references'],
+ [bundleGraphEdgeTypes.bundle, bundleGraphEdgeTypes.references],
);
}
@@ -1030,7 +1102,7 @@ export default class BundleGraph {
referencingBundles.add(node.value);
}
},
- 'references',
+ bundleGraphEdgeTypes.references,
);
return [...referencingBundles];
@@ -1052,7 +1124,7 @@ export default class BundleGraph {
return this._graph
.getNodeIdsConnectedTo(
nullthrows(this._graph.getNodeIdByContentKey(bundle.id)),
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
)
.map(id => nullthrows(this._graph.getNode(id)))
.filter(node => node.type === 'bundle_group')
@@ -1069,7 +1141,7 @@ export default class BundleGraph {
let bundles: Set = new Set();
for (let bundleNodeId of this._graph.getNodeIdsConnectedFrom(
this._graph.getNodeIdByContentKey(getBundleGroupId(bundleGroup)),
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
)) {
let bundleNode = nullthrows(this._graph.getNode(bundleNodeId));
invariant(bundleNode.type === 'bundle');
@@ -1125,7 +1197,9 @@ export default class BundleGraph {
// Shared bundles seem to depend on being used in the opposite order
// they were added.
// TODO: Should this be the case?
- this._graph.getNodeIdsConnectedFrom(nodeId, 'references').reverse(),
+ this._graph
+ .getNodeIdsConnectedFrom(nodeId, bundleGraphEdgeTypes.references)
+ .reverse(),
});
return [...referencedBundles];
@@ -1172,13 +1246,21 @@ export default class BundleGraph {
bundleHasAsset(bundle: Bundle, asset: Asset): boolean {
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
let assetNodeId = this._graph.getNodeIdByContentKey(asset.id);
- return this._graph.hasEdge(bundleNodeId, assetNodeId, 'contains');
+ return this._graph.hasEdge(
+ bundleNodeId,
+ assetNodeId,
+ bundleGraphEdgeTypes.contains,
+ );
}
bundleHasDependency(bundle: Bundle, dependency: Dependency): boolean {
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
let dependencyNodeId = this._graph.getNodeIdByContentKey(dependency.id);
- return this._graph.hasEdge(bundleNodeId, dependencyNodeId, 'contains');
+ return this._graph.hasEdge(
+ bundleNodeId,
+ dependencyNodeId,
+ bundleGraphEdgeTypes.contains,
+ );
}
filteredTraverse(
@@ -1493,13 +1575,23 @@ export default class BundleGraph {
getBundleGroupId(bundleGroup),
);
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
- if (this._graph.hasEdge(bundleGroupNodeId, bundleNodeId, 'bundle')) {
+ if (
+ this._graph.hasEdge(
+ bundleGroupNodeId,
+ bundleNodeId,
+ bundleGraphEdgeTypes.bundle,
+ )
+ ) {
// Bundle group already has bundle
return;
}
this._graph.addEdge(bundleGroupNodeId, bundleNodeId);
- this._graph.addEdge(bundleGroupNodeId, bundleNodeId, 'bundle');
+ this._graph.addEdge(
+ bundleGroupNodeId,
+ bundleNodeId,
+ bundleGraphEdgeTypes.bundle,
+ );
for (let entryAssetId of bundle.entryAssetIds) {
let entryAssetNodeId = this._graph.getNodeIdByContentKey(entryAssetId);
@@ -1575,7 +1667,7 @@ export default class BundleGraph {
nullthrows(
this._graph.getNodeIdByContentKey(getBundleGroupId(bundleGroup)),
),
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
)
.map(id => nullthrows(this._graph.getNode(id)))
.some(n => n.type === 'root');
@@ -1589,7 +1681,7 @@ export default class BundleGraph {
let entryBundleGroupIds = this._graph.getNodeIdsConnectedFrom(
nullthrows(this._graph.rootNodeId),
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
);
let entries = [];
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 1d03e49a6cf..6fedb3cf09a 100644
--- a/packages/core/core/src/RequestTracker.js
+++ b/packages/core/core/src/RequestTracker.js
@@ -45,6 +45,16 @@ import {
ERROR,
} from './constants';
+export const requestGraphEdgeTypes = {
+ subrequest: 2,
+ invalidated_by_update: 3,
+ invalidated_by_delete: 4,
+ invalidated_by_create: 5,
+ invalidated_by_create_above: 6,
+ dirname: 7,
+};
+
+export type RequestGraphEdgeType = $Values;
type SerializedRequestGraph = {|
...SerializedContentGraph,
invalidNodeIds: Set,
@@ -103,14 +113,6 @@ type RequestGraphNode =
| EnvNode
| OptionNode;
-type RequestGraphEdgeType =
- | 'subrequest'
- | 'invalidated_by_update'
- | 'invalidated_by_delete'
- | 'invalidated_by_create'
- | 'invalidated_by_create_above'
- | 'dirname';
-
export type RunAPI = {|
invalidateOnFileCreate: InternalFileCreateInvalidation => void,
invalidateOnFileDelete: ProjectPath => void,
@@ -280,7 +282,7 @@ export class RequestGraph extends ContentGraph<
requestNodeId,
subrequestNodeIds,
null,
- 'subrequest',
+ requestGraphEdgeTypes.subrequest,
);
}
@@ -290,7 +292,10 @@ export class RequestGraph extends ContentGraph<
node.invalidateReason |= reason;
this.invalidNodeIds.add(nodeId);
- let parentNodes = this.getNodeIdsConnectedTo(nodeId, 'subrequest');
+ let parentNodes = this.getNodeIdsConnectedTo(
+ nodeId,
+ requestGraphEdgeTypes.subrequest,
+ );
for (let parentNode of parentNodes) {
this.invalidateNode(parentNode, reason);
}
@@ -311,7 +316,7 @@ export class RequestGraph extends ContentGraph<
if (env[node.value.key] !== node.value.value) {
let parentNodes = this.getNodeIdsConnectedTo(
nodeId,
- 'invalidated_by_update',
+ requestGraphEdgeTypes.invalidated_by_update,
);
for (let parentNode of parentNodes) {
this.invalidateNode(parentNode, ENV_CHANGE);
@@ -327,7 +332,7 @@ export class RequestGraph extends ContentGraph<
if (hashFromOption(options[node.value.key]) !== node.value.hash) {
let parentNodes = this.getNodeIdsConnectedTo(
nodeId,
- 'invalidated_by_update',
+ requestGraphEdgeTypes.invalidated_by_update,
);
for (let parentNode of parentNodes) {
this.invalidateNode(parentNode, OPTION_CHANGE);
@@ -339,16 +344,36 @@ export class RequestGraph extends ContentGraph<
invalidateOnFileUpdate(requestNodeId: NodeId, filePath: ProjectPath) {
let fileNodeId = this.addNode(nodeFromFilePath(filePath));
- if (!this.hasEdge(requestNodeId, fileNodeId, 'invalidated_by_update')) {
- this.addEdge(requestNodeId, fileNodeId, 'invalidated_by_update');
+ if (
+ !this.hasEdge(
+ requestNodeId,
+ fileNodeId,
+ requestGraphEdgeTypes.invalidated_by_update,
+ )
+ ) {
+ this.addEdge(
+ requestNodeId,
+ fileNodeId,
+ requestGraphEdgeTypes.invalidated_by_update,
+ );
}
}
invalidateOnFileDelete(requestNodeId: NodeId, filePath: ProjectPath) {
let fileNodeId = this.addNode(nodeFromFilePath(filePath));
- if (!this.hasEdge(requestNodeId, fileNodeId, 'invalidated_by_delete')) {
- this.addEdge(requestNodeId, fileNodeId, 'invalidated_by_delete');
+ if (
+ !this.hasEdge(
+ requestNodeId,
+ fileNodeId,
+ requestGraphEdgeTypes.invalidated_by_delete,
+ )
+ ) {
+ this.addEdge(
+ requestNodeId,
+ fileNodeId,
+ requestGraphEdgeTypes.invalidated_by_delete,
+ );
}
}
@@ -375,9 +400,17 @@ export class RequestGraph extends ContentGraph<
let fileNameNodeId = this.addNode(fileNameNode);
if (
lastNodeId != null &&
- !this.hasEdge(lastNodeId, fileNameNodeId, 'dirname')
+ !this.hasEdge(
+ lastNodeId,
+ fileNameNodeId,
+ requestGraphEdgeTypes.dirname,
+ )
) {
- this.addEdge(lastNodeId, fileNameNodeId, 'dirname');
+ this.addEdge(
+ lastNodeId,
+ fileNameNodeId,
+ requestGraphEdgeTypes.dirname,
+ );
}
lastNodeId = fileNameNodeId;
@@ -399,13 +432,33 @@ export class RequestGraph extends ContentGraph<
// node will be invalidated.
let firstId = 'file_name:' + parts[0];
let firstNodeId = this.getNodeIdByContentKey(firstId);
- if (!this.hasEdge(nodeId, firstNodeId, 'invalidated_by_create_above')) {
- this.addEdge(nodeId, firstNodeId, 'invalidated_by_create_above');
+ if (
+ !this.hasEdge(
+ nodeId,
+ firstNodeId,
+ requestGraphEdgeTypes.invalidated_by_create_above,
+ )
+ ) {
+ this.addEdge(
+ nodeId,
+ firstNodeId,
+ requestGraphEdgeTypes.invalidated_by_create_above,
+ );
}
invariant(lastNodeId != null);
- if (!this.hasEdge(lastNodeId, nodeId, 'invalidated_by_create_above')) {
- this.addEdge(lastNodeId, nodeId, 'invalidated_by_create_above');
+ if (
+ !this.hasEdge(
+ lastNodeId,
+ nodeId,
+ requestGraphEdgeTypes.invalidated_by_create_above,
+ )
+ ) {
+ this.addEdge(
+ lastNodeId,
+ nodeId,
+ requestGraphEdgeTypes.invalidated_by_create_above,
+ );
}
} else if (input.filePath != null) {
node = nodeFromFilePath(input.filePath);
@@ -414,8 +467,18 @@ export class RequestGraph extends ContentGraph<
}
let nodeId = this.addNode(node);
- if (!this.hasEdge(requestNodeId, nodeId, 'invalidated_by_create')) {
- this.addEdge(requestNodeId, nodeId, 'invalidated_by_create');
+ if (
+ !this.hasEdge(
+ requestNodeId,
+ nodeId,
+ requestGraphEdgeTypes.invalidated_by_create,
+ )
+ ) {
+ this.addEdge(
+ requestNodeId,
+ nodeId,
+ requestGraphEdgeTypes.invalidated_by_create,
+ );
}
}
@@ -432,8 +495,18 @@ export class RequestGraph extends ContentGraph<
let envNode = nodeFromEnv(env, value);
let envNodeId = this.addNode(envNode);
- if (!this.hasEdge(requestNodeId, envNodeId, 'invalidated_by_update')) {
- this.addEdge(requestNodeId, envNodeId, 'invalidated_by_update');
+ if (
+ !this.hasEdge(
+ requestNodeId,
+ envNodeId,
+ requestGraphEdgeTypes.invalidated_by_update,
+ )
+ ) {
+ this.addEdge(
+ requestNodeId,
+ envNodeId,
+ requestGraphEdgeTypes.invalidated_by_update,
+ );
}
}
@@ -445,16 +518,41 @@ export class RequestGraph extends ContentGraph<
let optionNode = nodeFromOption(option, value);
let optionNodeId = this.addNode(optionNode);
- if (!this.hasEdge(requestNodeId, optionNodeId, 'invalidated_by_update')) {
- this.addEdge(requestNodeId, optionNodeId, 'invalidated_by_update');
+ if (
+ !this.hasEdge(
+ requestNodeId,
+ optionNodeId,
+ requestGraphEdgeTypes.invalidated_by_update,
+ )
+ ) {
+ this.addEdge(
+ requestNodeId,
+ optionNodeId,
+ requestGraphEdgeTypes.invalidated_by_update,
+ );
}
}
clearInvalidations(nodeId: NodeId) {
this.unpredicatableNodeIds.delete(nodeId);
- this.replaceNodeIdsConnectedTo(nodeId, [], null, 'invalidated_by_update');
- this.replaceNodeIdsConnectedTo(nodeId, [], null, 'invalidated_by_delete');
- this.replaceNodeIdsConnectedTo(nodeId, [], null, 'invalidated_by_create');
+ this.replaceNodeIdsConnectedTo(
+ nodeId,
+ [],
+ null,
+ requestGraphEdgeTypes.invalidated_by_update,
+ );
+ this.replaceNodeIdsConnectedTo(
+ nodeId,
+ [],
+ null,
+ requestGraphEdgeTypes.invalidated_by_delete,
+ );
+ this.replaceNodeIdsConnectedTo(
+ nodeId,
+ [],
+ null,
+ requestGraphEdgeTypes.invalidated_by_create,
+ );
}
getInvalidations(requestNodeId: NodeId): Array {
@@ -465,7 +563,7 @@ export class RequestGraph extends ContentGraph<
// For now just handling updates. Could add creates/deletes later if needed.
let invalidations = this.getNodeIdsConnectedFrom(
requestNodeId,
- 'invalidated_by_update',
+ requestGraphEdgeTypes.invalidated_by_update,
);
return invalidations
.map(nodeId => {
@@ -487,7 +585,10 @@ export class RequestGraph extends ContentGraph<
return [];
}
- let subRequests = this.getNodeIdsConnectedFrom(requestNodeId, 'subrequest');
+ let subRequests = this.getNodeIdsConnectedFrom(
+ requestNodeId,
+ requestGraphEdgeTypes.subrequest,
+ );
return subRequests.map(nodeId => {
let node = nullthrows(this.getNode(nodeId));
@@ -510,7 +611,11 @@ export class RequestGraph extends ContentGraph<
for (let matchNode of matchNodes) {
let matchNodeId = this.getNodeIdByContentKey(matchNode.id);
if (
- this.hasEdge(nodeId, matchNodeId, 'invalidated_by_create_above') &&
+ this.hasEdge(
+ nodeId,
+ matchNodeId,
+ requestGraphEdgeTypes.invalidated_by_create_above,
+ ) &&
isDirectoryInside(
path.dirname(fromProjectPathRelative(matchNode.value.filePath)),
dirname,
@@ -518,7 +623,7 @@ export class RequestGraph extends ContentGraph<
) {
let connectedNodes = this.getNodeIdsConnectedTo(
matchNodeId,
- 'invalidated_by_create',
+ requestGraphEdgeTypes.invalidated_by_create,
);
for (let connectedNode of connectedNodes) {
this.invalidateNode(connectedNode, FILE_CREATE);
@@ -532,7 +637,11 @@ export class RequestGraph extends ContentGraph<
let contentKey = 'file_name:' + basename;
if (this.hasContentKey(contentKey)) {
if (
- this.hasEdge(nodeId, this.getNodeIdByContentKey(contentKey), 'dirname')
+ this.hasEdge(
+ nodeId,
+ this.getNodeIdByContentKey(contentKey),
+ requestGraphEdgeTypes.dirname,
+ )
) {
let parent = nullthrows(this.getNodeByContentKey(contentKey));
invariant(parent.type === 'file_name');
@@ -570,7 +679,10 @@ export class RequestGraph extends ContentGraph<
// then also invalidate nodes connected by invalidated_by_update edges.
if (hasFileRequest && (type === 'create' || type === 'update')) {
let nodeId = this.getNodeIdByContentKey(filePath);
- let nodes = this.getNodeIdsConnectedTo(nodeId, 'invalidated_by_update');
+ let nodes = this.getNodeIdsConnectedTo(
+ nodeId,
+ requestGraphEdgeTypes.invalidated_by_update,
+ );
for (let connectedNode of nodes) {
didInvalidate = true;
@@ -580,7 +692,7 @@ export class RequestGraph extends ContentGraph<
if (type === 'create') {
let nodes = this.getNodeIdsConnectedTo(
nodeId,
- 'invalidated_by_create',
+ requestGraphEdgeTypes.invalidated_by_create,
);
for (let connectedNode of nodes) {
didInvalidate = true;
@@ -597,7 +709,7 @@ export class RequestGraph extends ContentGraph<
// Find potential file nodes to be invalidated if this file name pattern matches
let above = this.getNodeIdsConnectedTo(
fileNameNodeId,
- 'invalidated_by_create_above',
+ requestGraphEdgeTypes.invalidated_by_create_above,
).map(nodeId => {
let node = nullthrows(this.getNode(nodeId));
invariant(node.type === 'file');
@@ -617,7 +729,7 @@ export class RequestGraph extends ContentGraph<
if (isGlobMatch(filePath, fromProjectPathRelative(globNode.value))) {
let connectedNodes = this.getNodeIdsConnectedTo(
globeNodeId,
- 'invalidated_by_create',
+ requestGraphEdgeTypes.invalidated_by_create,
);
for (let connectedNode of connectedNodes) {
didInvalidate = true;
@@ -629,7 +741,7 @@ export class RequestGraph extends ContentGraph<
let nodeId = this.getNodeIdByContentKey(filePath);
for (let connectedNode of this.getNodeIdsConnectedTo(
nodeId,
- 'invalidated_by_delete',
+ requestGraphEdgeTypes.invalidated_by_delete,
)) {
didInvalidate = true;
this.invalidateNode(connectedNode, FILE_DELETE);
diff --git a/packages/core/core/src/applyRuntimes.js b/packages/core/core/src/applyRuntimes.js
index 1bab6a64551..fcd2a9a6707 100644
--- a/packages/core/core/src/applyRuntimes.js
+++ b/packages/core/core/src/applyRuntimes.js
@@ -20,7 +20,7 @@ import invariant from 'assert';
import nullthrows from 'nullthrows';
import AssetGraph, {nodeFromAssetGroup} from './AssetGraph';
import BundleGraph from './public/BundleGraph';
-import InternalBundleGraph from './BundleGraph';
+import InternalBundleGraph, {bundleGraphEdgeTypes} from './BundleGraph';
import {NamedBundle} from './public/Bundle';
import {PluginLogger} from '@parcel/logger';
import {hashString} from '@parcel/hash';
@@ -218,7 +218,11 @@ export default async function applyRuntimes({
const bundleGraphNodeId = bundleGraph._graph.getNodeIdByContentKey(
node.id,
); // the node id is not constant between graphs
- bundleGraph._graph.addEdge(bundleNodeId, bundleGraphNodeId, 'contains');
+ bundleGraph._graph.addEdge(
+ bundleNodeId,
+ bundleGraphNodeId,
+ bundleGraphEdgeTypes.contains,
+ );
}
}, runtimesGraphRuntimeNodeId);
diff --git a/packages/core/core/src/dumpGraphToGraphViz.js b/packages/core/core/src/dumpGraphToGraphViz.js
index 05aaaaabb0a..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,6 +34,7 @@ export default async function dumpGraphToGraphViz(
// $FlowFixMe
graph: Graph | Graph,
name: string,
+ edgeTypes?: typeof bundleGraphEdgeTypes | typeof requestGraphEdgeTypes,
): Promise {
if (
process.env.PARCEL_BUILD_ENV === 'production' ||
@@ -129,9 +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/public/MutableBundleGraph.js b/packages/core/core/src/public/MutableBundleGraph.js
index e90949ae3ae..e59a2d8ac9c 100644
--- a/packages/core/core/src/public/MutableBundleGraph.js
+++ b/packages/core/core/src/public/MutableBundleGraph.js
@@ -15,7 +15,7 @@ import invariant from 'assert';
import nullthrows from 'nullthrows';
import {hashString} from '@parcel/hash';
import BundleGraph from './BundleGraph';
-import InternalBundleGraph from '../BundleGraph';
+import InternalBundleGraph, {bundleGraphEdgeTypes} from '../BundleGraph';
import {Bundle, bundleToInternalBundle} from './Bundle';
import {assetFromValue, assetToAssetValue} from './Asset';
import {getBundleGroupId, getPublicId} from '../utils';
@@ -107,19 +107,23 @@ export default class MutableBundleGraph extends BundleGraph
);
this.#graph._graph.addEdge(dependencyNodeId, bundleGroupNodeId);
this.#graph._graph.replaceNodeIdsConnectedTo(bundleGroupNodeId, assetNodes);
- this.#graph._graph.addEdge(dependencyNodeId, resolvedNodeId, 'references');
+ this.#graph._graph.addEdge(
+ dependencyNodeId,
+ resolvedNodeId,
+ bundleGraphEdgeTypes.references,
+ );
this.#graph._graph.removeEdge(dependencyNodeId, resolvedNodeId);
if (dependency.isEntry) {
this.#graph._graph.addEdge(
nullthrows(this.#graph._graph.rootNodeId),
bundleGroupNodeId,
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
);
} else {
let inboundBundleNodeIds = this.#graph._graph.getNodeIdsConnectedTo(
dependencyNodeId,
- 'contains',
+ bundleGraphEdgeTypes.contains,
);
for (let inboundBundleNodeId of inboundBundleNodeIds) {
invariant(
@@ -128,7 +132,7 @@ export default class MutableBundleGraph extends BundleGraph
this.#graph._graph.addEdge(
inboundBundleNodeId,
bundleGroupNodeId,
- 'bundle',
+ bundleGraphEdgeTypes.bundle,
);
}
}
diff --git a/packages/core/core/src/requests/BundleGraphRequest.js b/packages/core/core/src/requests/BundleGraphRequest.js
index dcca6df7a53..13da2f1dbac 100644
--- a/packages/core/core/src/requests/BundleGraphRequest.js
+++ b/packages/core/core/src/requests/BundleGraphRequest.js
@@ -18,7 +18,7 @@ import {PluginLogger} from '@parcel/logger';
import ThrowableDiagnostic, {errorToDiagnostic} from '@parcel/diagnostic';
import AssetGraph from '../AssetGraph';
import BundleGraph from '../public/BundleGraph';
-import InternalBundleGraph from '../BundleGraph';
+import InternalBundleGraph, {bundleGraphEdgeTypes} from '../BundleGraph';
import MutableBundleGraph from '../public/MutableBundleGraph';
import {Bundle, NamedBundle} from '../public/Bundle';
import {report} from '../ReporterRunner';
@@ -200,8 +200,12 @@ class BundlerRunner {
}
let internalBundleGraph = InternalBundleGraph.fromAssetGraph(graph);
- // $FlowFixMe
- await dumpGraphToGraphViz(internalBundleGraph._graph, 'before_bundle');
+ await dumpGraphToGraphViz(
+ // $FlowFixMe
+ internalBundleGraph._graph,
+ 'before_bundle',
+ bundleGraphEdgeTypes,
+ );
let mutableBundleGraph = new MutableBundleGraph(
internalBundleGraph,
this.options,
@@ -223,8 +227,12 @@ class BundlerRunner {
}),
});
} finally {
- // $FlowFixMe[incompatible-call]
- await dumpGraphToGraphViz(internalBundleGraph._graph, 'after_bundle');
+ await dumpGraphToGraphViz(
+ // $FlowFixMe[incompatible-call]
+ internalBundleGraph._graph,
+ 'after_bundle',
+ bundleGraphEdgeTypes,
+ );
}
if (this.pluginOptions.mode === 'production') {
@@ -242,8 +250,12 @@ class BundlerRunner {
}),
});
} finally {
- // $FlowFixMe[incompatible-call]
- await dumpGraphToGraphViz(internalBundleGraph._graph, 'after_optimize');
+ await dumpGraphToGraphViz(
+ // $FlowFixMe[incompatible-call]
+ internalBundleGraph._graph,
+ 'after_optimize',
+ bundleGraphEdgeTypes,
+ );
}
}
@@ -273,8 +285,12 @@ class BundlerRunner {
configs: this.configs,
});
- // $FlowFixMe
- await dumpGraphToGraphViz(internalBundleGraph._graph, 'after_runtimes');
+ await dumpGraphToGraphViz(
+ // $FlowFixMe
+ internalBundleGraph._graph,
+ 'after_runtimes',
+ bundleGraphEdgeTypes,
+ );
// Store the serialized bundle graph in an in memory cache so that we avoid serializing it
// many times to send to each worker, and in build mode, when writing to cache on shutdown.
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/test/AssetGraph.test.js b/packages/core/core/test/AssetGraph.test.js
index 36d27794b36..ce1ed9e500d 100644
--- a/packages/core/core/test/AssetGraph.test.js
+++ b/packages/core/core/test/AssetGraph.test.js
@@ -154,12 +154,12 @@ describe('AssetGraph', () => {
{
from: graph.rootNodeId,
to: graph.getNodeIdByContentKey('entry_specifier:path/to/index1'),
- type: null,
+ type: 1,
},
{
from: graph.rootNodeId,
to: graph.getNodeIdByContentKey('entry_specifier:path/to/index2'),
- type: null,
+ type: 1,
},
{
from: graph.getNodeIdByContentKey('entry_specifier:path/to/index1'),
@@ -169,7 +169,7 @@ describe('AssetGraph', () => {
packagePath: toProjectPath('/path/to/index1'),
}).id,
),
- type: null,
+ type: 1,
},
{
from: graph.getNodeIdByContentKey('entry_specifier:path/to/index2'),
@@ -179,7 +179,7 @@ describe('AssetGraph', () => {
packagePath: toProjectPath('/path/to/index2'),
}).id,
),
- type: null,
+ type: 1,
},
{
from: graph.getNodeIdByContentKey(
@@ -196,7 +196,7 @@ describe('AssetGraph', () => {
env: DEFAULT_ENV,
}).id,
),
- type: null,
+ type: 1,
},
{
from: graph.getNodeIdByContentKey(
@@ -213,7 +213,7 @@ describe('AssetGraph', () => {
env: DEFAULT_ENV,
}).id,
),
- type: null,
+ type: 1,
},
]);
});
diff --git a/packages/core/graph/src/ContentGraph.js b/packages/core/graph/src/ContentGraph.js
index 9cfdad0e651..e43da92cddc 100644
--- a/packages/core/graph/src/ContentGraph.js
+++ b/packages/core/graph/src/ContentGraph.js
@@ -4,16 +4,16 @@ import type {ContentKey, NodeId} from './types';
import Graph, {type GraphOpts} from './Graph';
import nullthrows from 'nullthrows';
-export type SerializedContentGraph = {|
+export type SerializedContentGraph = {|
...GraphOpts,
_contentKeyToNodeId: Map,
_nodeIdToContentKey: Map,
|};
-export default class ContentGraph<
+export default class ContentGraph extends Graph<
TNode,
- TEdgeType: string | null = null,
-> extends Graph {
+ TEdgeType,
+> {
_contentKeyToNodeId: Map;
_nodeIdToContentKey: Map;
diff --git a/packages/core/graph/src/Graph.js b/packages/core/graph/src/Graph.js
index fe37bfa5023..d68ced59065 100644
--- a/packages/core/graph/src/Graph.js
+++ b/packages/core/graph/src/Graph.js
@@ -7,21 +7,22 @@ import type {TraversalActions, GraphVisitor} from '@parcel/types';
import assert from 'assert';
import nullthrows from 'nullthrows';
-export type GraphOpts = {|
+type NullEdgeType = 1;
+export type GraphOpts = {|
nodes?: Map,
- edges?: AdjacencyListMap,
+ edges?: AdjacencyListMap,
rootNodeId?: ?NodeId,
nextNodeId?: ?number,
|};
export const ALL_EDGE_TYPES = '@@all_edge_types';
-export default class Graph {
+export default class Graph {
nodes: Map;
- inboundEdges: AdjacencyList;
- outboundEdges: AdjacencyList;
+ inboundEdges: AdjacencyList;
+ outboundEdges: AdjacencyList;
rootNodeId: ?NodeId;
- nextNodeId: number = 0;
+ nextNodeId: number = 1;
constructor(opts: ?GraphOpts) {
this.nodes = opts?.nodes || new Map();
@@ -71,7 +72,7 @@ export default class Graph {
// Returns a list of all edges in the graph. This can be large, so iterating
// the complete list can be costly in large graphs. Used when merging graphs.
- getAllEdges(): Array> {
+ getAllEdges(): Array> {
let edges = [];
for (let [from, edgeList] of this.outboundEdges.getListMap()) {
for (let [type, toNodes] of edgeList) {
@@ -97,7 +98,7 @@ export default class Graph {
return this.nodes.get(id);
}
- addEdge(from: NodeId, to: NodeId, type: TEdgeType | null = null): void {
+ addEdge(from: NodeId, to: NodeId, type: TEdgeType | NullEdgeType = 1): void {
if (!this.getNode(from)) {
throw new Error(`"from" node '${fromNodeId(from)}' not found`);
}
@@ -110,13 +111,17 @@ export default class Graph {
this.inboundEdges.addEdge(to, from, type);
}
- hasEdge(from: NodeId, to: NodeId, type?: TEdgeType | null = null): boolean {
+ hasEdge(
+ from: NodeId,
+ to: NodeId,
+ type?: TEdgeType | NullEdgeType = 1,
+ ): boolean {
return this.outboundEdges.hasEdge(from, to, type);
}
getNodeIdsConnectedTo(
nodeId: NodeId,
- type: TEdgeType | null | Array = null,
+ type: TEdgeType | NullEdgeType | Array = 1,
): Array {
this._assertHasNodeId(nodeId);
@@ -149,7 +154,7 @@ export default class Graph {
getNodeIdsConnectedFrom(
nodeId: NodeId,
- type: TEdgeType | null | Array = null,
+ type: TEdgeType | NullEdgeType | Array = 1,
): Array {
this._assertHasNodeId(nodeId);
let outboundByType = this.outboundEdges.getEdgesByType(nodeId);
@@ -206,7 +211,7 @@ export default class Graph {
assert(wasRemoved);
}
- removeEdges(nodeId: NodeId, type: TEdgeType | null = null) {
+ removeEdges(nodeId: NodeId, type: TEdgeType | NullEdgeType = 1) {
this._assertHasNodeId(nodeId);
for (let to of this.outboundEdges.getEdges(nodeId, type)) {
@@ -218,7 +223,7 @@ export default class Graph {
removeEdge(
from: NodeId,
to: NodeId,
- type: TEdgeType | null = null,
+ type: TEdgeType | NullEdgeType = 1,
removeOrphans: boolean = true,
) {
if (!this.outboundEdges.hasEdge(from, to, type)) {
@@ -290,7 +295,7 @@ export default class Graph {
replaceNode(
fromNodeId: NodeId,
toNodeId: NodeId,
- type: TEdgeType | null = null,
+ type: TEdgeType | NullEdgeType = 1,
): void {
this._assertHasNodeId(fromNodeId);
for (let parent of this.inboundEdges.getEdges(fromNodeId, type)) {
@@ -305,7 +310,7 @@ export default class Graph {
fromNodeId: NodeId,
toNodeIds: $ReadOnlyArray,
replaceFilter?: null | (NodeId => boolean),
- type?: TEdgeType | null = null,
+ type?: TEdgeType | NullEdgeType = 1,
): void {
this._assertHasNodeId(fromNodeId);
@@ -331,7 +336,7 @@ export default class Graph {
traverse(
visit: GraphVisitor,
startNodeId: ?NodeId,
- type: TEdgeType | null | Array = null,
+ type: TEdgeType | NullEdgeType | Array = 1,
): ?TContext {
return this.dfs({
visit,
@@ -344,7 +349,7 @@ export default class Graph {
filter: (NodeId, TraversalActions) => ?TValue,
visit: GraphVisitor,
startNodeId: ?NodeId,
- type?: TEdgeType | null | Array,
+ type?: TEdgeType | Array,
): ?TContext {
return this.traverse(mapVisitor(filter, visit), startNodeId, type);
}
@@ -352,7 +357,7 @@ export default class Graph {
traverseAncestors(
startNodeId: ?NodeId,
visit: GraphVisitor,
- type: TEdgeType | null | Array = null,
+ type: TEdgeType | NullEdgeType | Array = 1,
): ?TContext {
return this.dfs({
visit,
diff --git a/packages/core/graph/src/types.js b/packages/core/graph/src/types.js
index 2e8e4d501e9..355f02d08a8 100644
--- a/packages/core/graph/src/types.js
+++ b/packages/core/graph/src/types.js
@@ -11,7 +11,7 @@ export function fromNodeId(x: NodeId): number {
export type ContentKey = string;
-export type Edge = {|
+export type Edge = {|
from: NodeId,
to: NodeId,
type: TEdgeType,
diff --git a/packages/core/graph/test/Graph.test.js b/packages/core/graph/test/Graph.test.js
index f311d01996b..bbecc3a28ec 100644
--- a/packages/core/graph/test/Graph.test.js
+++ b/packages/core/graph/test/Graph.test.js
@@ -87,7 +87,7 @@ describe('Graph', () => {
let nodeB = graph.addNode('b');
let nodeC = graph.addNode('c');
graph.addEdge(nodeA, nodeB);
- graph.addEdge(nodeA, nodeC, 'edgetype');
+ graph.addEdge(nodeA, nodeC, 1);
assert(graph.isOrphanedNode(nodeA));
assert(!graph.isOrphanedNode(nodeB));
assert(!graph.isOrphanedNode(nodeC));
@@ -114,9 +114,7 @@ describe('Graph', () => {
assert(graph.nodes.has(nodeD));
assert(!graph.nodes.has(nodeB));
assert(!graph.nodes.has(nodeC));
- assert.deepEqual(graph.getAllEdges(), [
- {from: nodeA, to: nodeD, type: null},
- ]);
+ assert.deepEqual(graph.getAllEdges(), [{from: nodeA, to: nodeD, type: 1}]);
});
it('removing a node recursively deletes orphaned nodes', () => {
@@ -157,8 +155,8 @@ describe('Graph', () => {
assert.deepEqual([...graph.nodes.keys()], [nodeA, nodeC, nodeF]);
assert.deepEqual(graph.getAllEdges(), [
- {from: nodeA, to: nodeC, type: null},
- {from: nodeC, to: nodeF, type: null},
+ {from: nodeA, to: nodeC, type: 1},
+ {from: nodeC, to: nodeF, type: 1},
]);
});
@@ -202,8 +200,8 @@ describe('Graph', () => {
assert.deepEqual([...graph.nodes.keys()], [nodeA, nodeC, nodeF]);
assert.deepEqual(graph.getAllEdges(), [
- {from: nodeA, to: nodeC, type: null},
- {from: nodeC, to: nodeF, type: null},
+ {from: nodeA, to: nodeC, type: 1},
+ {from: nodeC, to: nodeF, type: 1},
]);
});
@@ -237,11 +235,11 @@ describe('Graph', () => {
assert.deepEqual(nodesBefore, getNodeIds());
assert.deepEqual(graph.getAllEdges(), [
- {from: nodeA, to: nodeB, type: null},
- {from: nodeB, to: nodeC, type: null},
- {from: nodeB, to: nodeD, type: null},
- {from: nodeD, to: nodeE, type: null},
- {from: nodeE, to: nodeB, type: null},
+ {from: nodeA, to: nodeB, type: 1},
+ {from: nodeB, to: nodeC, type: 1},
+ {from: nodeB, to: nodeD, type: 1},
+ {from: nodeD, to: nodeE, type: 1},
+ {from: nodeE, to: nodeB, type: 1},
]);
});
@@ -280,8 +278,8 @@ describe('Graph', () => {
assert(!graph.hasNode(nodeC));
assert(graph.hasNode(nodeD));
assert.deepEqual(graph.getAllEdges(), [
- {from: nodeA, to: nodeB, type: null},
- {from: nodeA, to: nodeD, type: null},
+ {from: nodeA, to: nodeB, type: 1},
+ {from: nodeA, to: nodeD, type: 1},
]);
});
@@ -292,10 +290,10 @@ describe('Graph', () => {
let nodeC = graph.addNode('c');
let nodeD = graph.addNode('d');
- graph.addEdge(nodeA, nodeB, 'edgetype');
+ graph.addEdge(nodeA, nodeB, 2);
graph.addEdge(nodeA, nodeD);
graph.addEdge(nodeB, nodeC);
- graph.addEdge(nodeB, nodeD, 'edgetype');
+ graph.addEdge(nodeB, nodeD, 2);
graph.setRootNodeId(nodeA);
@@ -305,7 +303,7 @@ describe('Graph', () => {
visited.push(nodeId);
},
null, // use root as startNode
- 'edgetype',
+ 2,
);
assert.deepEqual(visited, [nodeA, nodeB, nodeD]);
From 2013dfff74468ee8a3a1dbed6742db32dd24032a Mon Sep 17 00:00:00 2001
From: Toby de Havilland <59738910+toby-wollit@users.noreply.github.com>
Date: Thu, 16 Sep 2021 11:33:33 +0100
Subject: [PATCH 4/7] Reorder resolveOptions() env priority (#6904)
---
packages/core/core/src/resolveOptions.js | 4 ++--
packages/core/integration-tests/test/javascript.js | 10 ++++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
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/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), {
From b6faa0c819d562726ac8708f7f91ff0cb65b8311 Mon Sep 17 00:00:00 2001
From: Chris Wilkinson
Date: Sun, 19 Sep 2021 00:46:05 +0100
Subject: [PATCH 5/7] Don't fail when HTML tags are implied (#6752)
---
flow-libs/posthtml-parser.js.flow | 5 ++-
flow-libs/posthtml-render.js.flow | 7 ++--
packages/core/integration-tests/test/html.js | 32 +++++++++++++++++++
.../test/integration/html-invalid/index.html | 14 ++++++++
.../html-optional-closing-tags/index.html | 9 ++++++
packages/core/test-utils/package.json | 4 +--
packages/core/test-utils/src/utils.js | 2 +-
packages/optimizers/htmlnano/package.json | 2 +-
packages/packagers/html/package.json | 2 +-
packages/transformers/html/package.json | 6 ++--
.../transformers/html/src/HTMLTransformer.js | 4 +--
packages/transformers/posthtml/package.json | 6 ++--
.../posthtml/src/PostHTMLTransformer.js | 4 +--
packages/transformers/svg/package.json | 6 ++--
.../transformers/svg/src/SVGTransformer.js | 4 +--
yarn.lock | 17 +++++++---
16 files changed, 96 insertions(+), 28 deletions(-)
create mode 100644 packages/core/integration-tests/test/integration/html-invalid/index.html
create mode 100644 packages/core/integration-tests/test/integration/html-optional-closing-tags/index.html
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/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/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/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/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..a38503cc958 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"
@@ -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==
From aaec5bae96bebe3d90046a1a182303b68336dcec Mon Sep 17 00:00:00 2001
From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
Date: Mon, 20 Sep 2021 23:42:35 +0200
Subject: [PATCH 6/7] Only use error overlay if there's a document (#6960)
---
packages/runtimes/hmr/src/loaders/hmr-runtime.js | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
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) {
From 1b980caf31e324fd2285d4301067191e4ad99243 Mon Sep 17 00:00:00 2001
From: Will Binns-Smith
Date: Mon, 20 Sep 2021 17:50:56 -0700
Subject: [PATCH 7/7] Upgrade Flow to 0.160.1 (#6964)
Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com>
---
.flowconfig | 2 +-
package.json | 2 +-
yarn.lock | 8 ++++----
3 files changed, 6 insertions(+), 6 deletions(-)
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/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/yarn.lock b/yarn.lock
index a38503cc958..c4176549c41 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6090,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"