Nocturnal Programmer's Machine

    handlebars-webpack-plugin
    DefinitelyTyped icon, indicating that this package has TypeScript declarations provided by the separate @types/handlebars-webpack-plugin package

    2.2.1 • Public • Published

    handlebars webpack plugin

    Server-side template rendering using Handlebars.

    npm install handlebars-webpack-plugin --save-dev

    Usage

    In your webpack config register and setup the handlebars plugin

    const path = require("path");
    const HandlebarsPlugin = require("handlebars-webpack-plugin");
     
    const webpackConfig = {
     
      plugins: [
     
        new HandlebarsPlugin({
          // path to hbs entry file(s). Also supports nested directories if write path.join(process.cwd(), "app", "src", "**", "*.hbs"),
          entry: path.join(process.cwd(), "app", "src", "*.hbs"),
          // output path and filename(s). This should lie within the webpacks output-folder
          // if ommited, the input filepath stripped of its extension will be used
          output: path.join(process.cwd(), "build", "[name].html"),
          // you can also add a [path] variable, which will emit the files with their relative path, like
          // output: path.join(process.cwd(), "build", [path], "[name].html"),
          
          // data passed to main hbs template: `main-template(data)`
          data: require("./app/data/project.json"),
          // or add it as filepath to rebuild data on change using webpack-dev-server
          data: path.join(__dirname, "app/data/project.json"),
     
          // globbed path to partials, where folder/filename is unique
          partials: [
            path.join(process.cwd(), "app", "src", "components", "*", "*.hbs")
          ],
     
          // register custom helpers. May be either a function or a glob-pattern
          helpers: {
            nameOfHbsHelper: Function.prototype,
            projectHelpers: path.join(process.cwd(), "app", "helpers", "*.helper.js")
          },
     
          // hooks
          // getTargetFilepath: function (filepath, outputTemplate) {},
          // getPartialId: function (filePath) {}
          onBeforeSetup: function (Handlebars) {},
          onBeforeAddPartials: function (Handlebars, partialsMap) {},
          onBeforeCompile: function (Handlebars, templateContent) {},
          onBeforeRender: function (Handlebars, data, filename) {},
          onBeforeSave: function (Handlebars, resultHtml, filename) {},
          onDone: function (Handlebars, filename) {}
        })
      ]
    };

    Partial ids are registered by parentFolder/filename (without file extensions)

    Use handlebars in your main and partials like, i.e.

    <body>
      {{> partialFolder/partialName}}
     
      {{> header/header title="page title"}}
     
      {{> partial/content}}
    </body>

    Options

    target filepaths

    Per default, the generated filepath of the html-results is defined by the output-property in the plugin-options. To changed the output folder and name, you can pass your custom filepath-helper to the plugin-options like

    {
        /**
         * Modify the default output path of each entry-template
         * @param {String} filepath     - the source of the template
         * @param {String} outputTemplate - the filepath template defined in `output`
         * @param {String} rootFolder   - the filepaths rootFolder
         * @return {String} final path, where the rendered html-file should be saved
         */
        getTargetFilepath: function getTargetFilepath(filepath, outputTemplate, rootFolder) {
            const fileName = path.basename(filepath).replace(path.extname(filepath), "");
            return outputTemplate.replace("[name]", fileName);
        };
    }

    You can find the default implementation in utils/getTargetFilepath.

    partial ids

    Per default, partials are identified with folder/filename in a hbs-template. e.g. a file in app/partials/page/header.hbs will be registered under page/header and can be included with

    {{> page/header title="page title"}}

    To change the partial's id you can pass a custom partial-generator to the plugin-options like

    {
        /**
         * Modify the hbs partial-id created for a loaded partial
         * @param {String} filePath   - filePath to the loaded partial
         * @return {String} hbs-partialId, per default folder/partialName is used
         */
        getPartialId: function (filePath) {
            return filePath.match(/\/([^/]+\/[^/]+)\.[^.]+$/).pop();
        }
    }

    Html Webpack Plugin

    Use the html-webpack-plugin to generate partials, that are dynamically registered to the handlebars-webpack-plugin

    • the HtmlWebpackPlugin should be placed before the HandlebarsWebpackPlugin
    • multiple HtmlWebpackPlugins may be used
    • per default, the partials get registered to html/<outputfilename>, i.e. a filename /dist/partials/head.hbs will be registered as html/head to handlebars
    plugins: [
       new HtmlWebpackPlugin({
        title: "Generic Head Title",
        // the template you want to use
        template: path.join(__dirname, "src", "generatedpartial", "head.hbs"),
        // the output file name
        filename: path.join(__dirname, "dist", "partials", "head.hbs"),
        inject: "head"
      }),
     
      new HandlebarsWebpackPlugin({
     
        htmlWebpackPlugin: {
          enabled: true, // register all partials from html-webpack-plugin, defaults to `false`
          prefix: "html", // where to look for htmlWebpackPlugin output. default is "html"
          HtmlWebpackPlugin // optionally: pass in HtmlWebpackPlugin if it cannot be resolved
        },
     
        entry: path.join(process.cwd(), "src", "hbs", "*.hbs"),
        output: path.join(process.cwd(), "dist", "[name].html"),
     
        partials: [
          path.join(process.cwd(), "html",/* <-- this should match htmlWebpackPlugin.prefix */ "*", "*.hbs"),
          path.join(process.cwd(), "src", "hbs", "*", "*.hbs")
        ]
      })
    ]

    Utilities

    Merging input-data

    In case you have several json-files that need to be passed to handlebars-compilation, you can build this within your webpack-configuration file. A simple helper can be found in utils/mergeJSON.js, which finds all json files and build a dataObject with { <filename>: <data> }. Example:

    const mergeJSON = require('handlebars-webpack-plugin/utils/mergeJSON');
    const projectData = mergeJSON(path.join(__dirname, "data/**/*.json"));
    // ...
    new HandlebarsPlugin({
        // ...
        data: projectData
    });

    For custom merge behaviour you can add your own merge-helper, following the implementation from utils/mergeJSON.js.

    Contributors

    Install

    npm i handlebars-webpack-plugin

    DownloadsWeekly Downloads

    3,448

    Version

    2.2.1

    License

    MIT

    Unpacked Size

    55.5 kB

    Total Files

    27

    Last publish

    Collaborators

    • sagold