Expand description
This library helps with managing assets (like JS or CSS files) in your web
application. It allows you to embed the files directly into your
executable (for ease of deployment), optionally in compressed form.
reinda
can also insert a hash into filenames to facilitate powerful web
caching. In development mode, all files are loaded dynamically, avoiding
recompilation and thus reducing feedback cycles.
§Quick start
There are three main steps:
- Use
embed!
to embed certain files into your binary. - Configure your assets via
Builder
and buildAssets
. - Serve your assets via
Assets::get
use reinda::Assets;
// Step 1: specify assets that you want to embed into the executable.
const EMBEDS: reinda::Embeds = reinda::embed! {
// Folder which contains your assets, relative to your `Cargo.toml`.
base_path: "assets",
// List files to embed. Supports glob patterns
files: [
"index.html",
"bundle.js",
"icons/*.svg",
],
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Step 2: Configure your assets next. In this example, all embedded
// assets are just added, without any special configuration. Note though
// that the first argument, the HTTP path, can differ.
let mut builder = Assets::builder();
builder.add_embedded("index.html", &EMBEDS["index.html"]);
builder.add_embedded("static/main.js", &EMBEDS["bundle.js"]).with_hash();
builder.add_embedded("static/icons/", &EMBEDS["icons/*.svg"]);
// You can also add assets not mentioned in `embed!` which are then
// always loaded at runtime.
builder.add_file("img/logo.svg", std::env::current_dir().unwrap().join("logo.svg"));
// Load & prepare all assets.
let assets = builder.build().await?;
// Step 3: serve assets (of course, this would be in an HTTP request handler).
let asset = assets.get("index.html").unwrap();
let bytes = asset.content().await?;
// ...
Ok(())
}
For a longer and more practical example, see examples/main.rs
in the
repository.
In practice, you likely want to use EntryBuilder::with_hash
for most of
your assets. And then use EntryBuilder::with_modifier
and/or
EntryBuilder::with_path_fixup
to fix the references across files.
§Prod vs. dev mode
Reinda operates in one of two modes: prod or dev. Prod mode is enabled
if you are building in release mode (e.g. cargo build --release
) or if
you enabled the crate feature always-prod
. Otherwise, dev mode is enabled.
The mode influences the behavior of reinda significantly. The following table describes those differences, though you likely don’t need to worry about the details too much.
Prod | Dev | |
---|---|---|
Summary | Embed assets & optimize for speed | Dynamically load assets for faster feedback cycles |
embed! | Loads & embeds assets into executable | Only stores asset paths |
with_hash | Hash inserted into filename | No hashes inserted |
Builder::build | Loads all assets, applies modifiers, calculates hashes | Does hardly anything, keeps storing paths |
Assets::get | Hashmap lookup | Checks if path matches any assets or globs |
Asset::content | Just returns the already loaded Bytes | Loads file from file system, applies modifier |
§Glossary: kinds of paths
This library is dealing with different kind of paths, which could be confused for one another. Here are the terms these docs try to use:
- FS path: a proper path referring to one file on the file system.
- Embed pattern: what you specify in
files
insideembed!
: could either be an FS path (referring to a single file) or contain a glob that matches any number of files. - HTTP path: the path under which assets are reachable.
- unhashed HTTP path: HTTP path before hashes are inserted. This is what
you specify in all
Builder::add_*
methods. - hashed HTTP path: HTTP path after inserting hashes (if configured).
This is what you pass to
Assets::get
and get insideAssets::iter
. Even for assets without a hashed filename, the same term is used for consistency. Meaning: for non-hashed assets or in dev mode, the hashed and unhashed HTTP path is exactly the same.
- unhashed HTTP path: HTTP path before hashes are inserted. This is what
you specify in all
§Cargo features
-
compress
(enabled by default): if enabled, embedded files are compressed. This often noticably reduces the binary size of the executable. This feature adds thebrotli
dependency. -
hash
(enabled by default): is required for support of filename hashing (see above). This feature adds thebase64
andsha2
dependencies. -
always-prod
: enabled prod mode even when compiled in debug mode. See the section about “prod” and “dev” mode above.
§Notes, Requirements and Limitations
reinda
consists of two crates:reinda-macros
and the main crate. Both crates have to be compiled with the same dev/prod mode. Cargo does this correctly by default, so don’t worry about this unless you add per-dependency overrides.- The environment variable
CARGO_MANIFEST_DIR
has to be set when expanding theembed!
macro. Cargo does this automatically. But if you, for some reason, compile manually withrustc
, you have to set that value.
Modules§
- util
- Utility functions.
Macros§
- embed
- Embeds files into the executable.
Structs§
- Asset
- An fully prepared asset.
- Assets
- Collection of assets, mapping from hashed HTTP paths to assets. Basically a virtual file system.
- Builder
- Helper to build
Assets
. - Embedded
File - A single file embedded by
embed!
. - Embedded
Glob - A glob entry embedded by
embed!
. - Embeds
- Collection of files embedded into the executable by
embed!
. - Entry
Builder - Returned by the various
Builder::add_*
functions, allowing you to configure added assets. - Modifier
Context - Passed to the modifier closure, e.g. allowing you to resolve unhashed HTTP paths to hashed ones.
Enums§
- Build
Error - Errors that might happen during
Builder::build
, when loading and resolving files. - Embedded
Entry - Corresponds to one entry in the
files
array specified inembed!
, either a single file or a glob.