NullVoxPopuli / ember-repl

Tools for building playgrounds and repls with and for ember. Useful for interactive styleguides, too
MIT License
13 stars 4 forks source link

ember-compatibility-helpers error on a new app #79

Closed MichalBryxi closed 3 years ago

MichalBryxi commented 3 years ago

What I did:

ember new sandbox
cd sandbox
ember install ember-repl
# npm start complains about incorrect version of ember-auto import
ember install ember-auto-import@2.0.0
# npm start complains about missing webpack
npm install webpack
# create basic demo set of components (see repro repo)
npm start

When I navigate to http://localhost:4200/, I get:

runtime.js:6228 

Error occurred:

- While rendering:
  -top-level
    application

execute @ runtime.js:6228
loader.js:247 Uncaught Error: Could not find module `ember-compatibility-helpers` imported from `@glimmer/component/index`
    at missingModule (loader.js:247)
    at findModule (loader.js:258)
    at Module.findDeps (loader.js:168)
    at findModule (loader.js:262)
    at Module.findDeps (loader.js:168)
    at findModule (loader.js:262)
    at requireModule (loader.js:24)
    at Class._extractDefaultExport (index.js:462)
    at Class.resolveOther (index.js:124)
    at Class.resolve (index.js:185)
MichalBryxi commented 3 years ago

Will try to poke different versions of packages later. Just wanted to document this.

NullVoxPopuli commented 3 years ago

do you have @glimmer/component in `dependencies'?

MichalBryxi commented 3 years ago

🙌 It was in devDependencies and after moving it to dependencies it seems to have fixed this problem.

I can't see any note about that in the README. Would it be reasonable to add it as a note to the installation? Seems like I did nothing wrong when building the bugreport app, so I think this might bite other people as well?

NullVoxPopuli commented 3 years ago

I think this is more about ember's path towards modern packagers -- any dependency directly imported from app code needs to be declared in package.json 🤔 I'm not sure if this would be on ember-auto-import on embroider's readme atm, but those READMEs would be the place to mention it.

Also, if the app blueprint upgrades to ember-auto-import@latest, glimmer-deps being in devDeps in package.json is probably considered a "bug" 🤷

MichalBryxi commented 3 years ago

Re the original problem: Ok, so that did not take me far. I moved @glimmer/tracking to dependencies and got:

runtime.js:6228 

Error occurred:

- While rendering:
  -top-level
    application
      foo

execute @ runtime.js:6228
(anonymous) @ runtime.js:6314
runInTrackingTransaction @ validator.js:154
sync @ runtime.js:6314
(anonymous) @ index.js:7460
(anonymous) @ index.js:7429
(anonymous) @ index.js:7776
inTransaction @ runtime.js:5019
_renderRoots @ index.js:7756
_renderRootsTransaction @ index.js:7808
_renderRoot @ index.js:7743
_appendDefinition @ index.js:7650
appendOutletView @ index.js:7632
invoke @ backburner.js:340
flush @ backburner.js:229
flush @ backburner.js:426
_end @ backburner.js:960
end @ backburner.js:710
_run @ backburner.js:1015
run @ backburner.js:754
run @ index.js:116
callback @ application.js:434
runtime.js:3053 Uncaught Error: Expected a dynamic component definition, but received an object or function that did not have a component manager associated with it. The dynamic invocation was `<this.myComponent>` or `{{this.myComponent}}`, and the incorrect definition is the value at the path `this.myComponent`, which was: Object
    at Object.evaluate (runtime.js:3053)
    at AppendOpcodes.evaluate (runtime.js:1284)
    at LowLevelVM.evaluateSyscall (runtime.js:5177)
    at LowLevelVM.evaluateInner (runtime.js:5133)
    at LowLevelVM.evaluateOuter (runtime.js:5125)
    at VM.next (runtime.js:6257)
    at VM._execute (runtime.js:6241)
    at VM.execute (runtime.js:6211)
    at runtime.js:6314
    at runInTrackingTransaction (validator.js:154)

Tried to move also: webpack, @glimmer/tracking and ember-auto-import, no change.

I also tried to completely remove dynamic parts from the compileHBS call:

  myComponent = compileHBS('Hello World');

Still no luck.

NullVoxPopuli commented 3 years ago

myComponent = compileHBS('Hello World');

this does not return a component by itself -- it returns an object of 3 things:

MichalBryxi commented 3 years ago

I'm starting to understand the bits here. But even with the latest changes no luck with rendering components I defined in my app:

import Component from '@glimmer/component';
import { compileHBS } from 'ember-repl';

export default class FooComponent extends Component {
  // This works:
  // myComponent = compileHBS('Hello World');
  // This does not work:
  myComponent = compileHBS('<Bar />');
}
{{#if this.myComponent.component}}
  <this.myComponent.component />
{{/if}}

It logs error:

Error occurred:

- While rendering:
  -top-level
    application
      foo
        (unknown template-only component)

And:

Uncaught Error: Attempted to use a value as a component, but it was not an object or function. Component definitions must be objects or functions with an associated component manager. The value was: undefined

Logging of myComponent gives me:

{{log this.myComponent.name}}
// ember-repl-ca40d94a-934d-5b1b-b2fe-8a519d2e4aa4

{{log this.myComponent.error}}
undefined

{{log this.myComponent.component}}
// Object { moduleName: "ember-repl-ca40d94a-934d-5b1b-b2fe-8a519d2e4aa4", name: "(unknown template-only component)" }

The component <Bar /> is a single file (no accompanying *.js file) in app/components/bar.hbs. So not sure why it is "unknown"?

From the documentation:

Components without JavaScript, that are based only on a template. These are called Template-only or TO components.

NullVoxPopuli commented 3 years ago

So not sure why it is "unknown"?

ember-repl is strict-mode only, so Bar needs to either be imported (and then use compileGJS), or it needs to be passed to the scope option of compileHBS, for example: https://github.com/NullVoxPopuli/ember-repl/blob/main/tests/rendering/compile-hbs-test.ts#L57

MichalBryxi commented 3 years ago

For future travellers. This works for me:

// Silly import name to emphasize that we now have TemplateOnlyComponentDefinition
import BarTemplate from './bar'; 

export default class FooComponent extends Component {
  myComponent = compileHBS('<Bar />', { scope: { Bar: BarTemplate } });
}
MichalBryxi commented 3 years ago

I will leave my experimental sandbox branch around in case anyone needs reference.