fix(bundler): Improve performance (#1599)

swc_bundler:
 - Skip sorting of statements if a module does not import anything.
This commit is contained in:
강동윤 2021-04-22 19:43:35 +09:00 committed by GitHub
parent 8222cc075d
commit 9a07869c21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 77 additions and 60 deletions

View File

@ -9,7 +9,7 @@ include = ["Cargo.toml", "build.rs", "src/**/*.rs", "src/**/*.js"]
license = "Apache-2.0/MIT" license = "Apache-2.0/MIT"
name = "swc_bundler" name = "swc_bundler"
repository = "https://github.com/swc-project/swc.git" repository = "https://github.com/swc-project/swc.git"
version = "0.32.4" version = "0.32.5"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features] [features]
@ -21,6 +21,7 @@ ahash = "0.7"
anyhow = "1" anyhow = "1"
crc = "1.8" crc = "1.8"
dashmap = {version = "3", optional = true} dashmap = {version = "3", optional = true}
fxhash = "0.2"
indexmap = "1.6" indexmap = "1.6"
is-macro = "0.1" is-macro = "0.1"
log = "0.4" log = "0.4"

View File

@ -15,10 +15,9 @@ use crate::{
util::{self, CloneMap, ExprExt, IntoParallelIterator, MapWithMut, VarDeclaratorExt}, util::{self, CloneMap, ExprExt, IntoParallelIterator, MapWithMut, VarDeclaratorExt},
Bundler, Hook, ModuleRecord, Bundler, Hook, ModuleRecord,
}; };
use ahash::AHashMap;
use ahash::AHashSet;
use ahash::RandomState;
use anyhow::{Context, Error}; use anyhow::{Context, Error};
use fxhash::FxHashMap;
use fxhash::FxHashSet;
use petgraph::graphmap::DiGraphMap; use petgraph::graphmap::DiGraphMap;
#[cfg(feature = "concurrent")] #[cfg(feature = "concurrent")]
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
@ -33,7 +32,7 @@ pub(super) struct Ctx {
pub graph: DiGraphMap<ModuleId, ()>, pub graph: DiGraphMap<ModuleId, ()>,
pub merged: CHashSet<ModuleId>, pub merged: CHashSet<ModuleId>,
pub transitive_remap: CloneMap<SyntaxContext, SyntaxContext>, pub transitive_remap: CloneMap<SyntaxContext, SyntaxContext>,
pub export_stars_in_wrapped: Lock<AHashMap<ModuleId, Vec<SyntaxContext>>>, pub export_stars_in_wrapped: Lock<FxHashMap<ModuleId, Vec<SyntaxContext>>>,
} }
impl<L, R> Bundler<'_, L, R> impl<L, R> Bundler<'_, L, R>
@ -541,7 +540,7 @@ where
fn add_var( fn add_var(
injected_ctxt: SyntaxContext, injected_ctxt: SyntaxContext,
vars: &mut Vec<(ModuleId, ModuleItem)>, vars: &mut Vec<(ModuleId, ModuleItem)>,
declared: &mut AHashSet<Id>, declared: &mut FxHashSet<Id>,
map: &CloneMap<SyntaxContext, SyntaxContext>, map: &CloneMap<SyntaxContext, SyntaxContext>,
module_id: ModuleId, module_id: ModuleId,
id: Id, id: Id,
@ -579,7 +578,7 @@ where
// If an user import and export from D, the transitive syntax context map // If an user import and export from D, the transitive syntax context map
// contains a entry from D to foo because it's reexported and // contains a entry from D to foo because it's reexported and
// the variable (reexported from D) exist because it's imported. // the variable (reexported from D) exist because it's imported.
let mut declared_ids = AHashSet::<_, RandomState>::default(); let mut declared_ids = FxHashSet::<_>::default();
for (_, stmt) in entry.iter() { for (_, stmt) in entry.iter() {
match stmt { match stmt {
@ -653,7 +652,7 @@ where
{ {
let mut map = ctx.export_stars_in_wrapped.lock(); let mut map = ctx.export_stars_in_wrapped.lock();
let mut additional_props = AHashMap::<_, Vec<_>>::new(); let mut additional_props = FxHashMap::<_, Vec<_>>::default();
// Handle `export *` for wrapped modules. // Handle `export *` for wrapped modules.
for (module_id, ctxts) in map.drain() { for (module_id, ctxts) in map.drain() {
for (_, stmt) in entry.iter() { for (_, stmt) in entry.iter() {
@ -858,6 +857,8 @@ where
return; return;
} }
let mut extra = vec![];
module.map_any_items(|_, items| { module.map_any_items(|_, items| {
let mut new = Vec::with_capacity(items.len() * 11 / 10); let mut new = Vec::with_capacity(items.len() * 11 / 10);
@ -1039,7 +1040,7 @@ where
orig: local, orig: local,
exported: Some(exported), exported: Some(exported),
}); });
new.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( extra.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport { NamedExport {
span: export.span.with_ctxt(injected_ctxt), span: export.span.with_ctxt(injected_ctxt),
specifiers: vec![specifier], specifiers: vec![specifier],
@ -1086,7 +1087,7 @@ where
exported: Some(exported), exported: Some(exported),
}); });
log::trace!("Exporting `default` with `export default expr`"); log::trace!("Exporting `default` with `export default expr`");
new.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( extra.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport { NamedExport {
span: export.span.with_ctxt(injected_ctxt), span: export.span.with_ctxt(injected_ctxt),
specifiers: vec![specifier], specifiers: vec![specifier],
@ -1158,7 +1159,7 @@ where
type_only: false, type_only: false,
asserts: None, asserts: None,
})); }));
new.push(export); extra.push(export);
continue; continue;
} }
@ -1190,7 +1191,7 @@ where
exported: Some(exported), exported: Some(exported),
}); });
new.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( extra.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
NamedExport { NamedExport {
span: export.span.with_ctxt(injected_ctxt), span: export.span.with_ctxt(injected_ctxt),
specifiers: vec![specifier], specifiers: vec![specifier],
@ -1254,6 +1255,10 @@ where
new new
}); });
for item in extra {
module.append(info.id, item);
}
// print_hygiene( // print_hygiene(
// &format!("prepared: {}", info.fm.name), // &format!("prepared: {}", info.fm.name),
// &self.cm, // &self.cm,

View File

@ -4,8 +4,8 @@ use crate::{
util::IntoParallelIterator, Bundle, util::IntoParallelIterator, Bundle,
}; };
use ahash::AHashMap; use ahash::AHashMap;
use ahash::AHashSet;
use anyhow::{Context, Error}; use anyhow::{Context, Error};
use fxhash::FxHashSet;
#[cfg(feature = "rayon")] #[cfg(feature = "rayon")]
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
@ -26,9 +26,9 @@ struct InternalEntry {
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct State { struct State {
synchronously_included: AHashSet<ModuleId>, synchronously_included: FxHashSet<ModuleId>,
dynamic_entries: AHashSet<ModuleId>, dynamic_entries: FxHashSet<ModuleId>,
common_libs: AHashSet<ModuleId>, common_libs: FxHashSet<ModuleId>,
} }
impl<L, R> Bundler<'_, L, R> impl<L, R> Bundler<'_, L, R>

View File

@ -5,8 +5,9 @@ use crate::{
BundleKind, Bundler, Load, ModuleId, Resolve, BundleKind, Bundler, Load, ModuleId, Resolve,
}; };
use ahash::AHashMap; use ahash::AHashMap;
use ahash::AHashSet;
use anyhow::{bail, Error}; use anyhow::{bail, Error};
use fxhash::FxHashMap;
use fxhash::FxHashSet;
use petgraph::{ use petgraph::{
algo::all_simple_paths, algo::all_simple_paths,
visit::Bfs, visit::Bfs,
@ -30,7 +31,7 @@ struct PlanBuilder {
/// `(a, b)`, `(a, c)`,`(b, c)` will be inserted. /// `(a, b)`, `(a, c)`,`(b, c)` will be inserted.
/// ///
/// `bool` is `true` if it's connected with exports. /// `bool` is `true` if it's connected with exports.
all_deps: AHashMap<(ModuleId, ModuleId), bool>, all_deps: FxHashMap<(ModuleId, ModuleId), bool>,
/// Graph to compute direct dependencies (direct means it will be merged /// Graph to compute direct dependencies (direct means it will be merged
/// directly) /// directly)
@ -38,14 +39,14 @@ struct PlanBuilder {
circular: Circulars, circular: Circulars,
kinds: AHashMap<ModuleId, BundleKind>, kinds: FxHashMap<ModuleId, BundleKind>,
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct Circulars(Vec<AHashSet<ModuleId>>); struct Circulars(Vec<FxHashSet<ModuleId>>);
impl Circulars { impl Circulars {
pub fn get(&self, id: ModuleId) -> Option<&AHashSet<ModuleId>> { pub fn get(&self, id: ModuleId) -> Option<&FxHashSet<ModuleId>> {
let pos = self.0.iter().position(|set| set.contains(&id))?; let pos = self.0.iter().position(|set| set.contains(&id))?;
Some(&self.0[pos]) Some(&self.0[pos])
@ -53,7 +54,7 @@ impl Circulars {
} }
impl Deref for Circulars { impl Deref for Circulars {
type Target = Vec<AHashSet<ModuleId>>; type Target = Vec<FxHashSet<ModuleId>>;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
&self.0 &self.0
@ -76,7 +77,7 @@ impl PlanBuilder {
} }
} }
let mut set = AHashSet::default(); let mut set = FxHashSet::default();
set.insert(src); set.insert(src);
set.insert(imported); set.insert(imported);
self.circular.push(set); self.circular.push(set);
@ -98,11 +99,11 @@ pub(super) struct Plan {
pub entries: Vec<ModuleId>, pub entries: Vec<ModuleId>,
/// key is entry /// key is entry
pub normal: AHashMap<ModuleId, NormalPlan>, pub normal: FxHashMap<ModuleId, NormalPlan>,
/// key is entry /// key is entry
pub circular: AHashMap<ModuleId, CircularPlan>, pub circular: FxHashMap<ModuleId, CircularPlan>,
pub bundle_kinds: AHashMap<ModuleId, BundleKind>, pub bundle_kinds: FxHashMap<ModuleId, BundleKind>,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -165,7 +166,7 @@ where
self.add_to_graph(&mut builder, module.id, &mut vec![], true); self.add_to_graph(&mut builder, module.id, &mut vec![], true);
} }
let mut metadata = AHashMap::<ModuleId, Metadata>::default(); let mut metadata = FxHashMap::<ModuleId, Metadata>::default();
// Draw dependency graph to calculte // Draw dependency graph to calculte
for (id, _) in &builder.kinds { for (id, _) in &builder.kinds {
@ -205,7 +206,7 @@ where
Ok((self.build_plan(&metadata, builder), graph)) Ok((self.build_plan(&metadata, builder), graph))
} }
fn build_plan(&self, _metadata: &AHashMap<ModuleId, Metadata>, builder: PlanBuilder) -> Plan { fn build_plan(&self, _metadata: &FxHashMap<ModuleId, Metadata>, builder: PlanBuilder) -> Plan {
let mut plans = Plan::default(); let mut plans = Plan::default();
for (id, kind) in builder.kinds.iter() { for (id, kind) in builder.kinds.iter() {
@ -218,7 +219,7 @@ where
let root_entry = *root_entry; let root_entry = *root_entry;
let mut bfs = Bfs::new(&builder.direct_deps, root_entry); let mut bfs = Bfs::new(&builder.direct_deps, root_entry);
let mut done = AHashSet::new(); let mut done = FxHashSet::default();
while let Some(entry) = bfs.next(&builder.direct_deps) { while let Some(entry) = bfs.next(&builder.direct_deps) {
let mut deps: Vec<_> = builder let mut deps: Vec<_> = builder

View File

@ -1,8 +1,8 @@
use super::Bundler; use super::Bundler;
use crate::{load::Load, resolve::Resolve}; use crate::{load::Load, resolve::Resolve};
use ahash::AHashMap;
use ahash::AHashSet;
use anyhow::{Context, Error}; use anyhow::{Context, Error};
use fxhash::FxHashMap;
use fxhash::FxHashSet;
use retain_mut::RetainMut; use retain_mut::RetainMut;
use swc_atoms::{js_word, JsWord}; use swc_atoms::{js_word, JsWord};
use swc_common::{sync::Lrc, FileName, Mark, Spanned, SyntaxContext, DUMMY_SP}; use swc_common::{sync::Lrc, FileName, Mark, Spanned, SyntaxContext, DUMMY_SP};
@ -94,7 +94,7 @@ pub(super) struct RawImports {
/// function bar() {} /// function bar() {}
/// foo[bar()] /// foo[bar()]
/// ``` /// ```
pub forced_ns: AHashSet<JsWord>, pub forced_ns: FxHashSet<JsWord>,
} }
/// This type implements two operation (analysis, deglobbing) to reduce binary /// This type implements two operation (analysis, deglobbing) to reduce binary
@ -114,13 +114,13 @@ where
/// HashMap from the local identifier of a namespace import to used /// HashMap from the local identifier of a namespace import to used
/// properties. /// properties.
usages: AHashMap<Id, Vec<Id>>, usages: FxHashMap<Id, Vec<Id>>,
/// While deglobbing, we also marks imported identifiers. /// While deglobbing, we also marks imported identifiers.
imported_idents: AHashMap<Id, SyntaxContext>, imported_idents: FxHashMap<Id, SyntaxContext>,
deglob_phase: bool, deglob_phase: bool,
idents_to_deglob: AHashSet<Id>, idents_to_deglob: FxHashSet<Id>,
/// `true` while folding objects of a member expression. /// `true` while folding objects of a member expression.
/// ///

View File

@ -1,6 +1,6 @@
use crate::id::Id; use crate::id::Id;
use crate::util::MapWithMut; use crate::util::MapWithMut;
use ahash::AHashMap; use fxhash::FxHashMap;
use swc_atoms::js_word; use swc_atoms::js_word;
use swc_ecma_ast::*; use swc_ecma_ast::*;
use swc_ecma_utils::private_ident; use swc_ecma_utils::private_ident;
@ -10,7 +10,7 @@ use swc_ecma_visit::VisitMutWith;
#[derive(Default)] #[derive(Default)]
pub struct KeywordRenamer { pub struct KeywordRenamer {
renamed: AHashMap<Id, Ident>, renamed: FxHashMap<Id, Ident>,
} }
impl KeywordRenamer { impl KeywordRenamer {

View File

@ -1,5 +1,5 @@
use crate::ModuleId; use crate::ModuleId;
use ahash::AHashMap; use fxhash::FxHashMap;
use retain_mut::RetainMut; use retain_mut::RetainMut;
use std::mem::take; use std::mem::take;
use swc_common::SourceMap; use swc_common::SourceMap;
@ -24,8 +24,8 @@ pub struct Modules {
// We will change this into `Vec<Module>`. // We will change this into `Vec<Module>`.
modules: Vec<(ModuleId, Module)>, modules: Vec<(ModuleId, Module)>,
prepended_stmts: AHashMap<ModuleId, Vec<ModuleItem>>, prepended_stmts: FxHashMap<ModuleId, Vec<ModuleItem>>,
appended_stmts: AHashMap<ModuleId, Vec<ModuleItem>>, appended_stmts: FxHashMap<ModuleId, Vec<ModuleItem>>,
} }
impl Modules { impl Modules {

View File

@ -2,8 +2,8 @@ use super::stmt::sort_stmts;
use crate::dep_graph::ModuleGraph; use crate::dep_graph::ModuleGraph;
use crate::modules::Modules; use crate::modules::Modules;
use crate::ModuleId; use crate::ModuleId;
use ahash::AHashSet;
use ahash::RandomState; use ahash::RandomState;
use fxhash::FxHashSet;
use indexmap::IndexSet; use indexmap::IndexSet;
use petgraph::algo::all_simple_paths; use petgraph::algo::all_simple_paths;
use petgraph::EdgeDirection::Outgoing; use petgraph::EdgeDirection::Outgoing;
@ -96,6 +96,16 @@ fn toposort_real_modules<'a>(
continue; continue;
} }
// Skip sorting statements if there is no import.
if ids.len() == 1 {
if graph.neighbors_directed(ids[0], Outgoing).count() == 0 {
chunks.push(Chunk {
stmts: stmts.into_iter().next().unwrap(),
});
continue;
}
}
let stmts = sort_stmts(injected_ctxt, stmts, cm); let stmts = sort_stmts(injected_ctxt, stmts, cm);
// print_hygiene( // print_hygiene(
@ -117,7 +127,7 @@ fn toposort_real_modules<'a>(
/// Get all modules in a cycle. /// Get all modules in a cycle.
fn all_modules_in_circle( fn all_modules_in_circle(
id: ModuleId, id: ModuleId,
done: &AHashSet<ModuleId>, done: &FxHashSet<ModuleId>,
already_in_index: &mut IndexSet<ModuleId, RandomState>, already_in_index: &mut IndexSet<ModuleId, RandomState>,
graph: &ModuleGraph, graph: &ModuleGraph,
) -> IndexSet<ModuleId, RandomState> { ) -> IndexSet<ModuleId, RandomState> {
@ -159,7 +169,7 @@ fn toposort_real_module_ids<'a>(
mut queue: VecDeque<ModuleId>, mut queue: VecDeque<ModuleId>,
graph: &'a ModuleGraph, graph: &'a ModuleGraph,
) -> impl 'a + Iterator<Item = Vec<ModuleId>> { ) -> impl 'a + Iterator<Item = Vec<ModuleId>> {
let mut done = AHashSet::<ModuleId>::default(); let mut done = FxHashSet::<ModuleId>::default();
from_fn(move || { from_fn(move || {
while let Some(id) = queue.pop_front() { while let Some(id) = queue.pop_front() {

View File

@ -1,5 +1,5 @@
use crate::util::fast_graph::FastDiGraphMap; use crate::util::fast_graph::FastDiGraphMap;
use ahash::AHashSet; use fxhash::FxHashSet;
use petgraph::EdgeDirection; use petgraph::EdgeDirection;
use petgraph::EdgeDirection::Incoming; use petgraph::EdgeDirection::Incoming;
use petgraph::EdgeDirection::Outgoing; use petgraph::EdgeDirection::Outgoing;
@ -22,7 +22,7 @@ pub(super) struct StmtDepGraph {
inner: FastDiGraphMap<usize, Required>, inner: FastDiGraphMap<usize, Required>,
/// Read-optimized hashset which contains all direct dependencies and /// Read-optimized hashset which contains all direct dependencies and
/// transitive dependencies. /// transitive dependencies.
paths: Vec<AHashSet<usize>>, paths: Vec<FxHashSet<usize>>,
} }
impl StmtDepGraph { impl StmtDepGraph {
@ -44,8 +44,8 @@ impl StmtDepGraph {
self.insert_transitives(a, b); self.insert_transitives(a, b);
} }
fn calc_transitives(&self, id: usize, dir: EdgeDirection) -> AHashSet<usize> { fn calc_transitives(&self, id: usize, dir: EdgeDirection) -> FxHashSet<usize> {
let mut set = AHashSet::default(); let mut set = FxHashSet::default();
let mut queue = VecDeque::default(); let mut queue = VecDeque::default();
queue.push_front(id); queue.push_front(id);

View File

@ -2,8 +2,8 @@ use super::graph::Required;
use crate::id::Id; use crate::id::Id;
use crate::modules::sort::graph::StmtDepGraph; use crate::modules::sort::graph::StmtDepGraph;
use crate::util::MapWithMut; use crate::util::MapWithMut;
use ahash::AHashMap; use fxhash::FxHashMap;
use ahash::AHashSet; use fxhash::FxHashSet;
use indexmap::IndexSet; use indexmap::IndexSet;
use petgraph::EdgeDirection::Incoming as Dependants; use petgraph::EdgeDirection::Incoming as Dependants;
use petgraph::EdgeDirection::Outgoing as Dependancies; use petgraph::EdgeDirection::Outgoing as Dependancies;
@ -103,8 +103,8 @@ fn iter<'a>(
// dbg!(&free); // dbg!(&free);
// dbg!(&module_starts); // dbg!(&module_starts);
let mut moves = AHashSet::new(); let mut moves = FxHashSet::default();
let mut done = AHashSet::new(); let mut done = FxHashSet::default();
let mut stack = VecDeque::new(); let mut stack = VecDeque::new();
stack.extend(module_starts.iter().copied()); stack.extend(module_starts.iter().copied());
@ -343,7 +343,7 @@ fn iter<'a>(
struct FieldInitFinter { struct FieldInitFinter {
in_object_assign: bool, in_object_assign: bool,
in_rhs: bool, in_rhs: bool,
accessed: AHashSet<Id>, accessed: FxHashSet<Id>,
} }
impl FieldInitFinter { impl FieldInitFinter {
@ -643,8 +643,8 @@ fn calc_deps(new: &[ModuleItem]) -> StmtDepGraph {
log::debug!("Analyzing dependencies between statements"); log::debug!("Analyzing dependencies between statements");
let mut graph = StmtDepGraph::default(); let mut graph = StmtDepGraph::default();
let mut declared_by = AHashMap::<Id, Vec<usize>>::default(); let mut declared_by = FxHashMap::<Id, Vec<usize>>::default();
let mut uninitialized_ids = AHashMap::<Id, usize>::new(); let mut uninitialized_ids = FxHashMap::<Id, usize>::default();
for (idx, item) in new.iter().enumerate() { for (idx, item) in new.iter().enumerate() {
graph.add_node(idx); graph.add_node(idx);

View File

@ -1,9 +1,9 @@
use anyhow::{bail, Context, Error}; use anyhow::{bail, Context, Error};
use reqwest::Url; use reqwest::Url;
use sha1::{Digest, Sha1}; use sha1::{Digest, Sha1};
use std::env::current_dir;
use std::io::Write; use std::io::Write;
use std::{ use std::{
self, env,
fs::{create_dir_all, read_to_string, write}, fs::{create_dir_all, read_to_string, write},
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
@ -39,7 +39,7 @@ fn calc_cache_path(cache_dir: &Path, url: &Url) -> PathBuf {
/// Load url. This method does caching. /// Load url. This method does caching.
fn load_url(url: Url) -> Result<String, Error> { fn load_url(url: Url) -> Result<String, Error> {
let cache_dir = PathBuf::from( let cache_dir = PathBuf::from(
env::var("CARGO_MANIFEST_DIR") current_dir()
.expect("the test requires an environment variable named `CARGO_MANIFEST_DIR`"), .expect("the test requires an environment variable named `CARGO_MANIFEST_DIR`"),
) )
.join("tests") .join("tests")

View File

@ -1608,6 +1608,8 @@ function joinGlobs(globs, { extended =false , globstar =false } = {
} }
const mod3 = function() { const mod3 = function() {
return { return {
SEP: SEP,
SEP_PATTERN: SEP_PATTERN,
win32: mod1, win32: mod1,
posix: mod2, posix: mod2,
basename: basename2, basename: basename2,
@ -1625,8 +1627,6 @@ const mod3 = function() {
sep: sep2, sep: sep2,
toFileUrl: toFileUrl2, toFileUrl: toFileUrl2,
toNamespacedPath: toNamespacedPath2, toNamespacedPath: toNamespacedPath2,
SEP: SEP,
SEP_PATTERN: SEP_PATTERN,
globToRegExp, globToRegExp,
isGlob, isGlob,
normalizeGlob, normalizeGlob,

View File

@ -1618,6 +1618,8 @@ function joinGlobs(globs, { extended =false , globstar =false } = {
} }
const mod3 = function() { const mod3 = function() {
return { return {
SEP: SEP,
SEP_PATTERN: SEP_PATTERN,
win32: win32, win32: win32,
posix: posix, posix: posix,
basename: basename2, basename: basename2,
@ -1635,8 +1637,6 @@ const mod3 = function() {
sep: sep2, sep: sep2,
toFileUrl: toFileUrl2, toFileUrl: toFileUrl2,
toNamespacedPath: toNamespacedPath2, toNamespacedPath: toNamespacedPath2,
SEP: SEP,
SEP_PATTERN: SEP_PATTERN,
globToRegExp, globToRegExp,
isGlob, isGlob,
normalizeGlob, normalizeGlob,