Binary Compilation
Lockness provides a powerful, declarative way to bundle your entire application
into a single, standalone executable using deno compile. This process is
orchestrated by the Lockness CLI, which handles pre-compilation tasks, asset
management, and framework invariants.
How it works
The compilation process is controlled through the @Kernel decorator in your
app/kernel.tsx. When you run deno task compile (which calls
deno task cli compile), the Lockness CLI performs the following steps in
order:
- Preparation: Ensures the output directory (default:
_dist) exists. - Routes Generation: Automatically scans your controllers and generates
app/routes.ts. This ensures all routes are statically available for the binary, as runtime directory scanning is not possible in a compiled executable. - User Scripts: Executes any custom scripts or commands defined in your
kernel's
compile.scriptslist (e.g., CSS building, documentation syncing). - Asset Management: Copies declared files and folders to the distribution directory alongside the binary.
- Compilation: Executes the native
deno compilecommand with your configured flags.
Configuration
Lockness encourages externalizing your compilation settings in
config/compile.ts to keep your kernel clean.
1. Define the configuration
Create or edit config/compile.ts:
// config/compile.ts
import type { CompileConfig } from '@lockness/core'
export const compileConfig: CompileConfig = {
output: '_dist/lockness', // Name and path of the binary
main: 'main.ts', // Entry point of your app
flags: ['-A', '--env-file=.env.production.local'], // Deno compile flags
assets: [ // Files/folders to copy to _dist
'public',
{ source: 'docs', target: 'docs', include: /\.md$/ }, // Only copy .md files
{ source: 'packages/ui/components', target: 'packages/ui/components' },
],
scripts: [ // Commands to run before compilation
'deno task css:build',
'scripts/prepare_docs.ts',
],
}
2. Register in the Kernel
Then, reference it in your app/kernel.tsx:
// app/kernel.tsx
import { config } from '../config/mod.ts'
@Kernel({
// ... other config
compile: config.compile,
})
export class AppKernel {}
Why externalize configuration?
Lockness follows the Dependency Inversion Principle. By moving configuration
out of the app/kernel.tsx, you ensure that:
- The Kernel remains a declarative overview of the application components.
- Configuration is easily testable and discoverable in the
config/directory. - Application-specific tasks (like building search registries or syncing project docs) are clearly separated from framework logic.
Runtime Behavior
When running as a binary, Lockness detects it's in a production environment and:
- Disables runtime controller discovery.
- Uses the generated
app/routes.tsregistry for routing. - Points to the orchestrated
assetsrelative to the binary location.
Deployment
To deploy your application, you only need to copy the contents of your output
directory (e.g., _dist/) to your server. The binary is self-contained and only
requires the Deno runtime environment if dynamic scripts are executed at
runtime.