Skip to main content

web_modules/
lib.rs

1//! Pure-Rust, buildless toolchain for **ES modules and Web Components**. No Node, no
2//! bundler.
3//!
4//! It vendors each npm package into a `web_modules/` tree with an import map
5//! (Snowpack-style) and serves them through an on-the-fly transform dev server
6//! (like `@web/dev-server`), built entirely in Rust on
7//! [`npm-utils`](https://docs.rs/npm-utils), [oxc] and [`grass`](https://docs.rs/grass).
8//! It emits native ES modules and leaves bare-specifier resolution to the browser's
9//! import map; it is **not** a bundler.
10//!
11//! # Modules
12//!
13//! **Core** (always on):
14//! - [`vendor`]: resolve, download and extract npm packages into a `web_modules/`
15//!   tree (via `npm-utils`) and accumulate the import map.
16//! - [`importmap`]: a deterministic import-map composer (build, merge fragments,
17//!   render the `<script type="importmap">`).
18//!
19//! **Processors** (applied to your source and assets):
20//! - [`typescript`]: TypeScript and modern JS → browser JS via oxc, with legacy
21//!   decorators configured for Lit.
22//! - [`scss`]: SCSS → CSS via grass.
23//! - [`minify`]: JS minification via oxc_minifier.
24//! - [`dts`]: `.d.ts` emission. [`i18n`]: XLIFF merge. [`icons`]: favicons from a PNG.
25//!
26//! **Toolchain** (build and serve):
27//! - [`build`]: vendor, transform and render into an output dir.
28//! - `bundle`: fold an app plus its `node_modules/` (CommonJS and all) into one
29//!   browser ESM file via rolldown, for React-class packages that ship only CommonJS.
30//! - [`templates`]: HTML templating (importmap injection).
31//! - [`server`] / [`dev`]: serve embedded assets, or compile on the fly with
32//!   file-watching and live-reload.
33//!
34//! [oxc]: https://oxc.rs
35
36mod error;
37pub use error::{Error, Result};
38
39// Always-on core, grouped under `core/`: vendoring, import maps, the mount model,
40// TypeScript `tsconfig` generation and static-file copying. Re-exported here so callers
41// use `web_modules::vendor` etc. — the `core` module itself is private.
42mod core;
43pub use core::mount::Mount;
44pub use core::symlinks::SymlinkMode;
45pub use core::{importmap, mount, reject, static_files, symlinks, tsconfig, vendor};
46// Crate-internal for now: the graph's overwrite/ownership semantics are still
47// settling, so it is not part of the public API yet.
48pub(crate) use core::module_graph;
49// Crate-internal: resolving `npm://` symlink targets into node_modules, used by the
50// build's preflight walk/emit and the dev/static server.
51pub(crate) use core::npm_link;
52
53/// Feature-gated source/asset processors, each re-exported at the crate root (e.g.
54/// `web_modules::scss`). Grouped to separate "what we apply to your source" from the
55/// vendor/import-map core and the build/serve toolchain.
56mod processors;
57
58/// The decorator-lowering mode (`web_modules::Decorators`), always available so the build
59/// [`Processors`](build::Processors) set can carry it regardless of which processors are compiled.
60pub use processors::Decorators;
61
62#[cfg(feature = "dts")]
63pub use processors::dts;
64#[cfg(feature = "i18n")]
65pub use processors::i18n;
66#[cfg(feature = "icons")]
67pub use processors::icons;
68#[cfg(feature = "minify")]
69pub use processors::minify;
70#[cfg(feature = "scss")]
71pub use processors::scss;
72#[cfg(feature = "typescript")]
73pub use processors::typescript;
74
75/// CLI scaffolding (the `feature_args!` macro + the `NoConfig` placeholder) that lets
76/// each compiler processor carry its own clap config. Compiled only with `cli`, so the
77/// library path stays clap-free.
78#[cfg(feature = "cli")]
79pub mod cli_config;
80
81/// Shared fluent-builder methods (the `source_builder_methods!` macro) stamped onto the
82/// [`Build`] and [`Dev`] builders, behind the `builder` feature.
83#[cfg(feature = "builder")]
84mod builder_shared;
85
86// Build-time toolchain, grouped under `build/`: the `build` pipeline plus the emit helpers
87// `bundle` / `compress` / `templates`, each re-exported at its historical crate root path. The
88// pipeline depends only on the always-on vendor/import-map core — each source processor (TypeScript,
89// SCSS, Tera, gzip) applies only when its feature is on — so the module is always available.
90pub mod build;
91
92/// The fluent build builder (feature `builder`), at the crate root alongside [`Frontend`].
93#[cfg(feature = "builder")]
94pub use build::Build;
95
96#[cfg(feature = "bundle")]
97pub use build::bundle;
98#[cfg(feature = "compress")]
99pub use build::compress;
100#[cfg(feature = "tera")]
101pub use build::templates;
102
103/// Re-export of [`npm_utils`] as `web_modules::npm`, the vendoring + transitive `node_modules`
104/// install engine, behind the `npm` feature. Lets consumers reach the npm API without a separate
105/// `npm-utils` dependency: install a tree with `web_modules::npm::install::node_modules`, then
106/// bundle it via `web_modules::bundle` (enable the `bundle` feature too).
107#[cfg(feature = "npm")]
108pub use npm_utils as npm;
109
110// Runtime serving, grouped under `serve/`: the axum `Frontend` router and the dev server,
111// over a shared (private) `serving` containment boundary. Re-exported at historical paths.
112mod serve;
113
114#[cfg(feature = "dev")]
115pub use serve::dev;
116
117/// The fluent dev-server builder (feature `builder`), at the crate root alongside [`Frontend`].
118#[cfg(all(feature = "builder", feature = "dev"))]
119pub use serve::dev::Dev;
120
121#[cfg(feature = "axum")]
122pub use serve::server;
123#[cfg(feature = "axum")]
124pub use serve::server::{serve, Frontend};
125
126/// Re-export of the `include_dir` crate for the [`include_dir::Dir`] type. Use the
127/// `include_dir` crate **directly** for the `include_dir!` macro; it emits
128/// `include_dir::`-qualified paths that don't resolve through a re-export.
129#[cfg(feature = "axum")]
130pub use include_dir;