@entryscape/blocks-bundler
v0.3.0
Published
Convention-based Rollup plugin + CLI that bundles an EntryScape Blocks source tree into a single window.__entryscape_config script.
Downloads
227
Keywords
Readme
@entryscape/blocks-bundler
Convention-based Rollup plugin + CLI that bundles an EntryScape Blocks
source tree into a single IIFE script which assigns to
window.__entryscape_config.
Quickstart
From an empty directory on a fresh machine — no install needed,
npx fetches the package on demand:
mkdir my-blocks && cd my-blocks
npx @entryscape/blocks-bundler create(Equivalent on pnpm: pnpm dlx @entryscape/blocks-bundler create.)
If the package is already a devDependency in the project, use the locally installed binary instead:
pnpm add -D @entryscape/blocks-bundler
pnpm exec blocks-bundler createThis bootstraps a full project: the source layout (src/config.js,
src/collections.js, src/style.css, src/nls.js,
src/blocks/example.js, plus a src/README.md orientation note), a
top-level README.md and .gitignore, a package.json with dev /
build / serve scripts, and a minimal demo/index.html that loads
the built bundle alongside the EntryScape Blocks CDN runtime. Existing
files are never overwritten. Pass --name <pkg> to set the
package.json name (defaults to the cwd basename). Pass --src <dir>
to put the whole source tree under a directory other than src/;
per-file flags (--config, --collections, --style, --nls,
--blocks-dir) further override individual paths.
After scaffolding:
pnpm install
pnpm start # runs dev + serve together; demo at http://localhost:5173/demo/(pnpm dev and pnpm serve are also available individually.)
Or lay out your source like this by hand (all roots are optional):
src/
config.js export default { namespaces, bundles, ... }
collections.js export default [ ...collections ]
style.css (read as a string and attached as `style:`)
nls.js export default { en: { ... }, sv: { ... } }
blocks/
myBlock.js export default { extends: "template", template: ... }
other/
another.js export default { ... }
scripts.js (helper module; not registered as a block)In each block file omit the block: property — the bundler injects it
from the filename. extends: can be a built-in name ("template",
"searchList", ...) or an imported block module:
import myBlock from '../myBlock.js';
export default { extends: myBlock, template: `...` };The build resolves the imported reference to a string at compile time, so
the final bundle has extends: "myBlock" directly — no runtime helpers.
Building
Both paths produce the same dist/blocks.js (readable IIFE) and
dist/blocks.min.js (terser-minified). Pick by use case.
One-off build with npx (no install)
If all you have is a source tree and you just want to (re)build it,
npx works without any package.json or node_modules:
npx @entryscape/blocks-bundler # bundle src/ into dist/
npx @entryscape/blocks-bundler --watch # rebuild on changes
npx @entryscape/[email protected] # pin a specific versionEquivalent on pnpm: pnpm dlx @entryscape/blocks-bundler.
Day-to-day development with a devDependency
For inner-loop dev (frequent builds, watch mode, parallel serve) prefer a local install — faster startup, lockfile-pinned transitives, and works with editor/IDE script pickers:
pnpm add -D @entryscape/blocks-bundlerThen in package.json:
{
"scripts": {
"build": "blocks-bundler",
"build:watch": "blocks-bundler --watch"
}
}(The create subcommand scaffolds this layout for you, along with
dev / serve / start scripts and the matching devDeps.)
When to use which
| Use case | Recommended path |
|---------------------------------------------------|-------------------------------------------------|
| First-time bootstrap of a project | npx … create |
| Recovering source from a built bundle | npx … disassemble |
| One-off rebuild without committing to a devDep | npx @entryscape/blocks-bundler |
| CI sanity check / version-pinned reproducible run | npx @entryscape/blocks-bundler@<version> |
| Day-to-day dev (watch, hot-reload, concurrent serve) | devDep + pnpm dev / pnpm start |
| CI build in the project's own repo | devDep (lockfile-pinned) + pnpm build |
| Editor / IDE-driven build | devDep (resolved via node_modules/.bin/) |
Load dist/blocks.js from your HTML alongside the EntryScape Blocks
runtime — see demo/index.html (scaffolded by create) for the
minimal pattern.
CLI options
blocks-bundler [command] [options]
Commands:
(default) Bundle the source tree.
create Scaffold the default source structure.
disassemble [path] Inverse of bundle: turn a built blocks.js back into
editable source (default path: dist/blocks.js).
Options:
-w, --watch Rebuild on source changes.
--no-minify Skip the minified bundle.
--outfile <path> Readable bundle output (default: dist/blocks.js).
--min-outfile <p> Minified bundle output (default: <outfile>.min.js).
--banner <text> Banner comment for both bundles (default: empty).
--src <dir> Source root (default: src). Sets the parent for
config/collections/style/nls/blocks unless those
are overridden by their per-file flags below.
--blocks-dir <d> Blocks source directory (default: <src>/blocks).
--config <file> Config file (default: <src>/config.js).
--collections <f> Collections file (default: <src>/collections.js).
--style <file> Style file (default: <src>/style.css).
--nls <file> NLS (i18n strings) file (default: <src>/nls.js).
-h, --help Show this help.Conventions
| Path | Role |
|-------------------------------------|-----------------------------------------------------|
| src/config.js | export default { ... } spread into the bundle |
| src/collections.js | export default [ ... ] attached as collections: |
| src/style.css | Read as a string, attached as style: |
| src/nls.js | export default { ... } attached as nls: (i18n) |
| src/blocks/<name>.js | One block; name = filename without .js |
| src/blocks/<group>/<name>.js | Subdirectories are organization only, no namespacing |
| src/blocks/scripts.js | Shared helpers; not registered as a block |
| src/blocks/**/scripts/*.js | Entire scripts directories are skipped |
Plugin API
If you need a custom rollup.config.js, import the plugin directly:
import blocksBundler from '@entryscape/blocks-bundler';
export default {
input: 'virtual:blocks-bundler-entry',
plugins: [blocksBundler({ /* override defaults if needed */ })],
output: { file: 'dist/blocks.js', format: 'iife' },
};Output shape
window.__entryscape_config = [].concat(window.__entryscape_config)
.filter(Boolean)
.concat([{ ...config, style: "...", collections, nls, blocks: [...] }]);Blocks are toposorted so each block's extends target appears before it.
Cyclic extends chains fail the build with a clear error.
Disassembling a built bundle
blocks-bundler disassemble [path] is the inverse of the build: it
evaluates an existing bundle (default dist/blocks.js; the minified
bundle also works) in a Node vm sandbox, captures the resulting
window.__entryscape_config, and writes the pieces back out as
src/config.js, src/collections.js, src/style.css, src/nls.js,
and one src/blocks/<name>.js per block. When a block's extends: value
matches another local block in the same bundle, an import statement
is reconstructed so the rebuild preserves the topological order.
blocks-bundler disassemble # default: dist/blocks.js
blocks-bundler disassemble path/to/bundle.js
blocks-bundler disassemble bundle.js --force # overwrite existingSkips existing files by default (use --force to overwrite). Honours
the same --src plus per-file flags
(--config/--collections/--style/--nls/--blocks-dir) as
create, so disassemble --src sources puts every recovered file
under sources/ instead of src/. The output is "flat string-extends" form for any extends:
values that don't match another local block (e.g. built-in names like
"template").
disassemble writes only the source tree (src/*); it does not
scaffold package.json, the demo page, or other project-shell files.
That keeps each subcommand single-purpose. To bootstrap a fresh
project from just a bundle, combine the two — both subcommands are
idempotent and compose cleanly:
# Order A: shell first, then real data
mkdir my-project && cd my-project
npx @entryscape/blocks-bundler create
npx @entryscape/blocks-bundler disassemble path/to/bundle.js --force
# Order B: real data first, then shell
mkdir my-project && cd my-project
npx @entryscape/blocks-bundler disassemble path/to/bundle.js
npx @entryscape/blocks-bundler createIn Order A, --force lets the real bundle data overwrite the example
src/config.js / src/collections.js / src/style.css that create
scaffolded. In Order B, create skips the already-populated source
files and only fills in the project shell (plus
src/blocks/example.js, which sits harmlessly alongside the real
blocks — delete it if it's noise).
