Sarcina Web Project Bundler
Sarcina is a fully-automatic, zero-configuration web project bundler designed to prepare vanilla, non-framework web projects for production. It offers a simpler, faster alternative to complex bundlers like Webpack, specifically targeting projects that do not require constant re-building during development. Instead, Sarcina is intended for a single run prior to deployment. The current stable version is 1.7.6. Sarcina processes markup files, identifies CSS and JavaScript assets, creates optimized bundles, and re-inserts links to these new bundles. During this process, it minifies HTML, minifies and autoprefixes CSS, and minifies and transpiles JavaScript. This results in a distribution folder with fewer, smaller, and less complex files, significantly improving browser load times and user experience. Its primary differentiator is its "works-out-of-the-box" philosophy, eliminating the need for extensive configuration often associated with other bundlers.
Common errors
-
sarcina: command not found
cause The Sarcina CLI tool is not globally installed or not found in the system's PATH, or `npx` cannot locate it.fixIf installed locally, run with `npx sarcina <input-dir> <output-dir>`. If you wish to use it globally, install with `npm install -g sarcina` (though `npx` is generally preferred for local installations). -
Error: Input directory not found: <path/to/src>
cause The specified input directory either does not exist or the path provided is incorrect.fixVerify the input directory path is correct and exists relative to where you're running Sarcina (either via CLI or programmatically). Ensure there are no typos and the directory structure matches expectations. -
TypeError: sarcina is not a function
cause When using the programmatic API, the imported 'sarcina' might not be directly callable as a function, or it might be a module object requiring a specific property to be called (e.g., `sarcina.bundle()`).fixDouble-check the package's actual programmatic export. If `require('sarcina')` returns an object, try accessing a property like `sarcina.run()` or `sarcina.bundle()`. If using ESM `import`, ensure it's a default export, or try `import * as sarcina from 'sarcina';` and then `sarcina.default()` or `sarcina.run()`.
Warnings
- gotcha Sarcina is explicitly designed for 'regular vanilla non-framework web projects'. It may not work as expected or provide optimal results for projects built with frameworks like React, Vue, or Angular, which often require specialized build configurations and tools.
- gotcha Sarcina is 'intended to be run only when bundling a project for deployment, not constantly during development'. Its design prioritizes simplicity and final output optimization over rapid incremental builds or hot module reloading features typically found in development-focused bundlers.
- gotcha As a 'zero-configuration' tool, Sarcina handles bundling and optimization with predefined defaults. This simplicity means less explicit control over advanced aspects like custom Babel presets, PostCSS plugins, or specific asset handling rules, which might be necessary for highly customized projects.
- breaking The exact programmatic API (function name, arguments, return value) for 'sarcina' is not explicitly documented in the provided README. The quickstart assumes a default export function that takes an object with 'input' and 'output' paths. Changes to this inferred API in future major versions could break existing integrations.
Install
-
npm install sarcina -
yarn add sarcina -
pnpm add sarcina
Imports
- bundleSarcina
import bundleSarcina from 'sarcina';
const bundleSarcina = require('sarcina'); - bundleSarcina
const bundleSarcina = require('sarcina');import bundleSarcina from 'sarcina';
- Sarcina CLI
import { sarcina } from 'sarcina'; // For CLI executionnpx sarcina <input-dir> <output-dir>
Quickstart
import sarcina from 'sarcina';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { mkdir, writeFile, rm } from 'fs/promises';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
async function setupAndBundle() {
const srcDir = join(__dirname, 'src');
const distDir = join(__dirname, 'dist');
const cssDir = join(srcDir, 'css');
const jsDir = join(srcDir, 'js');
// Clean up previous runs and set up source directories
await rm(distDir, { recursive: true, force: true });
await rm(srcDir, { recursive: true, force: true });
await mkdir(cssDir, { recursive: true });
await mkdir(jsDir, { recursive: true });
// Create sample HTML, CSS, and JS files
await writeFile(join(srcDir, 'index.html'), `
<!DOCTYPE html>
<html>
<head>
<title>Sarcina Demo</title>
<link rel="stylesheet" href="css/base.css">
</head>
<body>
<h1>Hello Sarcina!</h1>
<script src="js/main.js"></script>
</body>
</html>
`);
await writeFile(join(cssDir, 'base.css'), `
body {\n font-family: sans-serif;\n background-color: #f0f0f0;\n color: #333;\n }\n h1 {\n text-align: center;\n color: #007bff;\n }
`);
await writeFile(join(jsDir, 'main.js'), `
console.log("Sarcina has bundled this page!");
document.addEventListener('DOMContentLoaded', () => {
const heading = document.querySelector('h1');
if (heading) {
heading.textContent += ' (Bundled!)';
}
});
`);
console.log('Sample project created in ./src. Running Sarcina...');
try {
// Programmatic API: Assuming a default export function that takes an options object.
// The `input` and `output` properties are inferred from common bundler patterns
// and the package's description of processing 'markup files in a folder'.
await sarcina({
input: srcDir,
output: distDir
});
console.log(`Bundling complete! Check '${distDir}' for results.`);
} catch (error) {
console.error('Sarcina bundling failed:', error);
}
}
setupAndBundle();