From 28a22c5e1da360edd66b2369cea1c8afd6d6c7f3 Mon Sep 17 00:00:00 2001 From: Chad Hietala Date: Fri, 3 Apr 2015 10:07:09 -0700 Subject: [PATCH 1/3] Route driven project structure --- active/0003-route-project-structure.md | 153 +++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 active/0003-route-project-structure.md diff --git a/active/0003-route-project-structure.md b/active/0003-route-project-structure.md new file mode 100644 index 0000000000..af79fae73f --- /dev/null +++ b/active/0003-route-project-structure.md @@ -0,0 +1,153 @@ +- Start Date: 04/03/2015 +- RFC PR: (leave this empty) +- ember-cli Issue: (leave this empty) + +# Route Driven Pod Structure + +Have pods become the default file structure that reflect the hierarchy of the application. + +# Motivation + +Pods are a great way of splitting applications apart into functional sets, however in their current form they have several problems. The largest of those problems is findability of files. + +### Findability + +Files in pods are named after their type and not the name of the type e.g. `my-component/component.js` vs. `components/my-component.js`. Having tens of files called `component.js` is extremely difficult to search for and is also cumbersome when working with multiple `component.js` files. For instance below is an example of having 4 different components open at the same time. + +![](http://i.imgur.com/wgwKUJa.png) + +A developer has to preform so much context switching just to ensure they are working in the correct file. + +Searching for files has the same problem of scanability of the file names. + +![](http://i.imgur.com/m2wv5Fs.png) + +### Alignment With Routable Components + +Looking at the existing pod structure it does not align well the mental model of routable components. + +# Detailed design + +To address the existing shortcomings of pods, a new default structure needs to be introduced. For the most part, this new structure is more semantic and is in the same of vein as "if your url is nested, your ui is nested". See the below sample structure. + + +``` +app +├── routes +│   ├── profile +│   │   ├── components +│   │   │   ├── member-photo.js +│   │   │   └── member-connections.js +│   │   ├── styles +│   │   │   ├── member-photo.scss +│   │   │   └── member-connections.scss +│   │   ├── templates +│   │   │   ├── member-photo.hbs +│   │   │   └── member-connections.hbs +│   │   ├── edit +│   │   │   ├── components +│   │   │   │   └── edit-name.js +│   │   │   ├── templates +│   │   │   │   └── edit-name.hbs +│   │   │   ├── styles +│   │   │   │   └── edit-name.scss +│   │   │   └── profile-edit.js +│   │   └── profile.js +│   └── admin +│   ├── components +│   │   └── member-permissions.js +│   ├── templates +│   │   └── member-permissions.hbs +│   ├── styles +│   │   └── member-permissions.scss +│   └── admin.js +├── helpers +│   └── format-date.js +├── initializers +│   └── tracking.js +├── services +│   └── tracking.js +├── utils +│   └── fib.js +├── shared +│   ├── components +│   │   └── dropdown-menu.js +│   ├── templates +│   │   └── dropdown-menu.hbs +│   └── styles +│   └── dropdown-menu.scss +├── app.js +└── router.js + +``` + +The largest change here is that `routes` is where majority of your application lives. In Ember applications, everything is organized and flows from the routes. Because of this it's fitting that routes map back to the project structure. When your project is organized around the routes several things fall out of this. + +- A happy path to coarse bundling of the application + - This can be thought as an intermediate step towards engines. +- Automatic namespacing of components +- Discrete workspaces for larger teams + + +## Coarse Bundling + +With a route centric structure, projects can very easily be bundled into coarse bundles. For instance the sample structure described above can very easily be built into the following files. + +``` +dist +├── routes +│   ├── profile +│   │   ├── profile.js +│   │   └── profile.css +│   └── admin +│   ├── admin.css +│   └── admin.js +└── app.js + +``` + +In this case `app.js` is everything that is top level sans the `routes` directory. The reason behind this is that these constructs are application agnostic and no nothing about the overall structure of the application. + +In an engines world the directories in the `routes` folder can be looked as mountable entry points to the hosting application. + + +## Automatic Namespacing + +As of Ember 1.10.0, components can be nested we have the ability to namespace modules based on the route in which the component is contained in. For example, using the `member-photo` component would look like the following. + +``` + +``` + +For nested routes you would simply extend the namespace to incorporate the nested route. + +``` + +``` + +The convention for components that need to span across more than 1 route is to place them within the `shared` directory. The shared directory is bundled into `app.js` and is not namespaced as it can appear anywhere in the application. + +``` + +``` + +## Custom Resolver + +To enable this type of structure we will need to create a custom resolver and introduce the concept of `@` symbol based namespaces. + + +# Drawbacks +This will be introducing another directory structure and would have to come up with a migration plan if this becomes the default structure. + +Because this structure follows the "if your url is nested, your ui is nested" convention, it means that you potentially have a folder pyramid of hell. + +We need to have generators be aware of this new structures. + +# Alternatives + +Robert Jackson has a [proposal](https://github.com/rwjblue/container-resolver-namespaces) that talks about namespaces, so he may have other ideas. + +# Unresolved questions + +- `@` symbol namespace resolution +- Where do fragments fit in? From cacfdcb35118787445c295e75b3f3ed268832c04 Mon Sep 17 00:00:00 2001 From: Chad Hietala Date: Fri, 3 Apr 2015 16:01:26 -0700 Subject: [PATCH 2/3] Update to accommodate files grouped togeather Based on the communities feedback we want to have the template, js, and styles grouped togeather in a single folder. The only option that makes since to keep this feature is to have repetition in files and folders on disk. While verbose this solution achieves the findability issue and keeps the spirit of the original "pods". --- active/0003-route-project-structure.md | 51 +++++++++++++------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/active/0003-route-project-structure.md b/active/0003-route-project-structure.md index af79fae73f..7dd9f23c0a 100644 --- a/active/0003-route-project-structure.md +++ b/active/0003-route-project-structure.md @@ -35,31 +35,26 @@ To address the existing shortcomings of pods, a new default structure needs to b app ├── routes │   ├── profile -│   │   ├── components +│   │   ├── member-photo +│   │   │   ├── member-photo.hbs │   │   │   ├── member-photo.js -│   │   │   └── member-connections.js -│   │   ├── styles -│   │   │   ├── member-photo.scss +│   │   │   └── member-photo.scss +│   │   ├── member-connections +│   │   │   ├── member-connections.hbs +│   │   │   ├── member-connections.js │   │   │   └── member-connections.scss -│   │   ├── templates -│   │   │   ├── member-photo.hbs -│   │   │   └── member-connections.hbs │   │   ├── edit -│   │   │   ├── components -│   │   │   │   └── edit-name.js -│   │   │   ├── templates -│   │   │   │   └── edit-name.hbs -│   │   │   ├── styles -│   │   │   │   └── edit-name.scss -│   │   │   └── profile-edit.js +│   │   │ ├── edit-name +│   │   │ │   ├── edit-name.hbs +│   │   │ │   ├── edit-name.js +│   │   │ │   └── edit-name.scss +│   │   │ └── profile-edit.js │   │   └── profile.js │   └── admin -│   ├── components -│   │   └── member-permissions.js -│   ├── templates -│   │   └── member-permissions.hbs -│   ├── styles -│   │   └── member-permissions.scss +│      ├── member-permissions +│      │   ├── member-permissions.hbs +│      │   ├── member-permissions.js +│      │   └── member-permissions.scss │   └── admin.js ├── helpers │   └── format-date.js @@ -70,12 +65,10 @@ app ├── utils │   └── fib.js ├── shared -│   ├── components -│   │   └── dropdown-menu.js -│   ├── templates -│   │   └── dropdown-menu.hbs -│   └── styles -│   └── dropdown-menu.scss +│   ├── dropdown-menu +│   │   ├── dropdown-menu.js +| | ├── dropdown-menu.scss +│   └── └── dropdown-menu.hbs ├── app.js └── router.js @@ -88,6 +81,10 @@ The largest change here is that `routes` is where majority of your application l - Automatic namespacing of components - Discrete workspaces for larger teams +## Resolution + +The resolution of components and nested-routes is a tiered/fallback approach much like the current pattern in JJ Abrams Resolver. Routes take precedence over over components. + ## Coarse Bundling @@ -110,6 +107,8 @@ In this case `app.js` is everything that is top level sans the `routes` director In an engines world the directories in the `routes` folder can be looked as mountable entry points to the hosting application. +Since you can have nested components sitting the same level, routes once again take precedence over components. + ## Automatic Namespacing From 1e5c3f390557c45bb39648d81dfcc333eeb455b6 Mon Sep 17 00:00:00 2001 From: Chad Hietala Date: Fri, 3 Apr 2015 16:26:54 -0700 Subject: [PATCH 3/3] Adding -route extension --- active/0003-route-project-structure.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/active/0003-route-project-structure.md b/active/0003-route-project-structure.md index 7dd9f23c0a..ef6ee2f6d5 100644 --- a/active/0003-route-project-structure.md +++ b/active/0003-route-project-structure.md @@ -48,14 +48,14 @@ app │   │   │ │   ├── edit-name.hbs │   │   │ │   ├── edit-name.js │   │   │ │   └── edit-name.scss -│   │   │ └── profile-edit.js -│   │   └── profile.js +│   │   │ └── profile-edit-route.js +│   │   └── profile-route.js │   └── admin │      ├── member-permissions │      │   ├── member-permissions.hbs │      │   ├── member-permissions.js │      │   └── member-permissions.scss -│   └── admin.js +│   └── admin-route.js ├── helpers │   └── format-date.js ├── initializers