farm-plugin-tricks
v0.2.0
Published
Farm plugin providing compile-time transforms: compileTime(), @comptime, @treeshake, staticify(), autoStatic()
Downloads
430
Maintainers
Readme
farm-plugin-tricks
FarmFE plugin for compile-time source tricks.
Install
npm install farm-plugin-tricksDependencies: This plugin uses core-ast-ts internally for AST parsing and caching. It is installed automatically — no extra setup needed.
Supported Surface
compileTime(() => expr)— evaluate a getter at build time, inline the result@comptimedecorator — evaluate a decorated function at build time, replace call sites with the literal, remove the definition@treeshakeJSDoc — annotate functions as statically analyzable for tree-shakingstaticify(Component, { prop: value })— create a specialized component with static propsautoStatic(Component)— automatically specialize JSX elements with literal props
compileTime()
Evaluate a getter at build time and inline the result as a literal.
const API_URL = compileTime(() => process.env.API_URL ?? '/api')
// → const API_URL = /* @compileTime */ "/api"Results are shared across calls — later compileTime() calls can reference earlier ones:
const BASE = compileTime(() => '/api')
const FULL = compileTime(() => BASE + '/v1')
// → const BASE = /* @compileTime */ "/api"
// → const FULL = /* @compileTime */ "/api/v1"@comptime Decorator
Mark a function for compile-time evaluation. The function body must be a single return statement with an evaluable expression (literals, arithmetic, booleans, null). After evaluation, all call sites are replaced with the literal result and the function definition is removed.
@comptime
function apiUrl() { return "https://api.example.com" }
fetch(apiUrl())
// → fetch("https://api.example.com")@comptime
function maxItems() { return 42 }
const count = maxItems()
// → const count = 42@comptime
function total() { return 10 + 20 }
const x = total()
// → const x = 30Restrictions
- The function body must contain exactly one
returnstatement. - Only simple expressions are supported: string/number/boolean/null literals and basic arithmetic (
+,-,*,/). - No closures, no side effects, no DOM or runtime API access.
@treeshake JSDoc
Annotate functions as statically analyzable for tree-shaking. Injects /*#__PURE__*/ markers.
/** @treeshake */
export function helper() { ... }
// → export /*#__PURE__*/ function helper() { ... }staticify(Component, staticProps)
Create a specialized version of a component with static props baked in. Only dynamic props remain as parameters.
const Card = staticify(Card, { variant: 'primary', size: 'md' })
// Becomes:
function StaticComponent(overrideProps) {
return Card(Object.assign({}, { variant: 'primary', size: 'md' }, overrideProps))
}autoStatic(Component)
Automatically specialize JSX elements that use literal props. For each unique combination of literal prop values, a specialized component is generated.
const Card = autoStatic(Card)
<Card variant="primary" size="md" title="Hello" />
<Card variant="secondary" count={dynamic} />
// → Generates Card_variant_primary_size_md with static props baked in
// → Dynamic props (count) remain as function parametersHow it works
- Finds
autoStatic()calls and tracks the component name - Scans JSX usages of that component for literal vs dynamic props
- Generates specialized component declarations for each unique literal prop combination
- Replaces JSX tag names with the specialized version and removes literal prop attributes
How AST parsing works
This plugin uses core-ast-ts for AST parsing and caching via its singleton API:
// Internal usage (you don't need to write this)
import { get, invalidate, visitWithAncestors } from 'core-ast-ts'
const { ast } = get('app.tsx', source) // parse once, cache
invalidate('app.tsx') // on HMR updateSince this plugin only handles .js/.ts/.jsx/.tsx files, it uses the legacy singleton cache API (no format plugins needed). For multi-format support (Vue, Svelte, Astro), see the coreAst() plugin system.
Backend Modes
This package supports:
backend: 'auto'backend: 'native'backend: 'js'
auto prefers the Rust .farm binary and falls back to the JS backend when the native binary is unavailable.
The workspace verifies that contract through pnpm run test:farm-plugin-tricks:pack-js, which installs the packed package without any native binary package and exercises the JS fallback path.
Current Fallback Model
The JS fallback is supported, not accidental.
That means:
compileTime()still evaluates supported literal/static expressions@comptimestill evaluates decorated functions and inlines results@treeshakestill injects the purity marker path used by this packagestaticify()andautoStatic()still specialize components
Native mode remains the preferred path when available.
HMR
When source files change, the core-ast-ts cache is invalidated per-file and the virtual runtime module is refreshed. Each file is parsed only once between changes.
Example
import farmPluginTricks from 'farm-plugin-tricks'
export default {
plugins: [
farmPluginTricks({
backend: 'auto',
}),
],
}Notes
When the plugin falls back from native to JS in auto mode, it emits a warning once at plugin creation time.
