compress-all

This commit is contained in:
Motiejus Jakštys 2024-02-13 13:45:09 +02:00
parent adb8a26adc
commit db07a9d5ba
5 changed files with 155 additions and 54 deletions

View File

@ -107,6 +107,7 @@
tmuxbash = super.callPackage ./pkgs/tmuxbash.nix {};
nicer = super.callPackage ./pkgs/nicer.nix {};
gamja = super.callPackage ./pkgs/gamja.nix {};
compressAll = super.callPackage ./pkgs/compress-all.nix {};
})
];
in
@ -322,7 +323,7 @@
};
};
packages.gamja = pkgs.gamja;
packages.gamja = pkgs.compressAll pkgs.gamja;
devShells.default = pkgs.mkShellNoCC {
packages = [

View File

@ -312,7 +312,7 @@
abort @denied
tls {$CREDENTIALS_DIRECTORY}/irc.jakstys.lt-cert.pem {$CREDENTIALS_DIRECTORY}/irc.jakstys.lt-key.pem
root * ${gamja.passthru.data-compressed}
root * ${pkgs.compressAll gamja}
file_server browse {
precompressed br gzip
}

View File

@ -78,7 +78,7 @@
route /static/assets/* {
uri strip_prefix /static/assets
file_server * {
root ${pkgs.gitea.passthru.data-compressed}/public
root ${pkgs.compressAll pkgs.gitea.data}/public
precompressed br gzip
}
}

128
pkgs/compress-all.nix Normal file
View File

@ -0,0 +1,128 @@
/*
compress-all compresses files in a given derivation.
Useful when one wants to pre-compress certain static assets and pass them to
the web server. For example, `pkgs.gamja` creates this derivation:
/nix/store/2wn1qbk8gp4y2m8xvafxv1b2dcdqj8fz-gamja-1.0.0-beta.9/
index.2fd01148.js
index.2fd01148.js.map
index.37aa9a8a.css
index.37aa9a8a.css.map
index.html
manifest.webmanifest
`pkgs.compressAll pkgs.gamja`:
/nix/store/f5ryid7zrw2hid7h9kil5g5j29q5r2f7-gamja-1.0.0-beta.9-compressed
index.2fd01148.js -> /nix/store/2wn1qbk8gp4y2m8xvafxv1b2dcdqj8fz-gamja-1.0.0-beta.9/index.2fd01148.js
index.2fd01148.js.br
index.2fd01148.js.gz
index.2fd01148.js.map -> /nix/store/2wn1qbk8gp4y2m8xvafxv1b2dcdqj8fz-gamja-1.0.0-beta.9/index.2fd01148.js.map
index.2fd01148.js.map.br
index.2fd01148.js.map.gz
index.37aa9a8a.css -> /nix/store/2wn1qbk8gp4y2m8xvafxv1b2dcdqj8fz-gamja-1.0.0-beta.9/index.37aa9a8a.css
index.37aa9a8a.css.br
index.37aa9a8a.css.gz
index.37aa9a8a.css.map -> /nix/store/2wn1qbk8gp4y2m8xvafxv1b2dcdqj8fz-gamja-1.0.0-beta.9/index.37aa9a8a.css.map
index.37aa9a8a.css.map.br
index.37aa9a8a.css.map.gz
index.html -> /nix/store/2wn1qbk8gp4y2m8xvafxv1b2dcdqj8fz-gamja-1.0.0-beta.9/index.html
index.html.br
index.html.gz
manifest.webmanifest -> /nix/store/2wn1qbk8gp4y2m8xvafxv1b2dcdqj8fz-gamja-1.0.0-beta.9/manifest.webmanifest
manifest.webmanifest.br
manifest.webmanifest.gz
When this `-compressed` directory is passed to a properly configured web
server, it will serve those pre-compressed files:
$ curl -I -H 'Accept-Encoding: br' https://irc.example.org/
<...>
content-encoding: br
<...>
For example, a caddy configuration snippet for gamja to serve
the static assets (JS, CSS files) pre-compressed:
virtualHosts."irc.example.org".extraConfig = ''
root * ${pkgs.compressAll pkgs.gamja}
file_server browse {
precompressed br gzip
}
'';
This feature is also available in nginx via `ngx_brotli` and
`ngx_http_gzip_static_module`.
Inputs:
- extensions :: [String]
The default list of file extensions to compress.
Default: common formats that compress well. The list may be appended (but
not reduced) without warning.
- extraExtensions :: [String]
Extra extensions to compress in addition to `extensions`.
- compressors :: [String]
A list of compressor names to use.
Default: ["gz" "br"]
- compressor-<COMPRESSOR> :: String
Maps a desired extension (e.g. `gz`) to a compress program (e.g. `zopfli
--keep {}`).
The compressor program that will be executed to get the `COMPRESSOR`
extension. The program is passed to xargs like this:
xargs -I{} -n1 ${prog}
Example:
compressor-xz = "${xz}/bin/xz --keep {}";
compressor-zst = "${zstd}/bin/zstd --keep {}";
*/
{
lib,
runCommand,
xorg,
zopfli,
brotli,
xz,
zstd,
extensions ? ["css" "js" "svg" "ttf" "eot" "txt" "xml" "map" "html" "json" "webmanifest"],
extraExtensions ? [],
compressors ? ["gz" "br"],
} @ args: drv: let
compressorMap =
{
compressor-gz = "${zopfli}/bin/zopfli --keep {}";
compressor-br = "${brotli}/bin/brotli --keep --no-copy-stat {}";
compressor-xz = "${xz}/bin/xz --keep {}";
compressor-zst = "${zstd}/bin/zstd --keep {}";
}
// lib.filterAttrs (k: _: (lib.hasPrefix "compressor-" k)) args;
compressCommands =
map
(ext: let
prog = builtins.getAttr "compressor-${ext}" compressorMap;
in "tee >(xargs -I{} -n1 -P$NIX_BUILD_CORES ${prog})")
compressors;
extensionsVbar = builtins.concatStringsSep "|" (extensions ++ extraExtensions);
in
runCommand "${drv.name}-compressed" {} ''
mkdir $out
${xorg.lndir}/bin/lndir ${drv}/ $out/
find -L $out -type f -regextype posix-extended \
-iregex '.*\.(${extensionsVbar})' | \
${builtins.concatStringsSep " | \\\n " compressCommands}
''

View File

@ -1,20 +1,14 @@
{
lib,
stdenvNoCC,
fetchFromSourcehut,
buildNpmPackage,
runCommand,
writeText,
brotli,
zopfli,
xorg,
# https://git.sr.ht/~emersion/gamja/tree/master/doc/config-file.md
gamjaConfig ? null,
}: let
version = "1.0.0-beta.9";
pkg = buildNpmPackage {
}:
buildNpmPackage rec {
pname = "gamja";
inherit version;
version = "1.0.0-beta.9";
src = fetchFromSourcehut {
owner = "~emersion";
@ -25,37 +19,15 @@
npmDepsHash = "sha256-LxShwZacCctKAfMNCUMyrSaI1hIVN80Wseq/d8WITkc=";
installPhase = ''
mv dist $out
${lib.optionalString (gamjaConfig != null) "cp ${writeText "gamja-config" (builtins.toJSON gamjaConfig)} $out/config.json"}
'';
};
in
stdenvNoCC.mkDerivation {
name = pkg.pname;
inherit (pkg) version;
src = pkg;
sourceRoot = ".";
installPhase = ''
runHook preInstall
mv gamja-${version} $out
cp -r dist $out
${lib.optionalString (gamjaConfig != null) "cp ${writeText "gamja-config" (builtins.toJSON gamjaConfig)} $out/config.json"}
runHook postInstall
'';
passthru = {
data-compressed = runCommand "gamja-compressed" {} ''
mkdir $out
${xorg.lndir}/bin/lndir ${pkg}/ $out/
find $out \
-regextype posix-extended \
-iregex '.*\.(css|js|json|map|webmanifest|html)' | \
tee >(xargs -n1 -P''$(nproc) ${zopfli}/bin/zopfli) | \
xargs -n1 -P''$(nproc) ${brotli}/bin/brotli --no-copy-stat
'';
};
meta = with lib; {
description = "A simple IRC web client";
homepage = "https://git.sr.ht/~emersion/gamja";