Skip to content

[QUEST] Module Unification: Final Cut #16373

@mixonic

Description

@mixonic

Throughout 2017 a small crew has pushed forward the implementation of Ember's new filesystem layout for applications and addons. This was described in RFC 143 and we've lovingly called the effort "module unification".

Much of the effort up to now has been either design or exploration-heavy. It wasn't plausible to reduce the work list into things that individual contributors could pick up without context.

But in the last weeks we have turned a corner. Our effort is behind three feature flags in Ember, Ember CLI, and ember-resolver. In order to enable these flags by default for new applications, we need your help. In this quest issue I've outlined the current list of known blockers as well as guidance for how to test the new features in new and migrated codebases.

Several contributors have been huddled in #st-module-unification on the Ember.js Community Slack in recent months. Please join us there when you start to pick up one of these tasks.

The Issue List

Ember.js

  • In the Ember.js PR that landed namespaces behind a feature flag, we implemented parsing of {{namespace::name}} strings at runtime. This implementation should be improved to have this work happen at Ember app build time.
  • Before advocating to "go" the feature, we want to get benchmarks (via https://github.com/krisselden/ember-macro-benchmark and https://github.com/eviltrout/ember-performance) to confirm there isn't an unexpected large regression. The changes to implement these features are not expected to improve Ember's performance, but we should understand the impact.

Ember CLI

  • Ember CLI uses the presence of src/ to configure the return value of isModuleUnification(). This works well for apps and addons. The detection fails for a classic dummy app in a module unification addon, however. Although a dummy app may be in tests/dummy/app/ with no tests/dummy/src/ directory, the addon's root level src/ confuses our logic and the dummy app is incorrectly treated as a module unification app.
  • Requires design: An ember addon author may want two dummy apps for testing, a module unification src/ app and a classic app/ app. Their acceptance tests would run with both apps, or they could have two acceptance test suites.
  • Module Unification blueprints and generators, mostly tracked at: Module Unification: Blueprints ember-cli/ember-cli#7530
  • ember-maybe-import-generator-for-testing needs to apply to tests in src directory, see https://github.com/ember-cli/ember-maybe-import-regenerator-for-testing
  • If a classic app is running a version of Ember CLI that pre-dates module unification support, then an addon using module unification (with a src/ directory)must have a way a) fail gracefully or b) bring the reexport logic we use in ember-cli with it to the old version of ember-cli.
  • Module unification addons re-export their top level components to app/ for classic apps. This allows an addon author to use a src/ directory and still have their addon work for either kind of app. We would like to provide addons a build-time way to configure this re-export logic. It would permit them to re-name components and services to match legacy classic APIs while they adopt new APIs for module unification apps.
  • Ember addons need an API that allows them to alter the module unification config (for example https://github.com/ember-cli/ember-resolver/blob/master/mu-trees/addon/ember-config.js) and add their own collections and types. In theory Ember (or the resolver?) would use this same API to add its own types and collections.
  • Fix lib/models/project.js's isModuleUnification method to not only rely on presence of top level src as "the project is module unification format". Specifically, an addon may be in module unification format, but have its dummy app be in classic format.

Ember Template Compiler

  • hbs helpers should accept a source argument like templates in a running app do. In: https://github.com/ember-cli/ember-cli-htmlbars-inline-precompile
  • Part of the hbs AST transform should be to inline the source value. However test files for a private collection, local lookup component might not be able to use the "easy" value of their filename and still have access to resolve their subject. For example in src/ui/routes/application/-component/foo-bar/component-test.js templates created with hbs will not be able to access the {{foo-bar}} component. The simplest solution here is to pass a source to these hbs templates that is "one level up", for example the source for templates in the test file would be src/ui/routes/application. There are some tradeoffs in taking this or other approaches, but it seems like a good place to start. Allowing you to test templates from MU co-located tests ember-cli/babel-plugin-htmlbars-inline-precompile#33

Ember Resolver

Migrator

ember-svg-jar

ember-load-initializers

Several contributors have been huddled in #st-module-unification on the Ember.js Community Slack in recent months. Please join us there when you start to pick up one of these tasks.

Creating a new module unification app

Install Ember CLI master:

npm install -g https://github.com/ember-cli/ember-cli.git

Generate a new app with the module unification env variable:

MODULE_UNIFICATION=true EMBER_CLI_MODULE_UNIFICATION=true ember new my-app

Out of the box a newly generated application will use the ember-resolver "fallback" resolver. This allows the module unification app to use classic app/ addons. Much later, once we've converted the default addons that ship with new Ember apps, we can drop the "fallback" resolver and use the MU-only "glimmer wrapper" resolver.

The implementation of module unification uses a configuration of collections and types. In the classic addon app/ layout, addons could define new types of factories without any explicit definition. Before removing the feature flags we need an API for them to explicitly do so against the module unification config. Temporarily you may want to mutate the config for your app to add a type, for example in src/resolver.js.

If you have an issue after generating a new application you can likely find or file an issue:

Migrating an existing Ember app

Install the module migrator:

npm install -g ember-module-migrator jscodeshift

Run the migrator on your app codebase:

cd ~/project/path
ember-module-migrator

Install Ember CLI master:

npm install --save-dev https://github.com/ember-cli/ember-cli.git

And update your files to match the latest blueprint, similar to what you do for any upgrade:

ember init

You'll want to:

  • Keep the ember-resolver feature flag in config/environment.js.
  • Keep the Ember.js feature flag in config/environment.js.
  • Keep the canary version of Ember.js in package.json.
  • Keep the addition of loadInitializers in src/main.js. There are two of these lines, one for src/ and one for classic addons exporting into app/.
  • Keep the change to the fallback resolver in src/resolver.js.
  • Keep the change to import the app from ../src/main in test-helper.js.

If you have an issue after migrating an application you can likely find or file an issue:

Creating a new module unification addon

Install Ember CLI master:

npm install -g ember-cli/ember-cli#master

Generate a new app with the module unification env variable:

MODULE_UNIFICATION=true ember addon my-addon

You can find a file issues for the experience of building an addon:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions