diff --git a/CHANGELOG.md b/CHANGELOG.md index 8422906c8b7..87d2d52c8c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -419,3 +419,8 @@ - Fixed a bug where renaming a local variable which is used in combination with label shorthand syntax would produce invalid code. ([Surya Rose](https://github.com/GearsDatapacks)) + +- Fixed a bug where enabling `typescript_declarations = true` wouldn't generate + TypeScript declarations unless the build directory was manually deleted. The + compiler now automatically rebuilds the project when this configuration changes. + ([daniellionel01](https://github.com/daniellionel01)) diff --git a/compiler-core/src/build/project_compiler.rs b/compiler-core/src/build/project_compiler.rs index fcd3fdc8642..726ac25e7a5 100644 --- a/compiler-core/src/build/project_compiler.rs +++ b/compiler-core/src/build/project_compiler.rs @@ -188,6 +188,10 @@ where // verify that this version is appropriate. self.check_gleam_version()?; + // Checks if JavaScript configuration has changed since the last build (particularly TypeScript declarations) + // and rebuilds the project if necessary to ensure consistent compilation with current settings + self.rebuild_if_javascript_config_changed()?; + // The JavaScript target requires a prelude module to be written. self.write_prelude()?; @@ -261,6 +265,48 @@ where }) } + /// Checks if JavaScript configuration has changed since the last build. + /// If it has changed (e.g., TypeScript declarations setting), we clear the build directory + /// to ensure a clean rebuild with the new settings. + pub fn rebuild_if_javascript_config_changed(&self) -> Result<(), Error> { + if !self.target().is_javascript() || !self.options.codegen.should_codegen(true) { + return Ok(()); + } + + let build_path = self + .paths + .build_directory_for_target(self.mode(), self.target()); + + let ts_indicator_path = build_path.join("typescript-declarations.lock"); + let ts_enabled = self.config.javascript.typescript_declarations; + + let needs_rebuild = if ts_enabled { + !self.io.is_file(&ts_indicator_path) + } else { + self.io.is_file(&ts_indicator_path) + }; + + if needs_rebuild { + tracing::info!("removing_build_state_due_to_javascript_config_change"); + self.io.delete_directory(&build_path)?; + + self.io.mkdir(&build_path)?; + + if ts_enabled { + self.io + .write(&ts_indicator_path, "") + .map_err(|e| Error::FileIo { + action: FileIoAction::WriteTo, + kind: FileKind::File, + path: ts_indicator_path, + err: Some(e.to_string()), + })?; + } + } + + Ok(()) + } + pub fn compile_dependencies(&mut self) -> Result, Error> { assert!( self.stale_modules.is_empty(),