# Runtime Compiler Options post Ember 3.16

**URL:** <https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271>\
**Category:** Questions\
**Created:** [October 14, 2023, 11:57pm UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271 "2023-10-14T23:57:51Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![levimoore](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/levimoore/32/13840_2.png) [@levimoore](https://discuss.emberjs.com/u/levimoore)\
**Post date:** [October 14, 2023, 11:57pm UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271/1 "2023-10-14T23:57:51Z")

</div>

Hello. I am currently in the process of upgrading an Ember app from 3.16 to 3.24 and am hitting a wall. The goal is to immediately go to 3.28, but that requires updating a bunch of add ons and switching to ember-auto-import 2, webpack, etc… but if a better path is 3.16 → 3.28 for the issue described below let me know.

**My Problem**

The way our app works is that users can sign up for searchable “integrations”, they can subscribe and unsubscribe to these on the fly. Then when they enter a search term, the server returns results based on the subscribed-to integrations.

Each integration supplies the client with an Ember component (JS and template). This is done through an integation-loader service. For example the wikipedia integration:

```auto
// wikipedia.js
'use strict';

polarity.export = PolarityComponent.extend({
  details: Ember.computed.alias('block.data.details')
});

```

and a template:

```auto
<h1 class="p-title">{{fa-icon "search" fixedWidth=true}} Search Result</h1>
<div>
  <span class="p-key">Article: </span>
  <span class="p-value"><a class="p-link" href="{{details.match.link}}">{{details.match.label}} {{fa-icon "external-link" class="external-link-icon"}}</a></span>
</div>
{{#if (gt details.relatedList.length 0)}}
  <h1 class="p-title">{{fa-icon "link" fixedWidth=true}} Related Wikipedia Articles</h1>
  <ul class="link-list">
    {{#each details.relatedList as |item|}}
      <li><a class="p-link" href="{{item.link}}">{{item.label}}</a></li>
    {{/each}}
  </ul>
{{/if}}

```

This template is compiled on the server and sent to the client in the “wire” format.

```auto
{
    "id": "5sJCSUQF",
    "block": "{\"symbols\":[\"item\"],\"statements\":[[7,\"h1\",true.............,
    "meta": {}
}

```

The server @ember-source matches the client @ember-source, so the wire format is 3.16 for 3.16 and 3.24 for 3.24.

Our current implementation uses `createTemplateFactory` like so:

```auto
app.register('component:/wikipedia', evaluatedJS);
app.register('template:/wikipedia', createTemplateFactory(compiled));

```

In Ember 3.16 the createTemplateFactory uses this function (via @ember/-internals/glimmer/index):

```auto
  var TEMPLATE_COMPILER_MAIN = (0, _container.privatize)`template-compiler:main`;

  function template(json) {
    var glimmerFactory = (0, _opcodeCompiler.templateFactory)(json);
    var cache = new WeakMap();

    var factory = owner => {
      var result = cache.get(owner);

      if (result === undefined) {
        counters.cacheMiss++;
        var compiler = owner.lookup(TEMPLATE_COMPILER_MAIN);
        result = glimmerFactory.create(compiler, {
          owner
        });
        cache.set(owner, result);
      } else {
        counters.cacheHit++;
      }

      return result;
    };

    factory.__id = glimmerFactory.id;
    factory.__meta = glimmerFactory.meta;
    return factory;
  }

```

This has changed to the following in 3.24 (via @glimmer/opcode-compiler)

```auto
function templateFactory({
    id: templateId,
    moduleName,
    block
  }) {
    // TODO(template-refactors): This should be removed in the near future, as it
    // appears that id is unused. It is currently kept for backwards compat reasons.
    var id = templateId || `client-${clientId++}`; // TODO: This caches JSON serialized output once in case a template is
    // compiled by multiple owners, but we haven't verified if this is actually
    // helpful. We should benchmark this in the future.

    var parsedBlock;
    var ownerlessTemplate = null;
    var templateCache = new WeakMap();
    var factory = owner => {
      if (parsedBlock === undefined) {
        parsedBlock = JSON.parse(block);
      }
      if (owner === undefined) {
        if (ownerlessTemplate === null) {
          templateCacheCounters.cacheMiss++;
          ownerlessTemplate = new TemplateImpl({
            id,
            block: parsedBlock,
            moduleName,
            owner: null
          });
        } else {
          templateCacheCounters.cacheHit++;
        }
        return ownerlessTemplate;
      }
      var result = templateCache.get(owner);
      if (result === undefined) {
        templateCacheCounters.cacheMiss++;
        result = new TemplateImpl({
          id,
          block: parsedBlock,
          moduleName,
          owner
        });
        templateCache.set(owner, result);
      } else {
        templateCacheCounters.cacheHit++;
      }
      return result;
    };
    factory.__id = id;
    factory.__meta = {
      moduleName
    };
    return factory;
  }

```

So now I am receiving the error:

```auto
Error occurred:

- While rendering:
  -top-level
    application
      integrations/wikipedia

```

I have tried using the following babel plugins:

```auto
babel-plugin-htmlbars-inline-precompile

babel-plugin-ember-template-compilation

```

But have not had much luck. These seem to be focused on the `hbs` functionality and when using the `compile` function, I am greeted with `Ember.HTMLbars.compile` is not a function. Also I do not want the configuration in my ember-cli-build.js to affect my build time templates only my runtime ones.

The server does also send the non-wire template. i.e:

```auto
// wikipedia.hbs
<h1 class="p-title">{{fa-icon "search" fixedWidth=true}} Search Result</h1>
<div>
  <span class="p-key">Article: </span>
  <span class="p-value"><a class="p-link" href="{{details.match.link}}">{{details.match.label}} {{fa-icon "external-link" class="external-link-icon"}}</a></span>
</div>
{{#if (gt details.relatedList.length 0)}}
  <h1 class="p-title">{{fa-icon "link" fixedWidth=true}} Related Wikipedia Articles</h1>
  <ul class="link-list">
    {{#each details.relatedList as |item|}}
      <li><a class="p-link" href="{{item.link}}">{{item.label}}</a></li>
    {{/each}}
  </ul>
{{/if}}

```

and if I just call `hbs(the above code)` it works, but `hbs(${stringPlaceholder})` does not work and has been documented to not be possible which is unfortunate.

**My Question** What can I use to register a template either in hbs or wire format at runtime post Ember 3.16?

More specifically what can I pass as the second argument to the `app.register( )` function for a template at runtime?

---

<div class="post-metadata">

**Author:** ![NullVoxPopuli](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/nullvoxpopuli/32/18691_2.png) [@NullVoxPopuli](https://discuss.emberjs.com/u/NullVoxPopuli)\
**Post date:** [October 15, 2023, 12:11am UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271/2 "2023-10-15T00:11:53Z")

</div>

> `Ember.HTMLbars.compile` is not a function

ye, it’s not meant to be a runtime API.

> but `hbs(${stringPlaceholder})` does not work and has been documented to not be possible which is unfortunate

ye, this is because the babel transform that operates on `hbs` can’t guarantee that that string placeholders do what the user wants or would expect (for example, if you place a reactive reference in the `${}`

* * *

> More specifically what can I pass as the second argument to the `app.register( )` function for a template at runtime?

I don’t think you want to mess with the registry, actually – you may be interested in another approach which would allow you to delete a bunch of your existing code.

Idk if this is an option for you, but if you skip to 3.28 (which may require some deprecation silencing via ember-cli-deprecation-workflow while you incrementally work on upgrading stuff), you can use [ember-repl - npm](https://www.npmjs.com/package/ember-repl)

which gives you a nicer runtime api for compiling templates:

```js
// app/components/my-component.js
import Component from '@glimmer/component'; 
import { compileHBS } from 'ember-repl'; 

export class Renderer extends Component { 
  compileResult = compileHBS(this.args.input); 
}

```

```hbs
{{! app/components/my-component.hbs }}
<this.compileResult.component />

```

of note, however, that `ember-repl` is _strict mode only_, which means if your dynamically compiled components need to access other components or helpers or anything like that, they’ll need be referenced as identifiers in the template, and then passed via the “scope bag”

for example (from the readme)

```js
import Component from '@glimmer/component';
import { compileHBS } from 'ember-repl';
import BarComponent from './bar'

export class Renderer extends Component {
  compileResult = compileHBS(
    '<Bar />',
    {
      scope: {
        Bar: BarComponent
      }
    }
  );
}

```

There is also a `beta` of `ember-repl`, which uses resources, if that’s of interest to you

> **[ember-repl](https://www.npmjs.com/package/ember-repl/v/3.0.0-beta.6)**
>
> Addon for enabling REPL and Playground creation with Ember/Glimmer. Latest version: 2.0.63, last published: a year ago. Start using ember-repl in your project by running \`npm i ember-repl\`. There is 1 other project in the npm registry using...

---

<div class="post-metadata">

**Author:** ![levimoore](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/levimoore/32/13840_2.png) [@levimoore](https://discuss.emberjs.com/u/levimoore)\
**Post date:** [October 15, 2023, 12:24am UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271/3 "2023-10-15T00:24:22Z")

</div>

Dude I love you! I follow you on twitter, and have listened to you on the WW&W podcast and am so grateful you are so active in the Ember community.

I’ll try this. 🙏

---

<div class="post-metadata">

**Author:** ![levimoore](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/levimoore/32/13840_2.png) [@levimoore](https://discuss.emberjs.com/u/levimoore)\
**Post date:** [October 19, 2023, 6:00pm UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271/4 "2023-10-19T18:00:26Z")

</div>

@NullVoxPopuli So I have been able to get our app to build and run using 3.28, and am close to getting ember-repl working.

The problem I’m having currently is attaching my js and hbs?

It seems that `compileHBS` is for template only components, and all of the components we are getting from the server have js and hbs together sent like this:

```auto
{
    "component": {
        "content": "'use strict';\n\npolarity.export = PolarityComponent.extend({\n details: Ember.computed.alias('block.data.details')\n});\n",
        "file": "./components/wiki.js"
    },
    "template": {
        "compiled": "{\"id\":\"5sJCSUQF\",\"block\":\"{\\\"symbols\\\":[\\\"item\\\"],\\\"statements\\\":[[7,\\\"h1\\\",true],[10,\\\"class\\\",\\\"p-title\\\"],[8],[1,[28,\\\"fa-icon\\\",[\\\"search\\\"],[[\\\"fixedWidth\\\"],[true]]],false],[0,\\\" Search Result\\\"],[9],[0,\\\"\\\\n\\\"],[7,\\\"div\\\",true],[8],[0,\\\"\\\\n \\\"],[7,\\\"span\\\",true],[10,\\\"class\\\",\\\"p-key\\\"],[8],[0,\\\"Article: \\\"],[9],[0,\\\"\\\\n \\\"],[7,\\\"span\\\",true],[10,\\\"class\\\",\\\"p-value\\\"],[8],[7,\\\"a\\\",true],[10,\\\"class\\\",\\\"p-link\\\"],[11,\\\"href\\\",[29,[[24,[\\\"details\\\",\\\"match\\\",\\\"link\\\"]]]]],[8],[1,[24,[\\\"details\\\",\\\"match\\\",\\\"label\\\"]],false],[0,\\\" \\\"],[1,[28,\\\"fa-icon\\\",[\\\"external-link\\\"],[[\\\"class\\\"],[\\\"external-link-icon\\\"]]],false],[9],[9],[0,\\\"\\\\n\\\"],[9],[0,\\\"\\\\n\\\"],[4,\\\"if\\\",[[28,\\\"gt\\\",[[24,[\\\"details\\\",\\\"relatedList\\\",\\\"length\\\"]],0],null]],null,{\\\"statements\\\":[[0,\\\" \\\"],[7,\\\"h1\\\",true],[10,\\\"class\\\",\\\"p-title\\\"],[8],[1,[28,\\\"fa-icon\\\",[\\\"link\\\"],[[\\\"fixedWidth\\\"],[true]]],false],[0,\\\" Related Wikipedia Articles\\\"],[9],[0,\\\"\\\\n \\\"],[7,\\\"ul\\\",true],[10,\\\"class\\\",\\\"link-list\\\"],[8],[0,\\\"\\\\n\\\"],[4,\\\"each\\\",[[24,[\\\"details\\\",\\\"relatedList\\\"]]],null,{\\\"statements\\\":[[0,\\\" \\\"],[7,\\\"li\\\",true],[8],[7,\\\"a\\\",true],[10,\\\"class\\\",\\\"p-link\\\"],[11,\\\"href\\\",[29,[[23,1,[\\\"link\\\"]]]]],[8],[1,[23,1,[\\\"label\\\"]],false],[9],[9],[0,\\\"\\\\n\\\"]],\\\"parameters\\\":[1]},null],[0,\\\" \\\"],[9],[0,\\\"\\\\n\\\"]],\\\"parameters\\\":[]},null],[0,\\\"\\\\n\\\"]],\\\"hasEval\\\":false}\",\"meta\":{}}",
        "content": "<h1 class=\"p-title\">{{fa-icon \"search\" fixedWidth=true}} Search Result</h1>\n<div>\n <span class=\"p-key\">Article: </span>\n <span class=\"p-value\"><a class=\"p-link\" href=\"{{details.match.link}}\">{{details.match.label}} {{fa-icon \"external-link\" class=\"external-link-icon\"}}</a></span>\n</div>\n{{#if (gt details.relatedList.length 0)}}\n <h1 class=\"p-title\">{{fa-icon \"link\" fixedWidth=true}} Related Wikipedia Articles</h1>\n <ul class=\"link-list\">\n {{#each details.relatedList as |item|}}\n <li><a class=\"p-link\" href=\"{{item.link}}\">{{item.label}}</a></li>\n {{/each}}\n </ul>\n{{/if}}\n\n",
        "file": "./template/wiki.hbs"
    }
}

```

I am assuming I can call `compileJS` to create the component at runtime but am not sure how to attach the JS and the hbs together?

---

<div class="post-metadata">

**Author:** ![NullVoxPopuli](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/nullvoxpopuli/32/18691_2.png) [@NullVoxPopuli](https://discuss.emberjs.com/u/NullVoxPopuli)\
**Post date:** [October 19, 2023, 6:59pm UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271/5 "2023-10-19T18:59:58Z")

</div>

Nah, separate js and hbs are not a concept in ember-repl, it’s too hard to support the old way.

Ember-repl only supports `<template>` syntax, which you can learn about at [https://tutorial.glimdown.com](https://tutorial.glimdown.com)

---

<div class="post-metadata">

**Author:** ![levimoore](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/levimoore/32/13840_2.png) [@levimoore](https://discuss.emberjs.com/u/levimoore)\
**Post date:** [October 19, 2023, 7:07pm UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271/6 "2023-10-19T19:07:59Z")

</div>

So I suppose the answer to my original question is No. There are no runtime compiler options post Ember 3.16?

Thanks for the help.

---

<div class="post-metadata">

**Author:** ![NullVoxPopuli](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/nullvoxpopuli/32/18691_2.png) [@NullVoxPopuli](https://discuss.emberjs.com/u/NullVoxPopuli)\
**Post date:** [October 23, 2023, 3:04am UTC](https://discuss.emberjs.com/t/runtime-compiler-options-post-ember-3-16/20271/7 "2023-10-23T03:04:45Z")

</div>

> There are no runtime compiler options post Ember 3.16?

it’s more complicated than that. You could reverse-engineer ember-repl and build what you need.

Also, per [JS Representation of Template Tag by ef4 · Pull Request #931 · emberjs/rfcs · GitHub](https://github.com/emberjs/rfcs/pull/931),

we’ll have:

```js
import { template } from "@ember/template-compiler/runtime";

const Headline = template("<h1>{{yield}}</h1>");
const Section = template(
  "<Headline>{{@title}}</Headline>", 
  { 
    scope: () => ({ Headline}) 
  }
);

```

and for class-based components:

```js
import { template } from "@ember/template-compiler/runtime";
class Example extends Component {
  static {
    template(
      "Hello {{message}}",
      {
        component: this,
        scope: () => ({ message }),
      },
    );
  }
}

```

the RFC calls out:

> Unlike `precompileTemplate`, our `strict` param defaults to true instead of false if it’s not provided. This is aligned with the expectation that our main programming model is moving everyone toward handlebars strict mode by default.

_however_ if you have JS, you still have to use `eval`, like ember-repl does.
