turbopack_bench/bundlers/
mod.rs

1use std::{path::Path, process::Child, time::Duration};
2
3use anyhow::Result;
4
5use self::{
6    nextjs::{NextJs, NextJsVersion},
7    parcel::Parcel,
8    vite::Vite,
9    webpack::Webpack,
10};
11use crate::bundlers::rspack::Rspack;
12
13mod nextjs;
14mod parcel;
15mod rspack;
16mod vite;
17mod webpack;
18
19#[derive(Debug, Clone, Copy)]
20pub enum RenderType {
21    /// App is completely rendered on client side, the initial HTML is empty.
22    ClientSideRendered,
23    /// App is intially rendered on server side, then hydrated on client side.
24    ServerSidePrerendered,
25    /// App is rendered on server side, but additional client side javascript
26    /// emits events on hydration and changes
27    ServerSideRenderedWithEvents,
28    /// App is rendered on server side, without any client side events.
29    #[allow(dead_code)]
30    ServerSideRenderedWithoutInteractivity,
31}
32
33pub trait Bundler {
34    fn get_name(&self) -> &str;
35    fn get_path(&self) -> &str {
36        "/"
37    }
38    fn react_version(&self) -> &str {
39        "^18.2.0"
40    }
41    fn render_type(&self) -> RenderType {
42        RenderType::ClientSideRendered
43    }
44    /// There is a hydration done event emitted by client side JavaScript
45    fn has_hydration_event(&self) -> bool {
46        !matches!(
47            self.render_type(),
48            RenderType::ServerSideRenderedWithoutInteractivity
49        )
50    }
51
52    fn prepare(&self, _template_dir: &Path) -> Result<()> {
53        Ok(())
54    }
55    fn prepare_each(&self, _template_dir: &Path) -> Result<()> {
56        Ok(())
57    }
58    fn start_server(&self, test_dir: &Path) -> Result<(Child, String)>;
59
60    /// The maximum amount of time to wait for HMR during the setup and warmup
61    /// phase.
62    fn max_init_update_timeout(&self, _module_count: usize) -> Duration {
63        Duration::from_secs(60)
64    }
65
66    /// The maximum amount of time to wait for HMR during the actual benchmark.
67    /// This is a lot shorter than the init timeout because we expect
68    /// updates to generally happen quickly, and we don't want to wait for a
69    /// long time when an update is dropped.
70    fn max_update_timeout(&self, _module_count: usize) -> Duration {
71        Duration::from_secs(5)
72    }
73}
74
75pub fn get_bundlers() -> Vec<Box<dyn Bundler>> {
76    vec![
77        Box::new(NextJs::new(
78            NextJsVersion::Canary,
79            "Next.js canary Turbo SSR",
80            "/page",
81            true,
82            RenderType::ServerSidePrerendered,
83        )),
84        Box::new(NextJs::new(
85            NextJsVersion::Canary,
86            "Next.js canary Turbo RSC",
87            "/app",
88            true,
89            RenderType::ServerSideRenderedWithEvents,
90        )),
91        Box::new(NextJs::new(
92            NextJsVersion::Canary,
93            "Next.js canary Turbo RCC",
94            "/client",
95            true,
96            RenderType::ServerSideRenderedWithEvents,
97        )),
98        Box::new(NextJs::new(
99            NextJsVersion::V14,
100            "Next.js 14 Turbo SSR",
101            "/page",
102            true,
103            RenderType::ServerSidePrerendered,
104        )),
105        Box::new(NextJs::new(
106            NextJsVersion::V14,
107            "Next.js 14 Turbo RSC",
108            "/app",
109            true,
110            RenderType::ServerSideRenderedWithEvents,
111        )),
112        Box::new(NextJs::new(
113            NextJsVersion::V14,
114            "Next.js 14 Turbo RCC",
115            "/client",
116            true,
117            RenderType::ServerSidePrerendered,
118        )),
119        Box::new(NextJs::new(
120            NextJsVersion::V13,
121            "Next.js 13 Turbo SSR",
122            "/page",
123            true,
124            RenderType::ServerSidePrerendered,
125        )),
126        Box::new(NextJs::new(
127            NextJsVersion::V13,
128            "Next.js 13 Turbo RSC",
129            "/app",
130            true,
131            RenderType::ServerSideRenderedWithEvents,
132        )),
133        Box::new(NextJs::new(
134            NextJsVersion::V13,
135            "Next.js 13 Turbo RCC",
136            "/client",
137            true,
138            RenderType::ServerSidePrerendered,
139        )),
140        Box::new(NextJs::new(
141            NextJsVersion::Canary,
142            "Next.js canary webpack SSR",
143            "/page",
144            false,
145            RenderType::ServerSidePrerendered,
146        )),
147        Box::new(NextJs::new(
148            NextJsVersion::Canary,
149            "Next.js canary webpack RSC",
150            "/app",
151            false,
152            RenderType::ServerSideRenderedWithEvents,
153        )),
154        Box::new(NextJs::new(
155            NextJsVersion::Canary,
156            "Next.js canary webpack RCC",
157            "/client",
158            false,
159            RenderType::ServerSideRenderedWithEvents,
160        )),
161        Box::new(NextJs::new(
162            NextJsVersion::V14,
163            "Next.js 14 webpack SSR",
164            "/page",
165            false,
166            RenderType::ServerSidePrerendered,
167        )),
168        Box::new(NextJs::new(
169            NextJsVersion::V14,
170            "Next.js 14 webpack RSC",
171            "/app",
172            false,
173            RenderType::ServerSideRenderedWithEvents,
174        )),
175        Box::new(NextJs::new(
176            NextJsVersion::V14,
177            "Next.js 14 webpack RCC",
178            "/client",
179            false,
180            RenderType::ServerSidePrerendered,
181        )),
182        Box::new(NextJs::new(
183            NextJsVersion::V13,
184            "Next.js 13 webpack SSR",
185            "/page",
186            false,
187            RenderType::ServerSidePrerendered,
188        )),
189        Box::new(NextJs::new(
190            NextJsVersion::V13,
191            "Next.js 13 webpack RSC",
192            "/app",
193            false,
194            RenderType::ServerSideRenderedWithEvents,
195        )),
196        Box::new(NextJs::new(
197            NextJsVersion::V13,
198            "Next.js 13 webpack RCC",
199            "/client",
200            false,
201            RenderType::ServerSidePrerendered,
202        )),
203        Box::new(NextJs::new(
204            NextJsVersion::V12,
205            "Next.js 12 webpack SSR",
206            "/page",
207            false,
208            RenderType::ServerSidePrerendered,
209        )),
210        Box::new(Parcel {}),
211        Box::new(Vite::new(false, false)),
212        Box::new(Vite::new(true, false)),
213        Box::new(Vite::new(false, true)),
214        Box::new(Webpack {}),
215        Box::new(Rspack {}),
216    ]
217}