Render Template Loader
Render templates with Webpack using one of any number of templating engines.
See The Demo Project for an example webpack project setup that uses render-template-loader
with ejs
to render index.html
, and in the same config renders pug
and handlebars
templates as well.
See unit tests and webpack.config.js for other usage examples.
Built-in support for and tested with: ejs
, handlebars
, jade
, mustache
, pug
, twig
, and vash
.
Partials support tested with ejs
, handlebars
, jade
, twig
, and pug
.
Custom engine support included; see loader.spec.js.
Installation
render-template-loader
Install > npm install render-template-loader
Install a template engine or two
> npm install ejs pug
Examples
index.html
from an ejs
template
Render index.ejs (input)
<%=title%> <% include body %>
body.ejs (partial)
<%=title%><%=desc%>
webpack.config.js (config)
const path = const HtmlWebpackPlugin = moduleexports = entry: './src/index.js' output: filename: '[name].bundle.js' path: path module: rules: test: /\/src\/index.ejs$/ use: loader: 'render-template-loader' options: engine: 'ejs' locals: title: 'Render Template Loader' desc: 'Rendering templates with a Webpack loader since 2017' { // Ejs wants the template filename for partials rendering. // (Configuring a "views" option can also be done.) return filename: infofilename } plugins: template: 'src/index.ejs'
index.html (output)
Render Template Loader Render Template Loader Rendering templates with a Webpack loader since 2017
page.html
from a pug
template
Render page.pug (input)
html(lang="en") head title #{title} body include body
body.pug (partial)
#{title}#{desc}
webpack.config.js (config)
const path = const HtmlWebpackPlugin = moduleexports = entry: './src/index.js' output: filename: '[name].bundle.js' path: path module: rules: test: /\.pug$/ use: loader: 'file-loader?name=[name].html' /** * We use extract-loader in this configuration because * file-loader above expects a string. In other configs, * we use HtmlWebpackLoader which handles the module * output of render-template-loader, so extract-loader * is not required. */ loader: 'extract-loader' loader: 'render-template-loader' options: engine: 'pug' locals: title: 'Rendered with Pug!' desc: 'Partials Support' { return filename: infofilename } plugins:
page.html (output)
Rendered with Pug! Rendered with Pug! Partials Support
Loader Options
options: // The name of the engine as installed by npm (required). engine: 'engine name' | {) // Template variables (optional). locals: ... | { return ... } // Options specific to the engine (optional). engingeOptions: {} | {} // Called before the template is rendered (optional). {}}
engine (string|function)
: (required) the name of the template engine as installed, e.g., ejs
, or a custom engine function that returns the rendered template.
It can’t be a arrow function because we use .call()
to have webpack context as this
.
engine: 'ejs'locals: title: 'Ejs Template' desc: 'A template rendered by ejs'
{ return ejs}locals: title: 'Custom Template' desc: 'A template rendered by a custom function (using ejs)'
{ return input}locals: title: 'Custom Template' desc: 'A template rendered by a custom function (using regex)'
locals (object)
: (optional) an object containing variables used by the template. A local variable title
will be used by a template, e.g., <%= title %>
.
locals: title: 'Ejs Template' desc: 'A template rendered by ejs'
locals
can also be a function that returns a locals object:
{ return title: 'Ejs Template' desc: 'A template rendered by ejs' }
<%= title %><%= desc %>
engineOptions (object|function)
: (optional) an options object passed to the template engine when it's loaded. The content of this object is determined by each engine's configuration. For simple template rendering (without partials) engineOptions
isn't usually required.
engineOptions: views: './src/views'
{ // The info object contains the filename of the // template being rendered. return filename: infofilename }
init (function)
: (optional) a function called before the template is rendered. This is useful for engines that might require setup code to run before use. For instance, handlebars
partials can be configured by calling handlebars.registerPartial
.
engine: 'handlebars'locals: title: 'Handlebars Template' desc: 'A template rendered by Handlebars' { engine}
The Loader Context
Options which can be functions have their this
context set to the loader context. This allows for advanced usage, such as adding webpack dependencies on the fly. See the webpack documentation on the LoaderContext for its api methods.
Example
json data
loader configuration
loader: 'render-template-loader' options: engine: 'ejs' { // Ejs wants the template filename for partials rendering. // (Configuring a "views" option can also be done.) return filename: infofilename } { const file = path // Access the loader context's addDependency method to // add a data file dependency. this const buffer = fs // Return the loaded json as the locals. return JSON }
FAQ
Why do some configurations use
extract-loader
and others do not?
render-template-loader
exports the rendered template as a commonjs
javascript module:
moduleexports = "<h1>Pug Template</h1><h2>A template rendered by Pug</h2>"
In many cases, such as when using HtmlWebpackPlugin
, this is exactly what you want, because module code is expected. In other cases, such as when using file-loader
or html-loader
or some other loader that expects plain text, extract-loader
manages extracting the stirng from the module's output:
<h1>Pug Template</h1><h2>A template rendered by Pug</h2>
with extract-loader
/** * Use extract-loader because we're using file loader instead of * HtmlWebpackPlugin. */const path = const HtmlWebpackPlugin = moduleexports = entry: './src/index.js' output: filename: '[name].bundle.js' path: path module: rules: test: /\.pug$/ use: loader: 'file-loader?name=[name].html' /** * We use extract-loader in this configuration because * file-loader above expects a string. In other configs, * we use HtmlWebpackLoader which handles the module * output of render-template-loader, so extract-loader * is not required. */ loader: 'extract-loader' loader: 'render-template-loader' options: engine: 'pug' locals: title: 'Rendered with Pug!' desc: 'Partials Support' { return filename: infofilename } plugins:
without extract loader
/** * No need for extract-loader here because HtmlWebpackPlugin is * handling the index.ejs file. * */const path = const HtmlWebpackPlugin = moduleexports = entry: './src/index.js' output: filename: '[name].bundle.js' path: path module: rules: test: /\/src\/index.ejs$/ use: loader: 'render-template-loader' options: engine: 'ejs' locals: title: 'Render Template Loader' desc: 'Rendering templates with a Webpack loader since 2017' { // Ejs wants the template filename for partials rendering. // (Configuring a "views" option can also be done.) return filename: infofilename } plugins: // Tell HtmlWebpackPlugin about our index.ejs template. template: 'src/index.ejs'