Skip to content
This repository has been archived by the owner on Dec 8, 2024. It is now read-only.

[WIP] precompileTemplate with scope that has properties with different key and value #486

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

candunaj
Copy link

@candunaj candunaj commented Mar 21, 2023

Background

This PR solves a bug in precompileTemplate scope. precompileTemplate expects that the scope is a function that returns an object with a few properties where keys and values are equal, as in the following example.

import RootSelect from '../different/select.js';
import Select from '../select.js';

precompileTemplate(`
    <RootSelect/>
    <Select/>
    <button {{on "click" this.toogleClicked}}>
      {{#if this.isClicked}}
        Clicked
      {{else}}
        Not clicked
      {{/if}}
    </button>
  `, {
  strictMode: true,
  scope: () => ({
    RootSelect
    Select,
    on
  });

But when the project is built with the rollup, imports can be renamed. For example, Select can be renamed to Select$1, as shown in the following example.

import Select from '../different/select.js';
import Select$1 from '../select.js';

precompileTemplate(`
    <RootSelect/>
    <Select/>
    <button {{on "click" this.toogleClicked}}>
      {{#if this.isClicked}}
        Clicked
      {{else}}
        Not clicked
      {{/if}}
    </button>
  `, {
  strictMode: true,
  scope: () => ({
    RootSelect: Select
    Select: Select$1,
    on
  });

From a javascript point of view, everything is correct, and both examples are equivalent. But the second example will fail with an error.

I have created a simple example where you can see how an import is renamed by rollup and then there is a problem

Solution

When a GJS component is built in V2 addon, there is precompileTemplate function in the file in the dist dir. Imported components used in scope can be renamed by Rollup and then properties have different keys and values as shown below:

import Select from '../different/select.js';
import Select$1 from '../select.js';

precompileTemplate(`
    <RootSelect/>
    <Select/>
    <button {{on "click" this.toogleClicked}}>
      {{#if this.isClicked}}
        Clicked
      {{else}}
        Not clicked
      {{/if}}
    </button>
  `, {
  strictMode: true,
  scope: () => ({
    RootSelect: Select,
    Select: Select$1,
    on
  })

When the application is built, the ember-auto-import loads V2 addons with babel-plugin-hbmlbars-inline-precompile and replaces the precompileTemplate with _createTemplateFactory as shown below:

import Select from '../different/select.js';
import Select$1 from '../select.js';

_createTemplateFactory({
      "id":"4QKqJqnE",
      "block":"[[[1,\\"\\\\n    \\"],[8,[32,0],null,null,null],[1,\\"\\\\n    \\"],[8,[32,1],null,null,null],[1,\\"\\\\n    \\"],[11,\\"button\\"],[4,    [32,2],[\\"click\\",[30,0,[\\"toogleClicked\\"]]],null],[12],[1,\\"\\\\n\\"],[41,[30,0,[\\"isClicked\\"]],[[[1,\\"        Clicked\\\\n\\"]],[]],[[[1,\\"        Not clicked\\\\n\\"]],[]]],[1,\\"    \\"],[13],[1,\\"\\\\n  \\"]],[],false,[\\"if\\"]]",
      "moduleName":"(unknown template module)",
      "scope":()=>[RootSelect,Select,on],
      "isStrictMode":true
})

The problem is that the scope arrow function returns the original names of the properties. It can be solved by wrapping glimmer wire format in a closure function shown below:

import Select from '../different/select.js';
import Select$1 from '../select.js';

_createTemplateFactory(
    ((RootSelect, Select, on)=>
    ({
      "id":"4QKqJqnE",
      "block":"[...]",
      "moduleName":"(unknown template module)",
      "scope":()=>[RootSelect,Select,on],
      "isStrictMode":true
    }))(Select, Select$1, on)
)

@candunaj candunaj marked this pull request as ready for review March 21, 2023 13:38
@candunaj candunaj changed the title [WIP] Added test for scope with renamed import [WIP] precompileTemplate with scope that has properties different key and value Mar 23, 2023
@candunaj candunaj changed the title [WIP] precompileTemplate with scope that has properties different key and value [WIP] precompileTemplate with scope that has properties with different key and value Mar 23, 2023
@candunaj candunaj force-pushed the precompile-template-scope-renamed-import branch from cd1aa7f to eaf8682 Compare March 23, 2023 14:25
@meirish
Copy link

meirish commented Mar 23, 2023

🤩 awesome! I ran into this a few weeks ago and had to experiment with named exports to get things working properly.

@wagenet
Copy link

wagenet commented Mar 24, 2023

This is considered legacy, so we probably shouldn't be doing fixes here. The reason why this problem got hit was due to embroider-build/ember-auto-import#573.
The fix for the newer one is here: emberjs/babel-plugin-ember-template-compilation#17.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants