Make a reusable component
Wrap a function with cmp so it can be called anywhere in a component tree.
Rendered from
docs/how-to/make-a-reusable-component.md
in the generator repository — where a correction belongs, and where the
test suite runs every example on this page or states why it does not.
When the same shape appears more than once, give it a name. cmp()
turns an ordinary function into a component: it can be called from
inside the tree, and the components it calls attach in the right place.
import { Jostraca, Project, File, Content, cmp } from 'jostraca'
const Banner = cmp(function Banner(props) {
Content('/* ' + props.title + ' */\n')
Content('/* generated, do not edit by hand */\n')
})
await Jostraca().generate({ folder: './out' }, () => {
Project({}, () => {
File({ name: 'a.js' }, () => {
Banner({ title: 'alpha' })
Content('export const a = 1\n')
})
File({ name: 'b.js' }, () => {
Banner({ title: 'beta' })
Content('export const b = 2\n')
})
})
})
The generated a.js:
/* alpha */
/* generated, do not edit by hand */
export const a = 1
Banner never mentions a file, a folder, or a path. It emits content,
and its caller decides where that content lands. That is what makes it
reusable, and it is the discipline to keep: a component that calls
File is a section of a generator, not a building block.
Name the function you pass to cmp(). The wrapper keeps the name, and
Fragment uses it to recognise Slot children—an anonymous
component is harder to debug and, inside a Fragment, behaves
differently.
A component can also emit containers when that is what you want: a
cmp() that calls Folder and File works, and the callback you pass
to generate() may itself be a component.
See also#
- Pass data to child components for components that take a body.
- Component reference for the call
forms and
ctx$.