From d5c2ac07f89669beefccc58cb27dce7b95d36cfc Mon Sep 17 00:00:00 2001 From: Momtchil Momtchev Date: Tue, 8 Sep 2020 13:19:44 +0200 Subject: [PATCH] experimental mjs loader for Node 14 --- lib/hbs-es-loader.mjs | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 lib/hbs-es-loader.mjs diff --git a/lib/hbs-es-loader.mjs b/lib/hbs-es-loader.mjs new file mode 100644 index 000000000..610d0e4f3 --- /dev/null +++ b/lib/hbs-es-loader.mjs @@ -0,0 +1,72 @@ +/** + * This is an experimental automatic precompiler for + * ECMAScript Modules in Node.js (aka the Michael Jackson Solution) + * + * + * usage: + * + * node --experimental-loader handlebars/lib/hbs-es-loader.mjs index.js + * + * or + * + * export NODE_OPTIONS="--experimental-loader handlebars/lib/hbs-es-loader.mjs" + * node index.js + * + * + * then import the template and use it as a function: + * + * import tmpl from '../handlebars/email-alert.handlebars'; + * const text = tmpl({}); + */ + +import * as path from 'path'; +import handlebars from 'handlebars'; + +/** + * @param {string} url + * @param {Object} context (currently empty) + * @param {Function} defaultGetFormat + * @returns {Promise<{ format: string }>} + */ +export async function getFormat(url, context, defaultGetFormat) { + try { + const ext = path.extname(url); + if (ext === '.hbs' || ext === '.handlebars') { + return { + format: 'module' + }; + } + } catch (e) { + console.log(e); + } + // Defer to Node.js for all other URLs. + return defaultGetFormat(url, context, defaultGetFormat); +} + + +/** + * @param {!(string | SharedArrayBuffer | Uint8Array)} source + * @param {{ + * format: string, + * url: string, + * }} context + * @param {Function} defaultTransformSource + * @returns {Promise<{ source: !(string | SharedArrayBuffer | Uint8Array) }>} + */ +const _header = 'import handlebars from "handlebars"; const _template = handlebars.template('; +const _footer = '); export default _template;' +export async function transformSource(source, context, defaultTransformSource) { + const { url, format } = context; + try { + const ext = path.extname(url); + if (format === 'module' && (ext === '.hbs' || ext === '.handlebars')) { + return { + source: _header + handlebars.precompile(source.toString()) + _footer + } + } + } catch (e) { + console.log(e); + } + // Defer to Node.js for all other sources. + return defaultTransformSource(source, context, defaultTransformSource); +} \ No newline at end of file