swc_bundler/bundler/chunk/plan/
mod.rs1use anyhow::{bail, Error};
2use rustc_hash::FxHashMap;
3use swc_graph_analyzer::{DepGraph, GraphAnalyzer};
4
5use crate::{
6 bundler::{load::TransformedModule, scope::Scope},
7 dep_graph::ModuleGraph,
8 BundleKind, Bundler, Load, ModuleId, Resolve,
9};
10
11#[cfg(test)]
12mod tests;
13
14#[derive(Debug, Default)]
15struct PlanBuilder {
16 kinds: FxHashMap<ModuleId, BundleKind>,
17}
18
19#[derive(Debug, Default)]
20pub(super) struct Plan {
21 pub entries: FxHashMap<ModuleId, BundleKind>,
22
23 pub all: Vec<ModuleId>,
25}
26
27impl DepGraph for Scope {
28 type ModuleId = ModuleId;
29
30 fn deps_of(&self, module_id: Self::ModuleId) -> Vec<Self::ModuleId> {
31 let m = self.get_module(module_id).expect("failed to get module");
32
33 m.imports
34 .specifiers
35 .iter()
36 .chain(m.exports.reexports.iter())
37 .map(|v| v.0.module_id)
38 .collect()
39 }
40}
41
42impl<L, R> Bundler<'_, L, R>
43where
44 L: Load,
45 R: Resolve,
46{
47 pub(super) fn determine_entries(
48 &self,
49 entries: FxHashMap<String, TransformedModule>,
50 ) -> Result<(Plan, ModuleGraph, Vec<Vec<ModuleId>>), Error> {
51 let mut builder = PlanBuilder::default();
52 let mut analyzer = GraphAnalyzer::new(&self.scope);
53
54 for (name, module) in entries {
55 if let Some(v) = builder.kinds.insert(module.id, BundleKind::Named { name }) {
56 bail!("Multiple entries with same input path detected: {:?}", v)
57 }
58
59 analyzer.load(module.id);
60 }
61 let res = analyzer.into_result();
62
63 Ok((
66 Plan {
67 entries: builder.kinds,
68 all: res.all,
69 },
70 res.graph,
71 res.cycles,
72 ))
73 }
74}