mbland/rollup-plugin-handlebars-precompiler(新しいタブで開きます)
主要言語: JavaScript
Rollup plugin to precompile Handlebars templates into JavaScript modules
- star 数
- 3
- watcher 数
- 2
- fork 数
- 1
- issue 数
- 1
- 最終更新
- 2024/01/19
主要言語: JavaScript
Rollup plugin to precompile Handlebars templates into JavaScript modules
Rollup plugin to precompile Handlebars templates into JavaScript modules
Note: I still need to add a little bit more documentation, but the plugin is fully functional and tested.
Source: https://github.com/mbland/rollup-plugin-handlebars-precompiler
Add both this package and Handlebars to your project's devDependencies, e.g.,
using pnpm:
pnpm add -D handlebars rollup-plugin-handlebars-precompiler
Even though handlebars is a production dependency of this plugin, your project
needs to install it directly. The JavaScript modules generated by this plugin
need to access the Handlebars runtime at
node_modules/handlebars/lib/handlebars.runtime.js and have it bundled into
your own project.
Each generated Handlebars template module exports two functions:
RawTemplate() emits the raw HTML string generated by applying a Handlebars
template.Template(), emits a
DocumentFragment created from the result of RawTemplate().This provides you with two options of using a given template:
import Template, { RawTemplate } from './component.hbs' const appElem = document.querySelector('#app') const context = { message: 'Hello, World!', url: 'https://en.wikipedia.org/wiki/%22Hello,_World!%22_program' } const compilerOpts = {} // Use the DocumentFragment to append the entire template to a DOM Node at once. // You can also extract individual element references from .children before // doing so. const tmpl = Template(context) const [ firstChild, secondChild ] = tmpl.children appElem.appendChild(tmpl) // Use the RawTemplate() string to render the template manually. const newElem = document.createElement('div') newElem.innerHTML = RawTemplate(context) appElem.appendChild(newElem)
Both Template() and RawTemplate() take an optional Handlebars runtime
options argument:
const runtimeOpts = { data: { '@foo': 'bar' } } const tmpl = Template(context, runtimeOpts)
The plugin configuration, described below, specifies which project files contain custom helper function modules and partial templates.
These custom helper modules, and modules generated for explicitly used partials, are automatically imported by any generated modules that need them. There's no need to import them explicitly in any other code.
Any code using a template that contains dynamic partials will need to import
the generated modules for those partials directly. However, those generated
modules will automatically register any imported partials via
Handlebars.registerPartial().
To enable TypeScript type checking, copy lib/template.d.ts from this package into your project:
cp node_modules/rollup-plugin-handlebars-precompiler/lib/template.d.ts .This is an ambient module defining the types exported from each generated
module. Edit the contents to replace .hbs with your project's Handlebars
template file extension if necessary. If you want, you can change the file name
and locate it anywhere in your project that you wish (that TypeScript will find
it).
This is necessary because the precompiled modules are generated in your
project, not in rollup-plugin-handlebars-precompiler, so that's where
TypeScript needs to find the type declarations.
The function exported by this plugin takes a configuration object as an argument. For example, in a vite.config.js configuration file:
import HandlebarsPrecompiler from 'rollup-plugin-handlebars-precompiler' import { defineConfig } from 'vite' export default defineConfig({ plugins: [ HandlebarsPrecompiler({ helpers: ['components/helpers.js'] }) ] })
All of the configuration parameters are optional:
helpers (string[]): paths to modules containing custom Handlebars helper functions
include (string | string[]): one or more picomatch patterns matching Handlebars template files to transform
['**/*.hbs', '**/*.handlebars', '**/*.mustache']exclude (string | string[]): one or more picomatch patterns matching Handlebars template files to exclude from transformation
'node_modules/**'partials (string | string[]): one or more picomatch patterns matching Handlebars template files containing partials
'**/_*'partialName ((string) => string): function to transform a partial file name into the name used to apply the partial in other templates
components/_my_partial.hbs yields my_partialpartialPath ((string, string) => string): function to transform a partial's name and that of the module importing it into its import path
./_ prefix to the partial namemy_partial, components/other_template.hbs) yields
./_my_partial.hbscompiler (Handlebars.PrecompileOptions): Handlebars compiler options
passed through to Handlebars.parse() and Handlebars.precompile()
sourcemap or sourceMap (boolean): disables source map generation when false
As for why both sourcemap and sourceMap are supported, it's because:
sourceMap: false.sourcemap: false.Modules specified by the configuration as containing custom helpers should export a default function that takes the Handlebars runtime object as an argument. It should then call Handlebars.registerHelper() or any other runtime functions as needed.
Here's an example from test/large/components/helpers.js, adapted from Handlebars - Expressions - Helpers with Hash Arguments:
export default function(Handlebars) { const linkHelper = function(text, options) { const attrs = Object.keys(options.hash).map(key => { return `${Handlebars.escapeExpression(key)}=` + `"${Handlebars.escapeExpression(options.hash[key])}"` }) return new Handlebars.SafeString( `<a ${attrs.join(' ')}>${Handlebars.escapeExpression(text)}</a>` ) } Handlebars.registerHelper('link', linkHelper) }
Partials are first identified as Handlebars templates via the include configuration option. Then the partials, partialName, and partialPath options define a schema used to identify partial template files, register them with the Handlebars runtime, and generate imports.
The default behavior:
_ to contain a partialIf you choose to use a different schema for organizing partials, make sure to update any of these configuration options as necessary.
Uses pnpm and Vitest for building and testing. The Vitest browser mode (using the @vitest/browser plugin) enables all the tests to run in either the jsdom environment or the browser unchanged.
Uses GitHub Actions for continuous integration.
Developed using Vim, Visual Studio Code, and IntelliJ IDEA interchangeably, depending on my inclination from moment to moment.
I developed this while developing the frontend component of
mbland/tomcat-servlet-testing-example, found under
strcalc/src/main/frontend.
There were two existing Rollup plugins for compiling Handlebars templates from which I learned to write this one.
This was the first Rollup plugin to support Handlebars. It's very brief and easy to understand, but doesn't support:
It exports a function that emits the raw string from the applied template, but not one for instantiating it.
rollup-plugin-handlebars-precompiler borrows its include/exclude filters
for template discovery verbatim from this plugin.
This plugin was derived from the first, but does support:
It does not support Handlebars source maps.
TODO: more to come...
Original work rollup-plugin-handlebars © 2016 Benjamin Legrand under the MIT License
Original work rollup-plugin-handlebars-plus © 2016 Mixmax, Inc under the MIT License
Derived work rollup-plugin-handlebars-precompiler © 2023 Mike Bland mbland@acm.org (https://mike-bland.com/) under the Mozilla Public License 2.0
This software is made available as Open Source software under the MIT License ("Original work") and the Mozilla Public License 2.0 ("Derived work").
For the text of the Mozilla Public License 2.0, see the LICENSE.txt file. See the MPL 2.0 FAQ for a higher level explanation.