Git Product home page Git Product logo

ember-engines's Introduction

ember-engines npm version Build Status

This Ember addon implements the functionality described in the Ember Engines RFC. Engines allow multiple logical applications to be composed together into a single application from the user's perspective.

Packages

This project is a monorepo managed by pnpm workspaces. All packages are organized in the /packages/ directory.

The only public package is ember-engines. Other packages are private to this repo and are used to support testing ember-engines.

Documentation

Check the full documentation in the Ember Engines Guides.

Support

Having trouble? Join #ember-engines on the Ember Community Discord server

Contributing

See the Contributing guide for details.

License

Copyright 2015-2022 Dan Gebhardt, Michael Villander and Robert Jackson. MIT License (see LICENSE.md for details).

ember-engines's People

Contributors

2hu12 avatar bertdeblock avatar bobrimperator avatar brendenpalmer avatar buschtoens avatar chadhietala avatar dependabot[bot] avatar dgeb avatar ef4 avatar elwayman02 avatar jbailey4 avatar josex2r avatar kiwiupover avatar knownasilya avatar krisselden avatar mdebbar avatar mgmarcum avatar mike183 avatar nadavshatz avatar nathanhammond avatar nlfurniss avatar rwjblue avatar sduquej avatar sergeastapov avatar stefanpenner avatar thoov avatar trentmwillis avatar villander avatar void-malex avatar xg-wang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ember-engines's Issues

Engine Discovery

A feature that numerous people are discussing is to have a host application be able to "discover" available engines to lazy load. This is a multi-step process:

  1. We must define an engine bundle format.
  2. We must support lazily-loaded engines that are fully-defined at build time with the client already aware of the engines.
  3. We must define a way to advertise available engines.
  4. We must create a way to inject the advertised engines into the host application.

Known issues that must be solved (known unknowns):

  • Deep linking (currently solved at build time by propagating all routes to the top).
  • How should this play with the {{mount}} keyword?
  • How should this handle nested engines?
  • Security.
  • ???

Moving toward a solution to this problem should focus initially on getting us to lazy-loading, but we should keep this in the back of our minds so as not to paint ourselves into a corner.

/cc @mike183 @ebryn @MiguelMadero @peStoney @marcemira @trentmwillis

Require wrapping `addon/routes.js` default export to allow upgradability.

As we learned the hard way in the Ember 1.x series, having plain functions being exported can become quite painful from a compatibility perspective. I would prefer to avoid the mistakes we made with Handlebars helpers, and require that the routes file be wrapped in a helper function so that we have a way to handle compatibility concerns with any future refactors.

import buildRoutes from 'ember-engines/routes';

export default buildRoutes(function() {
  this.route('foo');
  this.route('bar');
});

Update ember-resolver addon to use `resolveEngine`.

For now, apps that consumes engines must use the ember-engines/resolver module instead of ember/resolver or ember-resolver. Once we are confident in the resolveEngine implementation added in #9 we should push those changes upstream into ember-resolver (possibly after publishing a beta version of this addon). Then we can remove addon/resolver.js.

Support Lazy Loading engines

So in the readme it's mentioned that this is coming soon. I'm wondering how this will work, since it seems like you have some ideas already.

Engine Routes with dynamic segments cannot be linked from the consuming app.

Example Setup

Engine routes.js

  this.route('foo', { path: '/:id'});

App router.js

this.mount('<some-engine>', { as: 'my-engine', path: 'baz'});

App application.hbs

{{#link-to 'my-engine.foo' 1}} Link to Foo (1) {{/link-to}}

Example Error

ember.debug.js:18694 Error: Assertion Failed: You used the dynamic segment id in your route foo, but <app-name>.Foo did not exist and you did not override your route's `model` hook.
    at new Error (native)
    at Error.EmberError (http://localhost:4200/assets/vendor.js:33145:21)
    at assert (http://localhost:4200/assets/vendor.js:21159:13)
    at Object.assert (http://localhost:4200/assets/vendor.js:32957:34)
    at Object.find (http://localhost:4200/assets/vendor.js:43463:28)
    at model (http://localhost:4200/assets/vendor.js:152988:32)
    at _emberRuntimeSystemObject.default.extend.deserialize (http://localhost:4200/assets/vendor.js:43430:19)
    at Object.applyHook (http://localhost:4200/assets/vendor.js:79140:30)
    at Object.HandlerInfo.runSharedModelHook (http://localhost:4200/assets/vendor.js:77329:33)
    at Object._routerUtils.subclass.getModel (http://localhost:4200/assets/vendor.js:77245:19)

cli error executing ember h g

Hey guys, I just tried to look at the cli's generate help after installing ember-engines and I got this:

$ ember h g
Requested ember-cli commands:

ember generate <blueprint> <options...>
  Generates new code from blueprints.
  aliases: g
  --dry-run (Boolean) (Default: false)
    aliases: -d
  --verbose (Boolean) (Default: false)
    aliases: -v
  --pod (Boolean) (Default: false)
    aliases: -p
  --classic (Boolean) (Default: false)
    aliases: -c
  --dummy (Boolean) (Default: false)
    aliases: -dum, -id
  --in-repo-addon (String) (Default: null)
    aliases: --in-repo <value>, -ir <value>

Cannot find module 'ember-cli/blueprints/route/index'
Error: Cannot find module 'ember-cli/blueprints/route/index'
    at Function.Module._resolveFilename (module.js:339:15)
    at Function.Module._load (module.js:290:25)
    at Module.require (module.js:367:17)
    at require (internal/module.js:16:19)
    at Object.<anonymous> (/path/to/my/project/node_modules/ember-engines/blueprints/in-repo-engine/index.js:5:13)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)

this is my package.json:

{
  "name": "my-app",
  "version": "0.0.0",
  "description": "Small description for my-app goes here",
  "private": true,
  "directories": {
    "doc": "doc",
    "test": "tests"
  },
  "scripts": {
    "build": "ember build",
    "start": "ember server",
    "test": "ember test"
  },
  "repository": "",
  "engines": {
    "node": ">= 0.10.0"
  },
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "broccoli-asset-rev": "^2.4.2",
    "ember-ajax": "^2.0.1",
    "ember-cli": "2.6.0-beta.2",
    "ember-cli-app-version": "^1.0.0",
    "ember-cli-babel": "^5.1.6",
    "ember-cli-dependency-checker": "^1.2.0",
    "ember-cli-fastboot": "^1.0.0-beta.1",
    "ember-cli-htmlbars": "^1.0.3",
    "ember-cli-htmlbars-inline-precompile": "^0.3.1",
    "ember-cli-inject-live-reload": "^1.4.0",
    "ember-cli-jshint": "^1.0.0",
    "ember-cli-postcss-fixed": "0.0.6",
    "ember-cli-qunit": "^1.4.0",
    "ember-cli-release": "0.2.8",
    "ember-cli-sri": "^2.1.0",
    "ember-cli-uglify": "^1.2.0",
    "ember-data": "^2.6.0-beta.1",
    "ember-engines": "0.2.2",
    "ember-export-application-global": "^1.0.5",
    "ember-load-initializers": "^0.5.1",
    "ember-network": "0.3.0",
    "ember-resolver": "^2.0.3",
    "ember-responsive": "1.2.6",
    "ember-truth-helpers": "1.2.0",
    "liquid-fire": "0.23.1",
    "loader.js": "^4.0.1"
  },
  "ember-addon": {
    "paths": [
      "lib/engine-main",
      "lib/engine-dashboard"
    ]
  },
  "dependencies": {
    "autoprefixer": "^6.3.6",
    "postcss-cssnext": "^2.5.2",
    "postcss-import": "^8.1.2"
  }
}

Support routeable engines via route map

  • Separate routing map from router
  • mount method in route map definition
  • Enable components from the engine's addon/ dir to be invocable from the addon's route templates.
  • Enable deep linking across engine boundaries

Can't resolve components for integration tests

When I run ember g component foo-component, it generates a file within the addon and app directories. When I try to run the generated test, it fails, saying it can't find the module. When I delete the component from the app directory (since it's my understanding an engine shouldn't have an app directory in the first place), the test interprets the component as a helper and says it can't be found.

I've only encountered this issue with components so far, not sure if the same thing happens with routes, models, etc.

Are there issues with tests at this point, or is there something I'm missing? Thank you!

[npm 05/13/16 2:49:44] not ok 40 PhantomJS 2.0 - Integration | Component | foo component: it renders
[npm 05/13/16 2:49:44]     ---
[npm 05/13/16 2:49:44]         actual: >
[npm 05/13/16 2:49:44]             null
[npm 05/13/16 2:49:44]         stack: >
[npm 05/13/16 2:49:44]              at missingModule (http://localhost:7357/assets/vendor.js:180:93)
[npm 05/13/16 2:49:44]              at findModule (http://localhost:7357/assets/vendor.js:194:30)
[npm 05/13/16 2:49:44]              at reify (http://localhost:7357/assets/vendor.js:124:32)
[npm 05/13/16 2:49:44]              at build (http://localhost:7357/assets/vendor.js:144:15)
                                    ...
[npm 05/13/16 2:49:44]         message: >
[npm 05/13/16 2:49:44]             Died on test #1  at testWrapper (http://localhost:7357/assets/test-support.js:6645:16)
[npm 05/13/16 2:49:44]              at test (http://localhost:7357/assets/test-support.js:6658:44)
[npm 05/13/16 2:49:44]              at http://localhost:7357/assets/tests.js:111:24
[npm 05/13/16 2:49:44]              at exports (http://localhost:7357/assets/vendor.js:93:39)
[npm 05/13/16 2:49:44]              at build (http://localhost:7357/assets/vendor.js:145:17)
[npm 05/13/16 2:49:44]              at findModule (http://localhost:7357/assets/vendor.js:196:14)
[npm 05/13/16 2:49:44]              at requireModule (http://localhost:7357/assets/vendor.js:184:22)
[npm 05/13/16 2:49:44]              at require (http://localhost:7357/assets/test-loader.js:67:16)
[npm 05/13/16 2:49:44]              at loadModules (http://localhost:7357/assets/test-loader.js:58:25)
[npm 05/13/16 2:49:44]              at load (http://localhost:7357/assets/test-loader.js:89:35)
[npm 05/13/16 2:49:44]              at http://localhost:7357/assets/test-support.js:6477:20: Could not find module `testmanager-engine/components/foo-component` imported from `dummy/components/foo-component`
[npm 05/13/16 2:57:23] not ok 40 PhantomJS 2.0 - Integration | Component | foo component: it renders
[npm 05/13/16 2:57:23]     ---
[npm 05/13/16 2:57:23]         actual: >
[npm 05/13/16 2:57:23]             null
[npm 05/13/16 2:57:23]         stack: >
[npm 05/13/16 2:57:23]             http://localhost:7357/assets/vendor.js:16524
[npm 05/13/16 2:57:23]         message: >
[npm 05/13/16 2:57:23]             Died on test #2  at testWrapper (http://localhost:7357/assets/test-support.js:6645:16)
[npm 05/13/16 2:57:23]              at test (http://localhost:7357/assets/test-support.js:6658:44)
[npm 05/13/16 2:57:23]              at http://localhost:7357/assets/tests.js:111:24
[npm 05/13/16 2:57:23]              at exports (http://localhost:7357/assets/vendor.js:93:39)
[npm 05/13/16 2:57:23]              at build (http://localhost:7357/assets/vendor.js:145:17)
[npm 05/13/16 2:57:23]              at findModule (http://localhost:7357/assets/vendor.js:196:14)
[npm 05/13/16 2:57:23]              at requireModule (http://localhost:7357/assets/vendor.js:184:22)
[npm 05/13/16 2:57:23]              at require (http://localhost:7357/assets/test-loader.js:67:16)
[npm 05/13/16 2:57:23]              at loadModules (http://localhost:7357/assets/test-loader.js:58:25)
[npm 05/13/16 2:57:23]              at load (http://localhost:7357/assets/test-loader.js:89:35)
[npm 05/13/16 2:57:23]              at http://localhost:7357/assets/test-support.js:6477:20: Assertion Failed: A helper named 'foo-component' could not be found

@Kaceykaso

Allow arguments to `{{mount}}` template keyword and `mount` routing helper

The following was discussed at the Ember Core Team F2F in January:

The {{mount}} template keyword should allow normal handlebars style hash arguments. The router DSL style should also allow some sort of API to supply parameters too.

Still TBD:

  • What API should the mount routing helper support for accepting parameters?
  • Are arguments set directly on the engine instance?
  • How can an engine declare which properties are writeable?

Establish dependency sharing between engines and parents

Relevant details from the RFC:

Dependencies between engines and parents can be defined imperatively or
declaratively.

Imperative dependencies can be defined in an engine's instance initializers.
When an engine is instantiated, the parent property on its EngineInstance is
set to its parent instance (either an ApplicationInstance or
EngineInstance). Since the engine instance is available in the instance
initializer, this parent property can also be accessed. This allows an engine
instance to interrogate its parent, specifically through its RegistryProxy and
ContainerProxy interfaces.

Alternatively, declarative dependencies can be defined on a limited basis. The
initial API will be limited: an engine can define an array of services that it
requires from its parent.

For example, the following engine expects its parent to provide store and
session services:

import Ember from 'ember';

var Engine = Ember.Engine.extend({
  dependencies: {
    services: [
      'store',
      'session'
    ]
  }
});

export default Engine;

The parent application can provide a re-mapping of services from its namespace
to that of the engine via an engines declaration.

In the following example, the application shares its store service directly
with the checkout engine. It also shares its current-user service as the
session service requested by the engine.

import Ember from 'ember';

var App = Ember.Application.extend({
  engines: {
    checkout: {
      dependencies: {
        services: [
          'store',
          {session: 'current-user'}
        ]
      }
    }
  }
});

export default App;

When engines are instantiated, the listed dependencies will be looked up on
the parent and made accessible within the engine.

Note that the engines declaration provides further space to define
characteristics about an engine, such as whether it should be eager or
lazy-loaded, URLs for manifest files, etc.

Determine how to handle query params.

{{link-to 'some-qp-route' (query-param foo='otherThing')}} will need to know the default values to properly generate /some-qp-route or /some-qp-route?foo=otherThing.

I am not sure how exactly to tackle this, but I wanted to notate the concern so we can circle around once we have more fleshed out.

Link out of an engine?

Currently, all transition destinations in a routable engine are automatically relative to the engine's mount point, which makes perfect sense for the common case. As we're considering what our monolith might look like in an engines world, though, it's becoming clear that we have a set of core entities in our domain that most engines are going to want to be able to reference and potentially link out to.

I could imagine exposing the actual names of such engine-external routes via a service or some other dedicated configuration, and then just mocking out simple placeholder routes and pointing to those in the engine's dummy app during testing and isolated development.

To actually transition to these routes, though, we'd need a way to opt out of the automatic prefixing in those specific {{link-to}} and transitionTo() invocations. Is this a use case that makes sense to support?

Could not find module `ember-resolver` imported from `ember-engines/resolver`

Hey everyone, first of all this looks great! At work, I'm about to build an application as part of a larger application, and the "in-repo-addon" option seems really appropriate.

So I followed the readme and tried to create an in-repo-addon for a newly created Ember project, but once everything is fired up with ember server there seems to be an import error. I've pushed my code to a repo for reference: https://github.com/nucleartide/__ember-engines-test

screen shot 2016-01-29 at 12 06 26 pm

Am I doing something wrong?

Ensure reopen mutations happen before instantiation.

  • import 'ember-engines/route-ext';
  • import 'ember-engines/router-ext';
  • import 'ember-engines/engine-ext';
  • import 'ember-engines/engine-instance-ext';
  • import 'ember-engines/keywords/mount';

Currently, these are done in an initializer (here), but that initializer is only ran after an application is created. At some point we plan to disable reopen after any instantiation has occurred so we should try to ensure these happen before any instances have been created.

paramsFor does not work properly with queryParams on page load.

EDIT: Simplifying the use case

routes/search.js

    model(params) {
      return params; // params are empty, params should be { keywords: 'foo' }
    }

Go to /search?keywords=foo

I'm looking for the origin of the bug, but figured I'd post it if anyone has any ideas.

Component fails to re-render when used with bound value in Engine

Issue: When using a component in an Engine (either routeless or routable as far as I can tell) with a bound value, if you try to re-render it by modifying the bound value, the re-render will fail with an error like:

Uncaught Error: Assertion Failed: A helper named '<component-name>' could not be found

Potential Cause: After a good amount of digging, it appears that when the re-render occurs the lookups are done in the context of the consuming application and not the engine. Thus, this error makes sense as the component won't be found and the application will fall back to trying to lookup a helper of the same name (which will also not be found).

Obviously, this is not the intended behavior and the re-render of a component should occur in the same context as the original render. However, my knowledge of the rendering internals in Ember is not very good, so I didn't make much progress on any actual solution.

Repro: I've put together a simple reproduction of the issue on the re-render branch of my fork. If you start that up and visit the routable-engine-demo/blog route, the error will occur.

cc @nathanhammond @rileyhilliard

Broken on latest canary

Looks like something broke for this addon when using the latest version of Ember Canary. Components aren't rendered within an Engine, but no error is given. I would've opened an issue on Ember proper, but I have no clue what the root cause is.

Determine how to handle Route#serialize.

When a given route in an engine is being linked to, that routes #serialize method (see API docs) is responsible for translating the provided model/object into the URL.

Example:

export default Ember.Route.extend({
  // use `model.slug` instead of `model.id`
  serialize(model) {
    return { id: model.get('slug') };
  }
});

One possible way to work around this would be to separate the serialization from the route object via a custom route-serializer object (that was a simple function). Might look like this:

// addon/route-serializer/post.js

export function(model) {
  return { id: model.get('slug') };
}

And that file (like addon/routes.js) would be included at all times (aka not-lazily loaded).

[FEAT] An Engine's Application Route should be capable of receiving params.

Example

App router.js

this.mount('my-engine', { as: 'thomas', path: 'the-tank/:id' }); 

Engine application.js

model(params) {
  return this.get('store').find('train', params.id);
}

Use Case

Imagine a group of routes being used in an application like below to encapsulate the behavior and abilities of an office.

< structure-A >

      this.route('office', { path: 'office/:office_id' }, function() {
        this.route('index', { path: '/' });
        this.route('add-employee');
        this.route('employee', { path: '/:employee_id' });
      });

We could utilize this structure to deal with the situation in which more than one entity is capable of
owning an office, or for offices that have no parent. For example.

this.route('organization', { path: 'organization/:id' }, function() {
   // offices with a parent organization
   this.mount(<structure-A>);
});

// ownerless offices
this.mount(<structure-A>);

In this situation, in becomes readily apparent that the application route for an engine is different in behavior from a traditional application route in a full Ember application. Because it is acting as a mount point within a larger structure, it needs to be able to handle the possibility that the structure at that point is dynamic, otherwise we are left with a needless wrapper route and outlet, as well as the need to safeguard the accidental url slip in which someone points to the mount point instead of the child.

We could support this fairly easily, it may even already be intended behavior (see Screenshot).

screen shot 2016-05-11 at 3 53 22 pm

In my own application, I worked around this by changing the Engine's application route deserialize hook like this.

deserialize(params, transition) {
    return this.model(params, transition);
}

A more robust approach that handles the potential of there being a dynamic segment intended for a leaf further into the engine might look like this.

  deserialize(params, transition) {
    let owner = getOwner(this);
    let mountPoint = owner.mountPoint;
    let routeName = this.routeName;
    let paramsForRoute = {};

    if (owner.mountPoint && routeName === 'application') {
      for (let i = 0; i < transition.handlerInfos.length; i++) {
        if (transition.handlerInfos[i].name === mountPoint) {
          paramsForRoute = transition.handlerInfos[i].params;

          return this.model(paramsForRoute, transition);
        }
      }
    }

    return this._super(params, transition);
  }

Enable TravisCI.

Now that the repo is public, we should enable CI to ensure PR's a green before merging...

input helper not sending enter/action event to controller

Using in-repo addon right now and trying to execute a simple form that sends an action to a controller upon 'enter'.

The action/enter event from the input helper is not sending to the controller.

{{input type='text' value=chatMessage action="postMessage"}}

{{input type='text' value=chatMessage enter="postMessage"}}

Anyone else face this issue?

Can't resolve component from addon consumed by engine consumed by app

I have a basic engines test app here: https://github.com/JackieChiles/et-app. The app consumes an engine (https://github.com/JackieChiles/et-engine) which in turn consumes an addon (https://github.com/JackieChiles/et-addon) and uses et-component from that addon. The following work:

But I haven't been able to get et-component to render in et-app though a template in the engine at all: https://github.com/JackieChiles/et-engine/blob/master/addon/templates/et-template.hbs#L2

I do see et-addon/components/et-component/component and et-app/components/et-component/component in the resolver's module names list when Ember tries to render that component, but it's looking for et-engine/components/et-component/component.

Is there a piece that I'm missing or is this a possible bug/gap?

best practice for app repo setup with engines?

hi,

is there a recommended best practice for setting an app that is going to use ember engines? We want to have multiple applications and use engines to tie them together, but we don't know if we should have a single repo or multiple repos. I think we would prefer a single repo because it can be easier to deal with.

thx!

Questions about workflow

Hey all, I just had some questions about how to develop engines:

  1. Within an in-repo addon/engine, would I be able to use ember-cli to generate framework entities (like components, templates, etc.)? Or do I have to create new files manually?
  2. How do you test the framework entities in an in-repo addon? I've noticed in other addons that people generally import things into their main app/ directory, so would the tests just exist in the base application and thus outside of the addon/engine?

Thanks!

Missing template compiler

When creating a new engine and I add a template for it i receive the following error: Addon templates were detected, but there are no template compilers registered for....

Update Engines RFC to reflect developments in and lessons from this addon

  • Document {{mount}} keyword
  • Include as option for mount method to allow engine aliases
  • Should we allow arbitrary configuration attributes to be passed from the consuming application to the engine?
  • What is the long term future of this addon? Can it continue to exist by overriding only public methods?
  • Go further in depth into lazy loading issues (e.g. separation of route serializers)
  • Should we remove the section about potential namespaced access to engines from parents?
  • Discuss synergies with routable components

Specifying ember-addon/paths leads to problems during addon discovery

In package.json, we specify paths to the engines used in testing ember-engines:

  "ember-addon": {
    "configPath": "tests/dummy/config",
    "paths": [
      "tests/dummy/lib/ember-chat",
      "tests/dummy/lib/ember-blog"
    ]
  }

When linking to this addon from another project, this causes problems during addon discovery:

$ ember serve

Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
    at AddonDiscovery.<anonymous> (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/lib/models/addon-discovery.js:124:22)
    at Array.map (native)
    at AddonDiscovery.discoverFromDependencies (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/lib/models/addon-discovery.js:109:68)
    at AddonDiscovery.discoverChildAddons (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/lib/models/addon-discovery.js:71:31)
    at Class.Addon.discoverAddons (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/lib/models/addon.js:209:40)
    at Class.Addon.initializeAddons (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/lib/models/addon.js:222:8)
    at setupRegistryForEachAddon (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/node_modules/ember-cli-preprocess-registry/preprocessors.js:18:10)
    at Object.module.exports.setupRegistry (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/node_modules/ember-cli-preprocess-registry/preprocessors.js:46:3)
    at Class.Addon (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/lib/models/addon.js:110:5)
    at new Class (/Volumes/src/dgeb/engines-demo/dummy/node_modules/ember-cli/node_modules/core-object/core-object.js:16:17)

Removing paths means that ember-engines can be used from other projects, but it fails when running its own dummy app and tests.

Ability to declare components as dependencies

We are currently developing a CMS for which the admin panel is an ember.js application. The CMS will allow add-ons to extend the admin panel with new routes, templates etc.

In order to ensure that the add-ons are well encapsulated, each add-on that wanted to extend the admin panel would provide an ember-engine which would then be mounted into the main application.

Our main issue as it currently stands, is the lack of ability to declare components as dependencies of an ember-engine. The main application provides a wide set of components, some implement basic things such as navigation menus, tables, progress bars etc. While others implement more complex functionality such as retrieving sets of data from the CMS and then displaying the data in a way that ensures consistency across the admin panel.

Without the ability to declare components as dependencies, an ember-engine is unable to make use of these components meaning that developing an add-on becomes a much larger and more complex task.

We have seen that the sharing of dependencies other than services from parent applications/engines is something currently under consideration, so we just wanted to put forward this use case for such a feature.

Adding models to a parent engine's `store`.

So let's say you're in child-engine with this dependency chain:

dependencies: {
  services: [
    'store'
  ]
}

The store that is passed in is effectively in parent-engine's scope. If child-engine wishes to extend parent-engine's store with additional available models that is presently only possible by abusing the app folder inside of child-engine.

We need to define a pattern for this behavior as it is almost guaranteed to be an issue.

/cc @Kaceykaso @jwlawrence @cklimkowsky @trentmwillis

Consuming app's resolver not updated by in-repo-engine

Following instructions on docs and used in-repo-engine to generate my engine. Everything is good except for one issue that popped up:

"attempted to mount engine at X, but engine named X could not be found"

Aha!

The generator does not update the Resolver within the app.js of parent application to 'ember-engines/resolver'

Route less engine mounting with a variable

{{mount someVar}} does not work where someVar is a variable with the engine-name

It throws below error:
Uncaught Error: Assertion Failed: The first argument of {{mount}} must be quoted, e.g. {{mount "chat-engine"}}.

Not sure if this constraint is by design or an issue

Mounting an engine before {{outlet}} causes error

In app/templates/application.hbs:

<h2 id="title">Welcome to Ember</h2>
{{#link-to "index"}}Home{{/link-to}}
{{#link-to "boom"}}Click-click{{/link-to}}   <-- link to routable engine
{{mount "mountable-engine"}}
{{outlet}}

causes TypeError: undefined is not an object (evaluating 'node.getState().controller.set')

while everything seems fine if this is the case:

<h2 id="title">Welcome to Ember</h2>
{{#link-to "index"}}Home{{/link-to}}
{{#link-to "boom"}}Click-click{{/link-to}}
{{outlet}}
{{mount "mountable-engine"}}

Documentation shortcomings

So I tried to turn my apps into engines, and I kept struggling with the lack of documentation on several issues:

  • feature flag needed for canary and engines is not mentioned
  • it is not immediately clear that the path to routes.js should be addon/routes.js, had to look into the dummy app
  • the fact that in engine htmlbars should be in dependencies instead of devDependencies is not mentioned. what is going on wrt dependencies/devDependencies in not exactly clear, where should the engine's dependencies go?
  • does engine have its own application route/template/adapters etc, or does it use the ones from parent app?
  • I keep getting "Assertion Failed: A helper named 'title' could not be found" on all helpers coming from addons, even though they work in parent application, and they are also included in engine.
  • if I include addons in parent app, should I also put them in an engine if I need them, will it load twice if I go to the engine, or is the deduplication as mentioned in RFC working yet?
  • does the resolver support namespace lookups as described in RFC? If so, couple of examples in readme would be nice
  • where to put the configuration, how is it merged, which file takes precedence in case of conflict?
  • some best practices would be helpful, e.g. what to put into app/ and what to put into addon/ folders (where to put templates, services, etc), maybe some instructions on how to turn an existing app into engine, couple of lines on what are the key differences between apps, addons and engines, or a bit more complex tutorial?

There is pretty much no documentation on engines except for readme and RFC. Maybe it's just because I'm not an Ember expert yet (haven't written any addon, are they mostly the same thing?), but even small questions like this quickly add up to hours of searching and debugging, hm.

Support URL's in Route#transitionTo?

Currently, we throw an error if the first argument "resembles a URL". Should we change this behavior and allow URL based transitions? What are some use-cases where this is important?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.