Start Date Release Date Release Versions PR link Tracking Link Stage Teams
12/15/2023
Accepted
  • CLI
  • Framework
  • Learning
  • TypeScript

Deprecate non-co-located components.

Summary

Deprecates

  • classic component layout
  • pods component layout

Once this deprecation is implemented, only the following will be allowed:

  • co-located components
  • gjs / gts components

Motivation

These older component layouts force build tooling to keep a lot of resolution rules around, and makes it hard for codemods and other community tooling to effectively work across folks' projects.

Transition Path

There are two types of paths to migrate off the old layouts

  • use a currently supported multi-file layout (keeping separate js, ts, and hbs files)
  • migrate the component entirely to the latest component format, gjs, gts, (aka <template>)

There are some tools to help with this:

Specifically, these layouts are no longer supported

Classic

{app,addon}/
  components/
    foo.js
    namespace/
      bar.js
  templates/
    components/
      foo.hbs
      namespace/
        bar.hbs

Pods' Component layout.

{app,addon}/
  components/
    foo/
      component.js
      template.hbs
    namespace/
      bar/
        component.js
        template.hbs

The above example(s) could fairly easily be migrated (by users) to:

{app,addon}/
  components/
    foo.js 
    foo.hbs
    namespace/
      bar.js
      bar.hbs

Or using component-structure=nested

{app,addon}/
  components/
    foo/
      index.js 
      index.hbs
    namespace/
      bar/
        index.js
        index.hbs

Note, however, that classic components importing the layout and setting it on an @ember/component will still work. The key thing being deprecated is the runtime resolution of templates, so if there is an import involved, there is no runtime resolution.

ember-source

The blueprint for components will need to remove the classic option:

Here is the output at the time of authoring this RFC:

pnpm ember g component --help
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, -pods
  --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>
  --lint-fix (Boolean) (Default: true)
  --in (String) (Default: null) Runs a blueprint against an in repo addon. A path is expected, relative to the root of the project.
  --typescript (Boolean) Generates a version of the blueprint written in TypeScript (if available).
    aliases: -ts

      component <name> <options...>
        Generates a component.
        --path (String) (Default: components)
          aliases: --no-path (--path="")
        --component-class (@ember/component, @glimmer/component, @ember/component/template-only, "") (Default: --no-component-class)
          aliases: -cc (--component-class=@ember/component), -gc (--component-class=@glimmer/component), -tc (--component-class=@ember/component/template-only), -nc (--component-class=""), --no-component-class (--component-class=""), --with-component-class (--component-class=@glimmer/component)
        --component-structure (flat, nested, classic) (Default: flat)
          aliases: -fs (--component-structure=flat), -ns (--component-structure=nested), -cs (--component-structure=classic)

Specifically, we'll remove:

  • --component-structure=classic and its alias

How We Teach This

Guides and docs already don't mention the above old layouts.

Deprecation Guide

component templates in templates/components

Before

{app,addon}
  components/
    demo.js
  templates/
    components/
      demo.hbs

After

{app,addon}
  components/
    demo.js
    demo.hbs

After (gjs)

{app,addon}
  components/
    demo.gjs

Pods

Before

{app,addon}
  components/
    demo/
      component.js
      template.hbs

After

{app,addon}
  components/
    demo/
      index.js
      index.hbs

After (non-nested)

{app,addon}
  components/
    demo.js
    demo.hbs

After (gjs)

{app,addon}
  components/
    demo.gjs

Drawbacks

If upgrading to ember v6 without any changes,

  • Some super old addons may break
  • Some super old apps may break

In either case, it's been ~4 years since co-located components were introduced, and the deprecation will give folks actionable information for how to move forward (ideally with a link to the deprecation site which can then link to tools folks can try).

Alternatives

none

Unresolved questions

none