Drive Bundler
drive-bundler is a JavaScript module designed for extracting bundles of files, code, and assets from Hyperdrives or Localdrives within the Holepunch peer-to-peer ecosystem. As of version 2.6.0, it provides programmatic access to traverse a 'drive' (a distributed or local file system abstraction) and gather specified entrypoints and their dependencies into a bundled output. This library is a foundational component for building serverless, local-first, and offline-capable applications that leverage Hypercore Protocol's decentralized data structures. It differs from traditional web bundlers (like Webpack or Parcel) by operating directly on a distributed file system interface, rather than a local file system, making it crucial for distributing P2P applications and their updates efficiently. While there's no explicit fixed release cadence, the broader Holepunch ecosystem is under active development, implying regular updates and maintenance for its core modules.
Common errors
-
TypeError: DriveBundler is not a constructor
cause Attempting to `new` a `DriveBundler` instance when the import method did not correctly resolve the constructor, often due to CommonJS/ESM interop issues or incorrect named vs. default import.fixIf using Node.js with ESM, use `import DriveBundler from 'drive-bundler';`. If using CommonJS (older Node.js or specifically `require`), ensure the package exports a default for `require()` or `const { DriveBundler } = require('drive-bundler');` if it's a named export. Check the package's `package.json` `exports` field for explicit guidance. -
Error: Could not read entrypoint /path/to/entry.js from drive
cause The specified entrypoint file does not exist at the given path within the `drive` instance, or the drive itself is not properly initialized or accessible.fixVerify that the `drive` instance is correct and points to the expected data. Double-check the path to the entrypoint, ensuring it is absolute from the drive's root. If it's a remote Hyperdrive, confirm that the file has been replicated and is available locally. -
ERR_MODULE_NOT_FOUND: Cannot find package 'some-dependency'
cause A dependency within the bundled source code cannot be resolved by the bundler. This might happen if `drive-bundler` doesn't automatically handle `node_modules`-like resolution or if the dependency isn't present in the drive.fixEnsure that all required dependencies, including those normally found in `node_modules`, are explicitly present within the structure of the drive being bundled, or configure `drive-bundler` (if options allow) to resolve external modules differently. For simple asset bundling, this error might indicate missing source files rather than npm packages.
Warnings
- breaking Starting with `drive-bundler` v3.0.0 (hypothetical, as a common pattern in the ecosystem), the package may transition to pure ES Module (ESM) exports only. This means CommonJS `require()` statements will no longer work directly.
- gotcha The `drive` argument passed to `new DriveBundler(drive)` must be a valid instance of a Hyperdrive-compatible interface (e.g., `hyperdrive` or `localdrive`). Passing a plain object or an uninitialized drive will lead to runtime errors or unexpected bundling behavior.
- gotcha When bundling from a remote Hyperdrive, the `drive-bundler` will only have access to data that has been replicated locally. If the desired entrypoint or its dependencies have not yet been synchronized from other peers, the bundle operation may fail to find files.
Install
-
npm install drive-bundler -
yarn add drive-bundler -
pnpm add drive-bundler
Imports
- DriveBundler
const DriveBundler = require('drive-bundler')import DriveBundler from 'drive-bundler'
- DriveBundler
import DriveBundler from 'drive-bundler' // if it becomes a named export
import { DriveBundler } from 'drive-bundler'
Quickstart
import Localdrive from 'localdrive';
import DriveBundler from 'drive-bundler';
import RAM from 'random-access-memory';
import { promises as fs } from 'fs';
import path from 'path';
async function createTempLocaldrive() {
const root = await fs.mkdtemp(path.join(process.cwd(), 'temp-drive-'));
const drive = new Localdrive(root, {
storage: (file) => new RAM()
});
// Add some dummy files to the localdrive
await fs.writeFile(path.join(root, 'index.js'), 'export * from "./lib";');
await fs.mkdir(path.join(root, 'lib'));
await fs.writeFile(path.join(root, 'lib', 'main.js'), 'export const hello = "world";');
await fs.writeFile(path.join(root, 'package.json'), JSON.stringify({
name: 'my-project',
main: 'index.js'
}));
console.log(`Created temporary localdrive at ${root}`);
return drive;
}
async function bundleExample() {
const drive = await createTempLocaldrive();
try {
const b = new DriveBundler(drive);
// Bundle a specific entrypoint, e.g., 'index.js'
const { entrypoint, resolutions, sources } = await b.bundle('/index.js');
console.log('Bundling successful!');
console.log('Entrypoint:', entrypoint);
console.log('Resolved Paths:', Object.keys(resolutions));
console.log('Source files bundled:', Object.keys(sources));
// Example: Accessing a bundled source
if (sources['/lib/main.js']) {
console.log('Content of /lib/main.js:', sources['/lib/main.js'].toString());
}
} finally {
// Clean up the temporary drive resources
// In a real app, ensure proper drive closing and resource management.
console.log('Finished bundling example.');
}
}
bundleExample().catch(console.error);