Jostraca code generation, made repeatable

Replace markers in a template

Swap named placeholders in a template for strings, computed values or generated components.

Rendered from docs/how-to/replace-markers-in-a-template.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.

$$path$$ covers values that live in the model. For everything else—a name computed at generate time, a whole block of generated code—pass a replace map. It works on Fragment, Content and Copy.

The template is tpl/class.js:

export class CLASS_NAME {
  // #Body
}
import { Jostraca, Project, File, Fragment, Content } from 'jostraca'

await Jostraca().generate({ folder: './out' }, () => {
  Project({}, () => {
    File({ name: 'widget.js' }, () => {

      Fragment({
        from: '../tpl/class.js',
        replace: {
          CLASS_NAME: 'Widget',
          '#Body': () => Content('    return 1\n'),
        },
      })
    })
  })
})

The generated widget.js:

export class Widget {
    return 1
}

Two different key forms did the work there, and the difference matters:

  • A plain key is matched literally. CLASS_NAME replaced the text wherever it appeared.
  • A key starting # is a comment tag. '#Body' matched the whole line // #Body, indentation included, and replaced it. Writing #Body bare in the template would not have matched.

A key wrapped in slashes is a regular expression: '/name_\\w+/'. A function value receives the named capture groups, the whole match under $&, and the current indent.

One asymmetry to know before you rely on it. A replacement that emits a component lands in the right place inside a Fragment, which streams its output, but is appended after the whole string inside a Content, which joins first. Where position matters, use Fragment—or return a string.

See also#