Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate Fallback Lookup Paths in ember-resolver #683

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

gabrielcsapo
Copy link

@gabrielcsapo gabrielcsapo commented Nov 23, 2020

This is a follow up rfc created based on the feedback from issue #661.

rendered text

@gabrielcsapo gabrielcsapo force-pushed the master branch 2 times, most recently from 0fae510 to 0cb29d4 Compare November 23, 2020 21:40
@mydea
Copy link
Contributor

mydea commented Nov 24, 2020

I generally think this is a good idea, my two cents to this:

  • I believe a replacement for pods needs to be defined before doing that. We use pods for route/controller/templates, and would not like to move those to the classic architecture. See: Colocate route+template+controllers #651 - would love to see some traction on that. If there is interest, I would also write up an RFC PR for that issue based on the ideas collected so far in the issue - it kind of quieted down and there was never any input from the core team on how they view the issue.
  • I have tried the mentioned ember-strict-resolver and found a lot of problems with it in our app. Not sure if the idea of this RFC is to use that as basis, but if so, I think there is a lot that needs to be done on that front before it could be recommended. Happy to write up my concrete experiences, if that helps in the context of this PR?

@gabrielcsapo
Copy link
Author

gabrielcsapo commented Nov 24, 2020

@mydea thanks for your reply!

  1. Totally agree there needs to be a pods replacement, the suggestion for moving forward makes this opt in and since the usage of pods seems constrained to host applications they wouldn't be affected. A suggestion came up when talking to @rwjblue was to have a shim for pods (similar to https://github.com/rwjblue/ember-holy-futuristic-template-namespacing-batman) instead of having that in the main resolver. I think a lot of the issues with pods being supported go away when there is an agreed upon spec for template imports.
  2. We had a similar experience, most of the issues came from our dependencies and our host app not having a consistent service or component lookup pattern. I would like to know what problems you experienced if you could do a writeup that would be great.

@mydea
Copy link
Contributor

mydea commented Nov 25, 2020

The main issues I encountered were:

  • Missing pod support (as mentioned)
  • Missing support for nested co-location index components (e.g. app/components/my-component/index.js)
  • Missing pluralization support. Noticed this with ember-can, which has e.g. app/abilitites/my-thing.js, but it wants to look up ability as abilitys. IMHO there should either be support for custom pluralization, or alternatively just do not pluralize unkown types at all - I would be fine with putting these into app/ability/my-thing.js.
  • After I got nested co-location to work, components from addons using non-colocated structure stopped working for me. Had to manually handle those.
  • That I had to manually map all multi-word services was also rather unexpected and annoying.

For reference, here is the extended strict resolver that ended up working with our application. There is for sure some room for improvement, but it shows the steps I took to make it work at least:
https://gist.github.com/mydea/d890f3b83a4bf25b3c3a4f41f6a47e42

@gabrielcsapo
Copy link
Author

Thanks for doing this @mydea

  • I totally agree the lack of pods support is a known and I think would be great to deprecate pods support in favor of a more mainstream javascript solution to take advantage of open source tools without having to code them to understand the pods architecture.
  • I was not aware of the nested index components, what would be the benefit of doing this over the normal naming scheme?
  • Looking at the gist we were able to avoid a lot of the component lookup issues as were already using https://github.com/rwjblue/ember-holy-futuristic-template-namespacing-batman which helped segment our code in in-repo addons very easily.
  • We had many downstream dependencies that we had to update to ensure that the service names were properly dasherized as a result we made a map and slowly removed items from the map to make the process gradual rather than blocking on it.

I think the biggest advantage of having less logic in the resolver is that it feels less magical. The thing that you want is the thing you get and teaching becomes incredibly straightforward. My favorite part of ember is that there is convention over configuration and this feels very conventionally as we lay out a 1:1 one of doing things instead of a many:1.

@mydea
Copy link
Contributor

mydea commented Dec 9, 2020

Having nested components be at app/component/my-component/index can be very helpful when you have a lot of nested components. e.g. Having this:

  • app/compoments/my-component/index.hbs
  • app/components/my-component/sub.hbs

Makes it much easier to see all parts belonging together than e.g.

  • app/components/my-component/sub.hbs
  • ... 50 other folders/components
  • app/components/my-component.hbs

Regarding the services, not sure I follow. All our services are already referenced in dasherized form, but I still need to map them in the resolver as they are somehow internally (?) looked up in camelcase form.

@gabrielcsapo
Copy link
Author

@mydea service lookups should not be transformed in the strict resolver case. If you are getting camel case lookups it is coming from having code that doesn't explicitly set the service name in the inject method.

import { inject as service } from "@ember/service";
@service
fooBar

Instead it should be referenced like:

@service("foo-bar")
fooBar

This was hard to track down until we enabled an internal eslint rule that enforced inject calls to ensure a value was provided as a dasherized string.

@mydea
Copy link
Contributor

mydea commented Dec 9, 2020

Ah OK, that was absolutely not clear to me, and to be honest also is rather surprising. That kind of feels like just adding more friction to every service definition. I guess it is more explicit, but I haven't seen this as a recommendation/best practice so far.

@rwjblue
Copy link
Member

rwjblue commented Dec 9, 2020

That kind of feels like just adding more friction to every service definition

Just to be clear, it is only required for multi-word services.

@gabrielcsapo
Copy link
Author

@rwjblue is there anyone who would be able to review this?

@rwjblue rwjblue added the T-ember-cli RFCs that impact the ember-cli library label Jan 12, 2021
@rwjblue rwjblue self-assigned this Jan 12, 2021
Copy link
Member

@rwjblue rwjblue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I'm definitely in favor of moving in this direction. Thanks for working on this!

text/0683-deprecate-fallback-resolution-ember-resolver.md Outdated Show resolved Hide resolved
text/0683-deprecate-fallback-resolution-ember-resolver.md Outdated Show resolved Hide resolved
text/0683-deprecate-fallback-resolution-ember-resolver.md Outdated Show resolved Hide resolved
text/0683-deprecate-fallback-resolution-ember-resolver.md Outdated Show resolved Hide resolved

The major difference between the two resolvers can be easily linted against:

_It is important to call out that app re-exports are necessary when referencing components coming from an external source or using Wall Street Syntax._
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should not mention "wall street syntax"

text/0683-deprecate-fallback-resolution-ember-resolver.md Outdated Show resolved Hide resolved
> on the integration of this feature with other existing and planned features,
> on the impact of the API churn on existing apps, etc.

A reason to not move the ecosystem forward in this regard is to prioritize technologies that will remove the need for the registry as a sub-system of Ember all-together. Technologies like template imports and reworking the service injection system to not require a resolution mechanic to function.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are moving in this direction, but template imports itself doesn't really solve the issue for all pieces of the system.

transition phase estimated difference -42ms [-57ms to -27ms]
render phase estimated difference -23ms [-37ms to -9ms]

## Detailed design
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section needs to explicitly state what is being proposed. As far as I can tell "strict resolution" is never defined. What does it mean? What would issue a deprecation? What would resolve to various files on disk?

Comment on lines +46 to +54
| Lookup | Ember-resolver | ember-strict-resolver |
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| service/foo‌ ‌ | service:foo‌ ‌ | service:foo‌ ‌ |
| service/foo-bar‌ ‌ | service:foo-bar,‌ ‌service:fooBar‌ ‌ | service:foo-bar‌ ‌ |
| (external-module-name)/addo‌n/services/foo-bar‌ ‌ | service:(external-module-nam‌e)@foo-bar‌ ‌service:(external-module-name)@fooBar‌ | service:(external-module-nam‌e)@foo-bar‌ ‌ |
| controller/foo/bar‌ ‌ | this.controllerFor(‘foo.bar’),‌ ‌this.controllerFor(‘foo/bar’)‌ ‌ | this.controllerFor(‘foo.bar’)‌ ‌ |
| component/foo/bar‌ ‌ | ‌{{foo/bar}}‌ ‌ | {{foo/bar}}‌ ‌ |
| component/foo/bar-baz‌ ‌ | ‌{{foo/bar-baz}},‌ ‌{{foo/bar_baz}}‌ ‌ | ‌{{foo/bar-baz}}‌ ‌ |
| (external-module-name)/addo‌n/components/foo/bar-baz‌ ‌ | {{component‌ ‌“(external-module-name)/foo/‌bar-baz”}}‌ ‌{{component‌ ‌“(external-module-name)/foo/‌bar_baz”}}‌ ‌{{component‌ ‌“(external-module-name)/foo/‌barBaz”}}‌ ‌ ‌ | {{component‌ ‌“(external-module-name)/foo/‌bar-baz”}}‌ ‌ |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand this table. What are the three columns trying to show?

I think it would be best to talk about it from the perspective of the service:foo calls (since those are constant from the framework perspective). So for service:fooBar (which is what is used when you do fooBar: injectService()) the strict resolver would literally look for app/services/fooBar.js and the current resolver would look for app/services/foo-bar.js.


As libraries migrate to the new use strict format older applications will not be negatively affected as the strict subset resolution is backwards compatible from libraries to applications.

The major difference between the two resolvers can be easily linted against:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linted against how? Is it limited to confirming that any injectService calls for camelcase property names have an argument?

gabrielcsapo and others added 5 commits January 12, 2021 16:55
Co-authored-by: Robert Jackson <me@rwjblue.com>
Co-authored-by: Robert Jackson <me@rwjblue.com>
Co-authored-by: Robert Jackson <me@rwjblue.com>
Co-authored-by: Robert Jackson <me@rwjblue.com>
Co-authored-by: Robert Jackson <me@rwjblue.com>
@wagenet
Copy link
Member

wagenet commented Jul 23, 2022

I'm going to try to bring this up with the core team and see if we can move it to a conclusion.

@wagenet
Copy link
Member

wagenet commented Jul 29, 2022

@chriskrycho should this be part of #832?

@chriskrycho
Copy link
Contributor

@wagenet I don’t think so; this is probably still worth doing if @gabrielcsapo wants to drive it forward, but separately from the Classic stuff. The resolver has its own path to slowly being replaced, but is separate from Classic issues.

@wagenet wagenet added the S-Proposed In the Proposed Stage label Dec 2, 2022
@achambers
Copy link
Contributor

@ef4 Is this in any way related to the RFCs you're currently working on? Also seems Embroider related. Do you have any thoughts to add here?

@ef4
Copy link
Contributor

ef4 commented Aug 28, 2023

Yes, #938 wants to introduce a new resolver implementation. That makes it a good time to drop deprecated resolver features. So if this RFC can land, we can make the new resolver in 938 not support the things this RFC deprecates.

One bit of feedback for this RFC is that we can probably avoid using an optional feature, in favor of making ember-resolver a V2 addon and having dedicated import paths for the different implementations.

@achambers
Copy link
Contributor

achambers commented Sep 1, 2023

@ef4 Just to clarify, if the new resolver in #938 doesn't implement the things that this RFC (#683) deprecates, then 683 is not needed, correct?

@ef4
Copy link
Contributor

ef4 commented Sep 1, 2023

Well, the work of deciding which things not to include still needs to happen. If #683 covers that work it makes it easier to do #938.

@wagenet wagenet removed the S-Proposed In the Proposed Stage label Sep 22, 2023
@wagenet
Copy link
Member

wagenet commented Sep 22, 2023

We agreed to move this to exploring at the RFC Review Meeting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-ember-cli RFCs that impact the ember-cli library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants