pub struct Builder { /* private fields */ }Expand description
Assembles a build: which folders are inputs, which directory receives the output, and which external tools transform what.
Every path is canonicalized and checked as it is registered, so a misconfiguration is
reported while the builder is being assembled rather than partway through a build that
has already written files. Builder::build then runs every configured pipeline once.
§Example
use mini_build::{Builder, CssOptions, CssTool};
use std::path::Path;
Builder::new(Path::new("./public"))?
.source_folder(Path::new("./src/styles"))?
.css_tool(CssTool::LightningCss, CssOptions::default())
.build()?;Implementations§
Source§impl Builder
impl Builder
Sourcepub fn new(output_dir: &Path) -> Result<Self, BuildError>
pub fn new(output_dir: &Path) -> Result<Self, BuildError>
Start a build that writes into output_dir.
§Errors
BuildError::Io if output_dir cannot be canonicalized — it must already exist,
since a typo that silently creates a directory tree is worse than an error.
Sourcepub fn source_folder(self, dir: &Path) -> Result<Self, BuildError>
pub fn source_folder(self, dir: &Path) -> Result<Self, BuildError>
Register a folder of CSS/JS inputs to be transformed into the output dir.
§Errors
BuildError::Io if dir cannot be canonicalized; BuildError::Config if it
overlaps the output dir or an already-registered source or asset folder.
Sourcepub fn asset_folder(self, dir: &Path) -> Result<Self, BuildError>
pub fn asset_folder(self, dir: &Path) -> Result<Self, BuildError>
Register a folder mirrored byte-for-byte into the output dir, whatever the
extension — images, fonts, robots.txt, hand-written HTML.
§Errors
Sourcepub fn css_tool(self, tool: CssTool, options: CssOptions) -> Self
pub fn css_tool(self, tool: CssTool, options: CssOptions) -> Self
Transform CSS with tool, per options.
Sourcepub fn js_tool(
self,
tool: JsTool,
options: JsOptions,
) -> Result<Self, BuildError>
pub fn js_tool( self, tool: JsTool, options: JsOptions, ) -> Result<Self, BuildError>
Transform JS with tool, per options.
§Errors
BuildError::Io if a configured bundle entry cannot be canonicalized;
BuildError::Config if it does not lie under a registered source folder — which
would mean bundling a file this build does not consider an input, so register the
folder first.
Sourcepub fn prune_output(self) -> Self
pub fn prune_output(self) -> Self
Delete the CSS bundle from the output dir when no CSS sources remain.
Off by default: pruning deletes files the builder did not necessarily write, and an output dir shared with hand-placed files should not lose them to a build.
Sourcepub fn subscribe(&self) -> Receiver<ChangeEvent>
pub fn subscribe(&self) -> Receiver<ChangeEvent>
Subscribe to the change events this build emits as it writes outputs.
A one-shot Builder::build emits these too, but they matter for a caller
watching for rebuilds — a dev server reloading a browser, say.
Sourcepub fn build(&self) -> Result<(), BuildError>
pub fn build(&self) -> Result<(), BuildError>
Run every configured pipeline once.
Tool availability is checked first, before any file is written: a build that is
going to fail for want of esbuild should fail before it has half-populated the
output dir.
§Errors
BuildError::ToolMissing if a configured tool’s binary is absent from PATH;
BuildError::Build if a pipeline ran and failed.
Sourcepub fn watch(
self,
on_error: impl FnMut(BuildError) + Send + 'static,
) -> Result<WatchHandle, BuildError>
pub fn watch( self, on_error: impl FnMut(BuildError) + Send + 'static, ) -> Result<WatchHandle, BuildError>
Build once, then keep the output dir in sync with the sources until the returned handle is dropped.
The initial build is part of the job: the output dir is not in sync with the
sources until it has run, so watching without it would leave a window where the
two disagree and nothing was going to correct it. Its failures come back through
the returned Result; failures of later rebuilds go to on_error, since by then
there is no call left to return from.
This is the development half of the split with a static server: this crate watches sources and writes the output dir, and the server watches the directory it serves. Because the server cannot observe a file before it is written, “reload only after the output exists” holds by construction rather than by careful sequencing.
§Errors
As Builder::build — the initial build runs the same checks.
§Example
use mini_build::Builder;
use std::path::Path;
let watching = Builder::new(Path::new("./public"))?
.source_folder(Path::new("./src/styles"))?
.watch(|e| eprintln!("rebuild failed: {e}"))?;
// ... outputs stay current until `watching` is dropped.
watching.stop();