From b8064a8d3ed9de9773f358224cc4a58885e5ad94 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Mon, 2 Feb 2026 22:22:27 -0500 Subject: [PATCH] more work to get esbuild up --- src/Config.hs | 11 +++++- src/Psb/Main.hs | 3 +- src/Utilities/Bundling.hs | 70 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/Config.hs b/src/Config.hs index 97c05e4..ce18934 100644 --- a/src/Config.hs +++ b/src/Config.hs @@ -1,8 +1,14 @@ module Config where -outputDir :: String +import Development.Shake.FilePath (addExtension, ()) + +outputDir :: FilePath outputDir = "publish" +-- build artifacts go here +buildDir :: FilePath +buildDir = ".psb" + assetGlobs :: [String] assetGlobs = ["static//*", "robots.txt", "favicon.ico"] @@ -13,6 +19,9 @@ resourceGlobs = jsGlobs ++ cssGlobs prependResources :: (Functor m) => m String -> m String prependResources = fmap ("resources/" ++) +resourceHashPath :: FilePath -> FilePath +resourceHashPath input = outputDir addExtension input ".hash" + jsGlobs :: [String] jsGlobs = prependResources $ liftA2 (++) ["js//*."] ["js", "mjs"] diff --git a/src/Psb/Main.hs b/src/Psb/Main.hs index b21b504..b861a6a 100644 --- a/src/Psb/Main.hs +++ b/src/Psb/Main.hs @@ -58,7 +58,8 @@ buildSite = do Shake.need $ map (outputDir ) assetPaths -- handle js, css and anything else we want to process before moving - Shake.need <$> Shake.getDirectoryFiles "" resourceGlobs + resourcePaths <- Shake.getDirectoryFiles "resources/" resourceGlobs + Shake.need $ map resourceHashPath resourcePaths -- take the misc pages which aren't blog posts and make their html files Shake.need $ map indexHtmlOutputPath pagePaths diff --git a/src/Utilities/Bundling.hs b/src/Utilities/Bundling.hs index c31afb2..2ad3a26 100644 --- a/src/Utilities/Bundling.hs +++ b/src/Utilities/Bundling.hs @@ -1,13 +1,29 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE TypeFamilies #-} + module Utilities.Bundling ( bundled, ) where -import Development.Shake (Action, Rules, command_) +import Config (buildDir, cssGlobs, jsGlobs, outputDir) +import Development.Shake (Action, RuleResult, Rules, addOracle, cmd_, command_, getDirectoryFiles, need, (%>)) +import Development.Shake.Classes +import Development.Shake.FilePath (()) +import GHC.Generics (Generic) -- does not include specification of output location or input files generic_esbuild_options :: [String] -generic_esbuild_options = ["--minify", "--sourcemap", "--bundle", "--chunk-names=[name]-[hash]"] +generic_esbuild_options = ["--minify", "--sourcemap", "--bundle", "--chunk-names=[name]-[hash]", "--entry-names=[name]-[hash]"] + +data BuildOracleVariant = CSS | Javascript deriving (Show, Typeable, Eq, Generic, Hashable, Binary, NFData) + +type BuildOutputs = [FilePath] + +type instance RuleResult BuildOracleVariant = BuildOutputs + +resource_dir :: FilePath +resource_dir = outputDir "resources" -- TODO: not sure if I want all bundling to be an all at once afair, per file format -- or multiple stages for various formats @@ -16,5 +32,51 @@ generic_esbuild_options = ["--minify", "--sourcemap", "--bundle", "--chunk-names -- indicate completion/fulfill a need directive without rebuilding even when files -- are left unchanged, maybe have the need be a $(filename).hash which we compute -- ourselves based on the unminified input -bundled :: Rules () -bundled = error "TODO" +bundled :: Rules (BuildOracleVariant -> Action BuildOutputs) +bundled = addOracle $ \q -> case q of + CSS -> bundle_css + Javascript -> bundle_scripts + +css_dir :: FilePath +css_dir = resource_dir "css" + +css_meta_file :: FilePath +css_meta_file = buildDir "esbuild-css-meta.json" + +css_esbuild_options :: [String] +css_esbuild_options = + [ "--outdir=" ++ css_dir, + "--loader:.png=file", + "--loader:.woff2=file", + "--loader:.svg=file", + "--metafile=" ++ css_meta_file + ] + +-- need to take an input of resouces/blah.css +-- and in addition to bundling it +bundle_css :: Action BuildOutputs +bundle_css = do + need cssGlobs + css_files <- getDirectoryFiles "" cssGlobs + cmd_ "esbuild" (generic_esbuild_options ++ css_esbuild_options ++ css_files) + pure $ error "TODO: pull the list of files from the meta file" + +-- Javascript and typescript +-- potentially: +-- "--target=es2020" +-- , "--format=esm" +js_esbuild_options :: [String] +js_esbuild_options = ["--outdir=" ++ js_dir, "--splitting", "--metafile=" ++ js_meta_file] + +js_meta_file :: FilePath +js_meta_file = buildDir "esbuild-js-meta.json" + +js_dir :: FilePath +js_dir = resource_dir "js" + +bundle_scripts :: Action BuildOutputs +bundle_scripts = do + need jsGlobs + js_files <- getDirectoryFiles "" cssGlobs + cmd_ "esbuild" (generic_esbuild_options ++ js_esbuild_options ++ js_files) + pure $ error "TODO: pull the list of files from the meta file"