Search code examples
javascriptrolluptemplate-literals

How to import HTML files as templates into Rollup and compile to concatenated strings


I'm creating a build process for Optimizely experiments using Rollup. We were currently using Webpack but that exports bloated code for this use case. I want to be able to import .html files as templates and compile them to ES5 compatible concatenated strings in my Rollup/Babel build.

I've already tried some of the template plugins at https://github.com/rollup/awesome#templating but don't want to add another module library as a dependency to each experiment. I was able to get HTML imported as a template literal using a couple of the plugins but for some reason they don't compile to an ES5 compatible string by babel. Babel seems to only compile inline (not imported) template literals to concatenated strings. Everything else compiles to ES5 correctly. Not sure why external HTML strings are not included. Maybe my problem is a babel config?

The method we've been using with our Webpack build uses html-es6-template-loader which has built in compilation so it can generate ES5 compatible string concatenation out of the box. Something similar might be ideal.

This is my current configuration. Using posthtml here but I've tried multiple plugins with the same result.

import babel from 'rollup-plugin-babel';
import posthtml from 'rollup-plugin-posthtml-template';

export default {
    input: './src/index',
    output: {
        file: './dist/index.js',
        format: 'cjs'
    },
    plugins: [
        posthtml({
            template: true
        }),
        babel({
            exclude: 'node_modules/**',
            presets: ['@babel/preset-env']
        })
    ]
}

Ideal scenario starting with an HTML file as a template with es6 ${} syntax, importing into a JS file, and compiling to a JS file with inline concatenated string.

template.html

<div class="some-div">hello ${data.entity}</div>

index.js written in modern ES version

import template from './template.html';
console.log(template({entity="world"})); // logs: <div class="some-div">hello world</div>

I expect the result to be compiled script compatible with ES5 without the need for extra code for templating. result would be similar to the code below.

var template = function(data){
  return '<div class="some-div">hello ' + data.entity + '</div>';
}
console.log(template({entity="world"})); // logs: <div class="some-div">hello world</div>

Solution

  • I figured out the solution. I just needed to add HTML to the babel config. I didnt think that was needed before since I thought babel just parsed the JS file after the HTML got imported and converted to a template literal but I guess it is needed.

    I figured this out while looking through the docs on external dependencies for rollup-plugin-babel

    babel({
        exclude: 'node_modules/**',
        presets: ['@babel/preset-env'],
        extensions: ['.js', '.html']
    })