Overriding Collectstatic and Manifestic file storage

I am trying to integrate terser js minification in a django collectstatic command , by overriding the CompressedManifestStaticFileStorage of whitenoise in below code , but the def _save() method minifies the copied files but the hashed files are either stored as original or empty due to content.close() method i call during the minification. How can i bypass this so that both the original files and hashed files are minified with terser.

class MinifiedCompressedManifestStaticFilesStorage(CompressedManifestStaticFilesStorage):
    def minify_js(self, content_str):
        """Minify JavaScript using Terser and validate output."""
        terser_path = (
            os.path.abspath("./node_modules/.bin/terser.cmd")
            if os.name == "nt"
            else "./node_modules/.bin/terser"
        )
        try:
            command = f'"{terser_path}" -m -c' if os.name == "nt" else [terser_path, "-m", "-c"]
            # Explicitly specify Terser CLI path if installed locally
            result = subprocess.run(
                command,
                input=content_str.encode("utf-8"),
                capture_output=True,
                check=True,
            )
            minified = result.stdout
            if not minified:
                raise ValueError("Terser returned empty output")
            return minified
        except (subprocess.CalledProcessError, FileNotFoundError, ValueError) as e:
            print(f"Minification failed: {str(e)}. Using original content.")
            return content_str.encode("utf-8")  # Fallback to original

    def _save(self, name, content):
        if name.endswith(".js"):
            # Read and close original content
            content_str = content.read().decode("utf-8")
            content.close()

            # Minify and create new ContentFile
            minified_bytes = self.minify_js(content_str)
            content = ContentFile(minified_bytes, name=name)
            content.seek(0)  # Reset pointer for parent class

        return super()._save(name, content)

Вернуться на верх