A wrapper around SWC for compiling and bundling JavaScript in Rust and Python.
Both compile and bundle take a file path and a JSMeldOptions struct:
use jsmeld::{compile, bundle, JSMeldOptions};
// Compile a single file
let output = compile(
"./src/app.ts".to_string(),
JSMeldOptions {
target: "es2020".to_string(),
minify: true,
..Default::default()
},
)?;
// Bundle an entry point
let output = bundle(
"./src/index.js".to_string(),
JSMeldOptions {
target: "es2020".to_string(),
externals: vec!["react".to_string()],
style_output: Some("./dist/index.css".to_string()),
..Default::default()
},
)?;A single unified options struct used by both compilation and bundling.
| Field | Type | Default |
|---|---|---|
target |
String |
"es6" |
minify |
bool |
false |
source_map |
bool |
true |
typescript |
bool |
true |
module |
String |
"esm" |
strict |
bool |
true |
code_split |
bool |
false |
externals |
Vec<String> |
[] |
style_output |
Option<String> |
None |
style_hooks |
HashMap<String, Vec<StyleTransformHook>> |
{} |
JSMeldOptions supports style transformation hooks keyed by file extension.
Hooks are executed in order when a matching style file is loaded during bundling.
Each key is a file extension (e.g. "css", "less") and each value is an ordered list of hook closures.
Hook type:
type StyleTransformHook = Arc<dyn Fn(&Path, &str) -> Result<String, String> + Send + Sync>;use std::sync::Arc;
use std::collections::HashMap;
use jsmeld::{Bundler, JSMeldOptions};
let mut options = JSMeldOptions::default();
options.style_hooks.insert(
"less".to_string(),
vec![Arc::new(|_path, source| {
// transform LESS -> CSS here
Ok(source.to_string())
})],
);
options.style_hooks.entry("css".to_string()).or_default().push(
Arc::new(|_path, source| {
// post-process CSS here
Ok(source.to_string())
}),
);
let bundler = Bundler::new(options);
let output = bundler.bundle("./src/index.js")?;If you initialize a Bundler with options, you can append hooks per extension:
use std::sync::Arc;
use jsmeld::{Bundler, JSMeldOptions};
let mut bundler = Bundler::new(JSMeldOptions::default());
bundler.add_style_hook("css", Arc::new(|_path, source| {
Ok(source.to_string())
}));Notes:
- Extensions are normalized to lowercase.
- Leading dots are allowed (e.g.
".css"). - Hooks run only for matching style-file extensions.
The CLI accepts an input file and output path:
cargo run -- <input> <output> [options]If installed as a binary, replace cargo run -- with jsmeld.
Compile a single file:
cargo run -- src/app.ts dist/app.js --compileBundle an entry point:
cargo run -- src/index.js dist/bundle.js --bundleBundle with minification and a target:
cargo run -- src/index.js dist/bundle.js --bundle --minify --target es2020Extract styles to dist/bundle.css (default sidecar path):
cargo run -- src/index.js dist/bundle.js --bundle --extract-stylesExtract styles to a custom path:
cargo run -- src/index.js dist/bundle.js --bundle --style-output dist/styles/app.cssNotes:
--style-outputimplies style extraction automatically.- If neither
--bundlenor--compileis provided, bundling is used.
$ jsmeld --help
A Rust wrapper around SWC for JavaScript/TypeScript compilation and bundling
Usage: jsmeld [OPTIONS] <INPUT> <OUTPUT>
Arguments:
<INPUT> Input file (entry point)
<OUTPUT> Output path
Options:
-b, --bundle Bundle and compile the input file
-c, --compile Only compile the input file
--target <TARGET> [default: es6]
-m, --minify Enable minification of output
--extract-styles Extract bundled styles into a separate CSS file, defaulting to <output>.css
--style-output <STYLE_OUTPUT> Path to write extracted bundled styles. Implies --extract-styles
-h, --help Print help
-V, --version Print versionInstall the cross-platform CLI package:
npm install --save-dev jsmeldRun it via npx:
npx jsmeld src/index.js dist/bundle.js --bundle --minifyOr use it from npm scripts:
{
"scripts": {
"build:js": "jsmeld src/index.js dist/bundle.js --bundle"
}
}The top-level jsmeld package uses optionalDependencies to install the
matching prebuilt binary package for your platform.
Published binary package names:
jsmeld-linux-x64-gnujsmeld-linux-arm64-gnujsmeld-linux-x64-musljsmeld-linux-arm64-musljsmeld-darwin-x64jsmeld-darwin-arm64jsmeld-win32-x64-msvcjsmeld-win32-arm64-msvc
The Python package exposes two top-level functions. Both accept an optional
options dictionary with the same keys as JSMeldOptions above.
import jsmeld
# Compile a single file (all options are optional)
output: str = jsmeld.compile("src/app.ts", {
"target": "es2020",
"minify": True,
})
# Bundle an entry point
output: str = jsmeld.bundle("src/index.js", {
"target": "es2020",
"externals": ["react"],
})style_hooks can be passed as a dictionary mapping file extensions to lists
of callables (path: str, source: str) -> str:
def add_banner(path: str, source: str) -> str:
return f"/* bundled by jsmeld */\n{source}"
output = jsmeld.bundle("src/index.js", {
"style_hooks": {
"css": [add_banner],
},
"style_output": "dist/index.css",
})