Architecture Overview
Package Structure
Shevky is organized as a multi-package system:
| Package | Role |
|---|---|
@shevky/base | Shared utilities: config, i18n, io, log, format, exec, plugin contract |
@shevky/core | CLI, build pipeline, engines, registries, content model |
@shevky/plugin-* | Optional build extensions loaded from project config |
Dependency direction: plugins depend on base; core depends on base; core dynamically imports plugins at build time.
Runtime Entry Points
- CLI binary:
core/shevky.js(hashbang Node.js script) - Dispatcher:
core/scripts/main.js(routes--build,--dev,--init, etc.) - Build pipeline:
core/scripts/build.js(execute()function)
Build Lifecycle
The build pipeline in core/scripts/build.js executes these stages:
- Clear and recreate
dist/. - Execute
dist:cleanplugin hook. - Copy static assets from
src/assets/. - Execute
assets:copyplugin hook. - Load Markdown content from
src/content/. - Execute
content:loadplugin hook. - Build menus and content collections (tags, categories, series).
- Execute
content:readyplugin hook. - Render pages (per-page
page:metahook, then Mustache + Markdown -> HTML). - Flush pages to
dist/. - Apply output aliases.
Internal Components
Engines
| Engine | File | Purpose |
|---|---|---|
| PluginEngine | core/engines/pluginEngine.js | Hook execution with per-hook context |
| RenderEngine | core/engines/renderEngine.js | Mustache + Markdown rendering, HTML transforms |
| MenuEngine | core/engines/menuEngine.js | Navigation menu building |
| MetaEngine | core/engines/metaEngine.js | URL resolution, site metadata, alternate links |
Registries
| Registry | File | Purpose |
|---|---|---|
| PluginRegistry | core/registries/pluginRegistry.js | Dynamic import and caching of plugins |
| ContentRegistry | core/registries/contentRegistry.js | Content loading, deduplication, collection building |
| TemplateRegistry | core/registries/templateRegistry.js | Mustache template loading by type |
| PageRegistry | core/registries/pageRegistry.js | Buffered page output |
Data Flow
- Markdown files ->
ContentRegistry->ContentFileobjects - Templates ->
TemplateRegistry-> Mustache strings - Content + templates ->
RenderEngine-> HTML strings - HTML ->
PageRegistry->dist/files
Plugins can inject content (content:load), process content (content:ready), and enrich page metadata (page:meta).
Extension Points
- Plugin hooks:
dist:clean,assets:copy,content:load,content:ready,page:meta - Custom collections via
content.collectionsconfig - Output aliases via
build.outputAliases - Content root directories via
build.contentRootDirectories