babel-plugin-ember-template-compilation
Babel plugin that implements Ember's low-level template-compilation API.
Requirements
Usage
This plugin implements precompileTemplate
from RFC 496:
import { precompileTemplate } from '@ember/template-compilation';
For backward compatibility, it also has an enableLegacyModules
option that can enable each of these widely-used older patterns:
import { hbs } from 'ember-cli-htmlbars';
import hbs from 'ember-cli-htmlbars-inline-precompile';
import hbs from 'htmlbars-inline-precompile';
Common Options
This package has both a Node implementation and a portable implementation that works in browsers.
The exported modules are:
babel-plugin-ember-template-compilation
: automatically chooses between the node and browser implementations (using package.json exports
feature).babel-plugin-ember-template-compilation/browser
: the core implementation that works in browsers (and anywhere else) without using any Node-specific APIs.babel-plugin-ember-template-compilation/node
: the Node-specific implementation that adds the ability to automatically load plugins from disk, etc.
The options are:
interface Options {
compiler?: EmberTemplateCompiler;
compilerPath?: string;
outputModuleOverrides?: Record<string, Record<string, [string, string]>>;
enableLegacyModules?: LegacyModuleName[];
targetFormat?: 'wire' | 'hbs';
transforms?: Transform[];
}
type LegacyModuleName =
| 'ember-cli-htmlbars'
| 'ember-cli-htmlbars-inline-precompile'
| 'htmlbars-inline-precompile';
type Transform = Function | string | [string, unknown];
JSUtils: Manipulating Javascript from within AST transforms
AST transforms are plugins for modifying HBS templates at build time. Because those templates are embedded in Javascript and can access the Javascript scope, an AST plugin may want to introduce some new things into Javascript scope. That is what the JSUtils API is for.
Your AST transform can access the JSUtils API via env.meta.jsutils
. Here's an example transform.
function myAstTransform(env) {
return {
name: 'my-ast-transform',
visitor: {
PathExpression(node, path) {
if (node.original === 'onePlusOne') {
let name = env.meta.jsutils.bindExpression('1+1', path, { nameHint: 'two' });
return env.syntax.builders.path(name);
}
},
},
};
}
The example transform above would rewrite:
import { precompileTemplate } from '@ember/template-compilation';
precompileTemplate('<Counter @value={{onePlusOne}} />>');
To:
import { precompileTemplate } from '@ember/template-compilation';
let two = 1 + 1;
precompileTemplate('<Counter @value={{two}} />', { scope: () => ({ two }) });
See the jsdoc comments in js-utils.js for details on the methods available.
Acknowledgement / History
This repo derives from https://github.com/ember-cli/babel-plugin-htmlbars-inline-precompile