autodetect js module type - only bundle esm (#5515)
* wip: autodetect esm * finish fixes * thread minify through * add sweetalert2 * Fix default bundle types * ts-ignore * small nits * small more nits * shrink flamegraph
This commit is contained in:
1 parent
2f40780ce0
commit
218bb9d56d
24 files changed
+1598
-616
No files matched your search
@@ -22,6 +22,7 @@ pub struct JsAssetOptions {
|
||||
minify: bool,
|
||||
preload: bool,
|
||||
static_head: bool,
|
||||
module: bool,
|
||||
}
|
||||
|
||||
impl Default for JsAssetOptions {
|
||||
@@ -42,6 +43,7 @@ impl JsAssetOptions {
|
||||
preload: false,
|
||||
minify: true,
|
||||
static_head: false,
|
||||
module: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +61,11 @@ impl JsAssetOptions {
|
||||
pub const fn minified(&self) -> bool {
|
||||
self.minify
|
||||
}
|
||||
|
||||
/// Check whether the asset is declared as an ES module
|
||||
pub const fn is_module(&self) -> bool {
|
||||
self.module
|
||||
}
|
||||
}
|
||||
|
||||
impl AssetOptions {
|
||||
@@ -116,6 +123,27 @@ impl AssetOptionsBuilder<JsAssetOptions> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Mark the asset as an ES module (default: false)
|
||||
///
|
||||
/// When true, the script tag emitted via `with_static_head(true)` is rendered as
|
||||
/// `<script type="module" ...>`, and the file is delivered with its module syntax
|
||||
/// (`import`/`export`) preserved so the browser can resolve imports natively at
|
||||
/// runtime. The default treats the file as a classic script: `<script>` is emitted
|
||||
/// without `type="module"`, and minification preserves classic-script semantics.
|
||||
///
|
||||
/// Note: this does not perform build-time bundling. If you need imports resolved
|
||||
/// into a single file, pre-bundle with your tool of choice and ship the result.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use manganis::{asset, Asset, AssetOptions};
|
||||
/// const _: Asset = asset!("/assets/script.js", AssetOptions::js().with_module(true));
|
||||
/// ```
|
||||
#[allow(unused)]
|
||||
pub const fn with_module(mut self, module: bool) -> Self {
|
||||
self.variant.module = module;
|
||||
self
|
||||
}
|
||||
|
||||
/// Convert the builder into asset options with the given variant
|
||||
pub const fn into_asset_options(self) -> AssetOptions {
|
||||
AssetOptions {
|
||||
|
||||
@@ -38,6 +38,48 @@ const REQUIRED: Asset = asset!("/assets/style.css");
|
||||
const OPTIONAL: Option<Asset> = option_asset!("/assets/missing.css");
|
||||
```
|
||||
|
||||
## JavaScript assets
|
||||
|
||||
The CLI auto-detects whether each `.js` asset is an ES module (top-level
|
||||
`import`/`export` or `import.meta`) or a classic script and processes it
|
||||
accordingly.
|
||||
|
||||
- **`with_minify(true)` (default)**: the file is minified in place. Classic
|
||||
scripts are minified verbatim with their format preserved (no IIFE
|
||||
re-wrapping). ES modules are minified and bundled — local relative imports
|
||||
are inlined into a single ESM file, while `http://` / `https://` imports
|
||||
remain as external `import` statements for the browser to resolve at runtime.
|
||||
- **`with_minify(false)`**: the file is copied byte-for-byte. Use this when
|
||||
shipping pre-built third-party libraries you do not want re-processed.
|
||||
- **`with_static_head(true)`**: appends a `<script>` tag to the document head
|
||||
pointing at the asset. The CLI emits `<script type="module" ...>` when the
|
||||
file is detected (or declared) as an ES module, and a classic `<script>`
|
||||
otherwise.
|
||||
- **`with_preload(true)`**: emits a `<link rel="preload" as="script">` for the asset.
|
||||
- **`with_module(true)`**: forces the file to be treated as an ES module even
|
||||
when auto-detection would say otherwise. Useful when you author a
|
||||
side-effect-only module without top-level `import`/`export` declarations.
|
||||
Files named `*.mjs` are always treated as modules; files named `*.cjs` are
|
||||
always treated as classic.
|
||||
|
||||
```rust
|
||||
use manganis::{asset, Asset, AssetOptions};
|
||||
|
||||
// Vendored UMD library: copy verbatim, emitted as a classic <script>.
|
||||
const SWEETALERT: Asset = asset!(
|
||||
"/assets/sweetalert2.all.min.js",
|
||||
AssetOptions::js().with_minify(false).with_static_head(true)
|
||||
);
|
||||
|
||||
// Authored ES module with local imports: auto-detected from the top-level
|
||||
// `import`/`export`, bundled and minified into a single ESM file, emitted as
|
||||
// `<script type="module">`.
|
||||
const APP: Asset = asset!(
|
||||
"/assets/app.js",
|
||||
AssetOptions::js().with_static_head(true)
|
||||
);
|
||||
```
|
||||
|
||||
## Native FFI Bindings
|
||||
|
||||
Manganis provides the `#[ffi]` attribute macro for generating direct FFI bindings between Rust and native platforms (Swift/Kotlin). See the `geolocation-native-plugin` example for usage.
|
||||
Reference in new issue
Block a user