UNPKG

6.24 kBMarkdownView Raw
1# Ember CLI HTMLBars
2
3<a href="https://github.com/ember-cli/ember-cli-htmlbars/actions"><img alt="Build Status" src="https://github.com/ember-cli/ember-cli-htmlbars/workflows/CI/badge.svg"></a>
4
5## Compatibility
6
7* Ember.js v3.8 or above
8* Ember CLI v3.8 or above
9* Node.js v12 or above
10
11## Tagged Template Usage / Migrating from `htmlbars-inline-precompile`
12
13Starting with version 4.0, this addon now includes the testing helper from [ember-cli-htmlbars-inline-precompile](https://github.com/ember-cli/ember-cli-htmlbars-inline-precompile)
14
15This will require an update to the imports of the `hbs` helper in your tests:
16
17Prior syntax:
18
19```
20import hbs from 'htmlbars-inline-precompile';
21
22...
23
24await render(hbs`
25 <MyComponent />
26`);
27```
28
29New syntax:
30
31```
32import { hbs } from 'ember-cli-htmlbars';
33
34...
35
36await render(hbs`
37 <MyComponent />
38`);
39```
40
41There is a [codemod](https://github.com/ember-codemods/ember-cli-htmlbars-inline-precompile-codemod) available to automate this change.
42
43## Additional Trees
44
45For addons which want additional customizations, they are able to interact with
46this addon directly.
47
48```ts
49interface EmberCLIHTMLBars {
50 /**
51 Supports easier transpilation of non-standard input paths (e.g. to transpile
52 a non-addon NPM dependency) while still leveraging the logic within
53 ember-cli-htmlbars for transpiling (e.g. custom AST transforms, colocation, etc).
54 */
55 transpileTree(inputTree: BroccoliTree): BroccoliTree;
56}
57```
58
59### `transpileTree` usage
60
61```js
62// find the ember-cli-htmlbars addon
63let htmlbarsAddon = this.addons.find(addon => addon.name === 'ember-cli-htmlbars');
64
65// invoke .transpileTree passing in the custom input tree
66let transpiledCustomTree = htmlbarsAddon.transpileTree(someCustomTree);
67```
68
69## Adding Custom Plugins
70
71You can add custom plugins to be used during transpilation of the `addon/` or
72`addon-test-support/` trees of your addon (or the `app/` and `tests/` trees of an application)
73by registering a custom AST transform.
74
75```js
76var SomeTransform = require('./some-path/transform');
77
78module.exports = {
79 name: 'my-addon-name',
80
81 included: function() {
82 // we have to wrap these in an object so the ember-cli
83 // registry doesn't try to call `new` on them (new is actually
84 // called within htmlbars when compiling a given template).
85 this.app.registry.add('htmlbars-ast-plugin', {
86 name: 'some-transform',
87 plugin: SomeTransform
88 });
89
90 this._super.included.apply(this, arguments);
91 }
92};
93```
94
95### Options for registering a plugin
96
97* `name` - String. The name of the AST transform for debugging purposes.
98* `plugin` - A function of type [`ASTPluginBuilder`](https://github.com/glimmerjs/glimmer-vm/blob/v0.83.1/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts#L314-L320).
99* `dependencyInvalidation` - Boolean. A flag that indicates the AST Plugin may, on a per-template basis, depend on other files that affect its output.
100* `cacheKey` - function that returns any JSON-compatible value - The value returned is used to invalidate the persistent cache across restarts, usually in the case of a dependency or configuration change.
101* `baseDir` - `() => string`. A function that returns the directory on disk of the npm module for the plugin. If provided, a basic cache invalidation is performed if any of the dependencies change (e.g. due to a npm install/upgrade).
102
103### Implementing Dependency Invalidation in an AST Plugin
104
105Plugins that set the `dependencyInvalidation` option to `true` can provide function for the `plugin` of type `ASTDependencyPlugin` as given below.
106
107Note: the `plugin` function is invoked without a value for `this` in context.
108
109```ts
110import {ASTPluginBuilder, ASTPlugin} from "@glimmer/syntax/dist/types/lib/parser/tokenizer-event-handlers";
111
112export type ASTDependencyPlugin = ASTPluginWithDepsBuilder | ASTPluginBuilderWithDeps;
113
114export interface ASTPluginWithDepsBuilder {
115 (env: ASTPluginEnvironment): ASTPluginWithDeps;
116}
117
118export interface ASTPluginBuilderWithDeps extends ASTPluginBuilder {
119 /**
120 * @see {ASTPluginWithDeps.dependencies} below.
121 **/
122 dependencies(relativePath): string[];
123}
124
125export interface ASTPluginWithDeps extends ASTPlugin {
126 /**
127 * If this method exists, it is called with the relative path to the current
128 * file just before processing starts. Use this method to reset the
129 * dependency tracking state associated with the file.
130 */
131 resetDependencies?(relativePath: string): void;
132 /**
133 * This method is called just as the template finishes being processed.
134 *
135 * @param relativePath {string} A relative path to the file that may have dependencies.
136 * @return {string[]} paths to files that are a dependency for the given
137 * file. Any relative paths returned by this method are taken to be relative
138 * to the file that was processed.
139 */
140 dependencies(relativePath: string): string[];
141}
142```
143
144## Precompile HTMLBars template strings within other addons
145
146```javascript
147module.exports = {
148 name: 'my-addon-name',
149
150 setupPreprocessorRegistry: function(type, registry) {
151 var htmlbarsPlugin = registry.load('template').find(function(plugin) {
152 return plugin.name === 'ember-cli-htmlbars';
153 });
154
155 // precompile any htmlbars template string via the precompile method on the
156 // ember-cli-htmlbars plugin wrapper; `precompiled` will be a string of the
157 // form:
158 //
159 // Ember.HTMLBars.template(function() {...})
160 //
161 var precompiled = htmlbarsPlugin.precompile("{{my-component}}");
162 }
163};
164```
165
166### Custom Template Compiler
167
168You can still provide a custom path to the template compiler (e.g. to test
169custom template compiler tweaks in an application) by:
170
171```js
172// ember-cli-build.js
173
174module.exports = function(defaults) {
175 let app = new EmberApp(defaults, {
176 'ember-cli-htmlbars': {
177 templateCompilerPath: `some_path/to/ember-template-compiler.js`,
178 }
179 });
180};
181```
182
183## Using as a Broccoli Plugin
184
185```javascript
186var HtmlbarsCompiler = require('ember-cli-htmlbars');
187
188var templateTree = new HtmlbarsCompiler('app/templates', {
189 isHTMLBars: true,
190
191 // provide the templateCompiler that is paired with your Ember version
192 templateCompiler: require('./bower_components/ember/ember-template-compiler')
193});
194```