08 · Bundler
Two modules (index.js imports formatTime from utils.js) bundled into a
single file that runs on its own under 3va or in a browser.
Source: examples/08-bundler
Build and run
cd examples/08-bundler
3va bundle src/index.js -o dist/bundle.js --minify✓ Bundle created: dist/bundle.js
Run: 3va run dist/bundle.js --allow-net=<trusted-hosts>3va run dist/bundle.js{"greeting":"Hello, 3va!","timestamp":"17:19:20","generatedBy":"3va bundler"}The hint about --allow-net is generic. This bundle needs no permissions.
How it works
The bundler follows the real import graph (project files and
node_modules, ESM and CommonJS), converts every module to a CommonJS-style
function, and wraps them in one IIFE with a tiny module registry:
(function() {
var __modules = {
"./src/utils.js": function(module, exports, require) {
function formatTime(date) { … }
module.exports.formatTime = formatTime;
},
"./src/index.js": function(module, exports, require) {
var { formatTime } = require("./src/utils.js");
…
},
};
…
})();.json imports are inlined, and .css imports become a <style> tag
injected at runtime in the browser.
The entry decides where it’s running:
if (typeof window === "undefined") {
console.log(createMessage("3va")); // 3va run
} else {
globalThis.createMessage = createMessage; // browser <script>
}public/index.html loads /bundle.js with a classic <script> and then
calls createMessage("browser").
Things to keep in mind
-
Module IDs are relative to the directory you run
3va bundlefrom. From the example folder they are./src/utils.js. Fromsrc/they would be./utils.js. No absolute paths from your machine end up in the bundle. -
--minifyremoves whitespace but doesn’t rename. In this example the output only went from 1453 to 1266 bytes. Function and variable names were kept as-is. Use a dedicated minifier afterwards if size is critical. -
--source-mapand--splitaren’t supported yet. They appear in3va bundle --help, but using either one stops the command with exit code 1 and writes nothing:Error: --source-map is not supported yet by `3va bundle`; run it without that flag -
The output is a classic script, not an ES module. Exports aren’t visible to the page. Expose what the page needs on
globalThis, as the example does. -
A bundle runs with the same permissions as any script. Bundling doesn’t grant anything. If the code reads files or opens sockets,
3va run dist/bundle.jsstill needs the matching--allow-*flags. One upside: since everything is inlined, you no longer need--allow-readfor your own modules ornode_modules. -
There’s no watch mode on
3va bundle. For automatic rebuilds, run3va dev, which also writesdist/bundle.js.