diff --git a/src/commands/build/wranglerjs/mod.rs b/src/commands/build/wranglerjs/mod.rs index 55a537aec..d259b83ad 100644 --- a/src/commands/build/wranglerjs/mod.rs +++ b/src/commands/build/wranglerjs/mod.rs @@ -49,13 +49,11 @@ pub fn run_build(project: &Project) -> Result<(), failure::Error> { .write(&wranglerjs_output) .expect("could not write bundle to disk"); - let mut msg = format!( - "Built successfully, script size is {}", - wranglerjs_output.script_size() + let msg = format!( + "Built successfully, built project size is {}", + wranglerjs_output.project_size() ); - if bundle.has_wasm() { - msg = format!("{} and Wasm size is {}", msg, wranglerjs_output.wasm_size()); - } + message::success(&msg); Ok(()) } else { diff --git a/src/commands/build/wranglerjs/output.rs b/src/commands/build/wranglerjs/output.rs index 9234034d1..fd4dd8cb9 100644 --- a/src/commands/build/wranglerjs/output.rs +++ b/src/commands/build/wranglerjs/output.rs @@ -1,3 +1,4 @@ +use crate::terminal::emoji; use flate2::write::ZlibEncoder; use flate2::Compression; use number_prefix::{NumberPrefix, Prefixed, Standalone}; @@ -24,25 +25,52 @@ impl WranglerjsOutput { self.errors.join("\n") } - pub fn script_size(&self) -> String { + fn project_size_bytes(&self) -> u64 { let mut e = ZlibEncoder::new(Vec::new(), Compression::default()); + + //approximation of how projects are gzipped e.write_all(&self.script.as_bytes()) - .expect("could not write buffer"); - let compressed_bytes = e.finish(); + .expect("could not write script buffer"); - match NumberPrefix::decimal(compressed_bytes.unwrap().len() as f64) { - Standalone(bytes) => format!("{} bytes", bytes), - Prefixed(prefix, n) => format!("{:.0} {}B", n, prefix), + if let Some(wasm) = &self.wasm { + e.write_all(wasm.to_owned().as_bytes()) + .expect("could not write wasm buffer"); } + + e.finish().expect("failed to compress project").len() as u64 } - pub fn wasm_size(&self) -> String { - let size = self.wasm.to_owned().unwrap().len(); - match NumberPrefix::decimal(size as f64) { + fn project_size_message(compressed_size: u64) -> String { + const MAX_PROJECT_SIZE: u64 = 1 << 20; // 1 MiB + const WARN_THRESHOLD: u64 = MAX_PROJECT_SIZE - 81_920; //Warn when less than 80 KiB left to grow, ~92% usage + + let bytes_left = MAX_PROJECT_SIZE.checked_sub(compressed_size); + + let human_size = match NumberPrefix::binary(compressed_size as f64) { Standalone(bytes) => format!("{} bytes", bytes), Prefixed(prefix, n) => format!("{:.0} {}B", n, prefix), + }; + + let human_leftover = if let Some(bytes_left) = bytes_left { + let msg = match NumberPrefix::binary(bytes_left as f64) { + Standalone(bytes) => format!("{} bytes", bytes), + Prefixed(prefix, n) => format!("{:.0} {}B", n, prefix), + }; + Some(msg) + } else { + None + }; + + match compressed_size { + WARN_THRESHOLD...MAX_PROJECT_SIZE => format!("{}. {2} Your built project is {} away from reaching the 1MiB size limit. {2}", human_size, human_leftover.expect("failed to get leftover bytes"), emoji::WARN), + 0...WARN_THRESHOLD => format!("{}.", human_size), + _ => format!("{}. {1} Your built project has grown past the 1MiB size limit and may fail to deploy. {1}", human_size, emoji::WARN) } } + + pub fn project_size(&self) -> String { + Self::project_size_message(self.project_size_bytes()) + } } #[cfg(test)] @@ -50,24 +78,34 @@ mod tests { use super::*; #[test] - fn it_returns_gzip_script_size() { + fn it_warns_over_max_size() { + assert!(WranglerjsOutput::project_size_message(1 << 21).contains("grown past")); + } + + #[test] + fn it_warns_near_max_size() { + assert!(WranglerjsOutput::project_size_message((1 << 20) - 4096).contains("reaching")); + } + + #[test] + fn it_returns_project_size_with_wasm() { let wranglerjs_output = WranglerjsOutput { errors: vec![], - script: "aaaa".to_string(), - wasm: None, + script: "abcdefg".to_string(), + wasm: Some("123456".to_string()), }; - assert_eq!(wranglerjs_output.script_size(), "12 bytes"); + assert_eq!(wranglerjs_output.project_size_bytes(), 21); } #[test] - fn it_returns_wasm_size() { + fn it_returns_project_size_without_wasm() { let wranglerjs_output = WranglerjsOutput { errors: vec![], - script: "".to_string(), - wasm: Some("abc".to_string()), + script: "abcdefg".to_string(), + wasm: None, }; - assert_eq!(wranglerjs_output.wasm_size(), "3 bytes"); + assert_eq!(wranglerjs_output.project_size_bytes(), 15); } }