Skip to content

Commit

Permalink
Merge pull request #13 from yoichiro/support-compile-options
Browse files Browse the repository at this point in the history
Support compile options
  • Loading branch information
yoichiro authored Sep 17, 2024
2 parents eab0ba8 + 1aadd04 commit 1e2f7eb
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 13 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ This plugin can be configured with the following options:

* `templateFileExtension` (string) - Specifies the extension of Handlebars template files. Defaults to `hbs` if omitted.
* `partialDirectoryPath` (string) - Specifies the path to the directory containing partial template files to be included in Handlebars template files. If omitted, partial template files are not registered.
* `compileOptions` (object) - Specifies the options to be passed to the Handlebars compiler. If omitted, the default options are used.

These options can be specified as arguments to the `handlebarsPlugin` function. Below is an example that specifies `handlebars` as the template file extension and `templates/partials` as the directory containing partial template files.

Expand All @@ -90,6 +91,8 @@ export default defineConfig({
});
```

The `compileOptions` are the various options applied when compiling template files in Handlebars. For details on each option, please refer to the [Handlebars documentation](https://handlebarsjs.com/api-reference/compilation.html#handlebars-compile-template-options).

# Samples

The `integration` directory contains a sample Vite project using this plugin. You can start this sample project by following these steps:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@yoichiro/vite-plugin-handlebars",
"version": "1.1.3",
"version": "1.2.0",
"author": {
"name": "Yoichiro Tanaka",
"email": "[email protected]",
Expand Down
62 changes: 61 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,70 @@ import {
transform,
} from './internal.js';

/** This plugin supports a variety of options to customize the behavior of the Handlebars compiler. */
export type CompileOptions = {
/** Set to false to disable `@data` tracking. */
data?: boolean;
/** Set to true to enable recursive field lookup. */
compat?: boolean;
/**
* Hash containing list of helpers that are known to exist (truthy) at template execution time.
* Passing this allows the compiler to optimize a number of cases.
* Builtin helpers are automatically included in this list and may be omitted by setting that value to `false`.
* */
knownHelpers?: { [p: string]: boolean };
/** Set to true to allow further optimizations based on the known helpers list. */
knownHelpersOnly?: boolean;
/** Set to true to not HTML escape any content. */
noEscape?: boolean;
/**
* Run in strict mode. In this mode, templates will throw rather than silently ignore missing fields.
* This has the side effect of disabling inverse operations such as `{{^foo}}{{/foo}}`
* unless fields are explicitly included in the source object.
* */
strict?: boolean;
/**
* Removes object existence checks when traversing paths.
* This is a subset of `strict` mode that generates optimized templates when the data inputs are known to be safe.
* */
assumeObjects?: boolean;
/**
* By default, an indented partial-call causes the output of the whole partial being indented by the same amount.
* This can lead to unexpected behavior when the partial writes `pre` -tags.
* Setting this option to `true` will disable the auto-indent feature.
*/
preventIndent?: boolean;
/**
* Disables standalone tag removal when set to `true`.
* When set, blocks and partials that are on their own line will not remove the whitespace on that line.
* */
ignoreStandalone?: boolean;
/**
* Disables implicit context for partials.
* When enabled, partials that are not passed a context value will execute against an empty object.
*/
explicitPartialContext?: boolean;
};

/** The options for the Handlebars plugin. */
export type HandlebarsPluginOptions = {
/** The file extension of the Handlebars template files. Default is '.hbs'. */
templateFileExtension?: string;
/**
* The directory path where partial Handlebars files are stored.
* If this option is set, the plugin automatically loads and compiles all partial Handlebars files.
* If omitted, the plugin does not load and compile partial Handlebars files.
*/
partialsDirectoryPath?: string;
/** The compile options for the Handlebars compiler. */
compileOptions?: CompileOptions;
};

/**
* The Handlebars plugin for Vite.
* @param options The options for the Handlebars plugin.
* @returns The Vite plugin instance.
*/
export default function handlebarsPlugin(
options: HandlebarsPluginOptions = {}
): Plugin {
Expand All @@ -26,7 +85,8 @@ export default function handlebarsPlugin(
code,
id,
templateFileExtension,
options.partialsDirectoryPath
options.partialsDirectoryPath,
options.compileOptions
);
return {
code: transformed,
Expand Down
38 changes: 27 additions & 11 deletions src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export const decideTemplateFileExtension = (

export const createPartialMap = (
templateFileExtension: string,
partialsDirectoryPath?: string
partialsDirectoryPath: string | undefined,
compileOptions: CompileOptions | undefined
): { [p: string]: string } => {
if (partialsDirectoryPath === undefined) {
return {};
Expand All @@ -30,17 +31,23 @@ export const createPartialMap = (
return loadAndCompileFiles(
templateFileExtension,
partialsPath,
partialsFiles
partialsFiles,
compileOptions
);
};

const getPartialMap = (
templateFileExtension: string,
partialsDirectoryPath: string | undefined
partialsDirectoryPath: string | undefined,
compileOptions: CompileOptions | undefined
): { [p: string]: string } => {
return (
cachePartialMap ??
createPartialMap(templateFileExtension, partialsDirectoryPath)
createPartialMap(
templateFileExtension,
partialsDirectoryPath,
compileOptions
)
);
};

Expand All @@ -52,13 +59,15 @@ export const transform = (
code: string,
_id: string,
templateFileExtension: string,
partialsDirectoryPath: string | undefined
partialsDirectoryPath: string | undefined,
compileOptions: CompileOptions | undefined
): string => {
const partialMap = getPartialMap(
templateFileExtension,
partialsDirectoryPath
partialsDirectoryPath,
compileOptions
);
const precompiled = Handlebars.precompile(code);
const precompiled = Handlebars.precompile(code, compileOptions ?? {});
return `
import Handlebars from 'handlebars/runtime';
Expand All @@ -71,14 +80,21 @@ ${Object.entries(partialMap)
export default Handlebars.template(${precompiled});`;
};

export const loadAndCompileFile = (filePath: string): string => {
return Handlebars.precompile(fs.readFileSync(filePath, 'utf-8')).toString();
export const loadAndCompileFile = (
filePath: string,
compileOptions: CompileOptions | undefined
): string => {
return Handlebars.precompile(
fs.readFileSync(filePath, 'utf-8'),
compileOptions ?? {}
).toString();
};

export const loadAndCompileFiles = (
templateFileExtension: string,
baseDirectoryPath: string,
filePaths: string[]
filePaths: string[],
compileOptions: CompileOptions | undefined
): { [p: string]: string } => {
return filePaths.reduce(
(partialMap, file: string) => {
Expand All @@ -87,7 +103,7 @@ export const loadAndCompileFiles = (
baseDirectoryPath,
file
);
partialMap[partialName] = loadAndCompileFile(file);
partialMap[partialName] = loadAndCompileFile(file, compileOptions);
return partialMap;
},
{} as { [p: string]: string }
Expand Down

0 comments on commit 1e2f7eb

Please sign in to comment.