handlebars-lang / handlebars.js

Minimal templating on steroids.
http://handlebarsjs.com
MIT License
17.99k stars 2.04k forks source link

Support ES Modules in precompiled templates #2051

Open arturober opened 2 weeks ago

arturober commented 2 weeks ago

This should not be too complicated because it doens't require much change from CommonJS. As an example, I've created a simple script that makes precompiled templates work with import. I'm running a client app (vanilla JavaScript with Vite).

I'm compiling my templates with CommonJS, and after that I run the script (package.json):

  "scripts": {
    "handlebars": "handlebars -c \"handlebars\" templates/*.hbs -f compiled.js --esm handlebars",
    "posthandlebars": "node hbs-replace.js",
    "prestart": "npm run handlebars",
    "start": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }

This is the script hbs-replace.js:

import {replaceInFileSync} from 'replace-in-file';

const options = {
    files: './compiled.js',
    from: ['var Handlebars = require("handlebars");', /$/],
    to: ['import Handlebars from "handlebars/runtime";', 'export default templates;'],
}

replaceInFileSync(options);

The result (compiled.js):

import Handlebars from "handlebars/runtime"; // Replaced the required statement 
// Unmodified content
export default templates; // Added at the end

And this is how it can be used from code (import):

import templates from './compiled.js';
console.log(templates['example.hbs']({text: 'patata'}));
console.log(templates['example2.hbs']({text: 'patata'}));

Maybe this is not the most elegant way of exporting templates, but it's usable

jaylinski commented 2 weeks ago

Related to #1816.