-
-
Notifications
You must be signed in to change notification settings - Fork 101
feat: adds the strict resolver as an option #837
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
2b945e1
73d85c2
7e41201
eff25f8
523dedd
06f869d
514bfed
82d4fe9
7aa9efd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,26 +36,115 @@ export default class App extends Application { | |
| // ...snip... | ||
| ``` | ||
|
|
||
| ## Strict | ||
|
|
||
| > Originally from <https://github.com/stefanpenner/ember-strict-resolver> | ||
|
|
||
| in app/resolver.js | ||
|
|
||
| ```js | ||
| export { default } from "ember-strict-resolver"; | ||
|
gabrielcsapo marked this conversation as resolved.
Outdated
|
||
| ``` | ||
|
|
||
| _For additional improvements when fully using the ember-strict-resolver monkey patching the registry to no longer cache and simply returning the values passed like the following can be produce extra performance._ | ||
|
gabrielcsapo marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```js | ||
| // disable the normalization cache as we no longer normalize, the cache has become a bottle neck. | ||
| Ember.Registry.prototype.normalize = function (i) { | ||
| return i; | ||
| }; | ||
| ``` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. However, I have a broader comment, which is: if we think this is worth doing, we should build a public API for it. It's one thing to do this as an experiment in our app (a successful one, I might add!) but we should not recommend others do it until there is a public API, or else we're setting people up for pain. |
||
|
|
||
| ## Migration | ||
|
|
||
| Migrating away from use the _ember-resolver/classic_ can be done in piecemeal by supporting a sub-set of the old resolution formats. | ||
|
gabrielcsapo marked this conversation as resolved.
Outdated
|
||
|
|
||
| > normalize is needed, because without it you will get errors related to failing to be able to inject services that were never normalized in the registry. | ||
|
gabrielcsapo marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```js | ||
| // app/resolver.js | ||
|
|
||
| import Resolver from "ember-strict-resolver"; | ||
|
gabrielcsapo marked this conversation as resolved.
Outdated
|
||
|
|
||
| export default class extends Resolver { | ||
| legacyMappings = { | ||
| "service:camelCaseNotSupported": "service:camel-case-not-supported", | ||
| }; | ||
|
|
||
| resolve(_fullName) { | ||
| return super.resolve(this.legacyMappings[_fullName] || _fullName); | ||
| } | ||
|
|
||
| normalize(_fullName) { | ||
| return this.legacyMappings[_fullName] || _fullName; | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| This will allow you file PRs with libraries that currently do not support the strict resolver in its entirety. | ||
|
|
||
| In the event that you have a component that is failing to resolve correctly with the error `Attempted to lookup "helper:nameOfVariable". Use "helper:name-of-variable" instead.` please convert your template to use explicit-this. The template lint can be enabled by turning on [no-implicit-this](https://github.com/ember-template-lint/ember-template-lint/blob/master/docs/rule/no-implicit-this.md). | ||
|
gabrielcsapo marked this conversation as resolved.
Outdated
|
||
|
|
||
| An example of what this looks like is the following | ||
|
|
||
| ```hbs | ||
| // addon/components/templates/foo.hbs | ||
|
|
||
| <div> | ||
| {{fullName}} | ||
| </div> | ||
| ``` | ||
|
|
||
| This will result in the error, `Attempted to lookup "helper:fullName". Use "helper:full-name" instead.`. The fix for this would be to decide if this is a argument being passed into foo or if this is a local property. | ||
|
|
||
| _fullName_ is coming from an invocation of _Foo_ like the following: | ||
|
|
||
| ``` | ||
| <Foo | ||
| @fullName="The Teamster" | ||
| /> | ||
| ``` | ||
|
|
||
| Then the fix for your template would be: | ||
|
|
||
| ```hbs | ||
| // addon/components/templates/foo.hbs | ||
|
|
||
| <div> | ||
| {{@fullName}} | ||
| </div> | ||
| ``` | ||
|
|
||
| If _fullName_ is a property on your component the fix would be: | ||
|
|
||
| ```hbs | ||
| // addon/components/templates/foo.hbs | ||
|
|
||
| <div> | ||
| {{this.fullName}} | ||
| </div> | ||
| ``` | ||
|
|
||
| ## Addon Development | ||
|
|
||
| ### Installation | ||
|
|
||
| * `git clone` this repository | ||
| * `npm install` | ||
| * `bower install` | ||
| - `git clone` this repository | ||
| - `npm install` | ||
| - `bower install` | ||
|
|
||
| ### Running | ||
|
|
||
| * `ember server` | ||
| * Visit your app at http://localhost:4200. | ||
| - `ember server` | ||
| - Visit your app at http://localhost:4200. | ||
|
|
||
| ### Running Tests | ||
|
|
||
| * `ember test` | ||
| * `ember test --server` | ||
| - `ember test` | ||
| - `ember test --server` | ||
|
|
||
| ### Building | ||
|
|
||
| * `ember build` | ||
| - `ember build` | ||
|
|
||
| For more information on using ember-cli, visit [http://www.ember-cli.com/](http://www.ember-cli.com/). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| /* globals requirejs */ | ||
|
|
||
| import { warn } from '@ember/debug'; | ||
| import { dasherize } from '@ember/string'; | ||
| import { DEBUG } from '@glimmer/env'; | ||
|
|
||
| import require from 'require'; | ||
|
|
||
| export default class Resolver { | ||
| constructor(attrs) { | ||
| if (attrs) { | ||
| this.namespace = attrs.namespace; | ||
| } | ||
| // secret handshake with router to ensure substates are enabled | ||
| // see https://github.com/emberjs/ember.js/blob/a429dc327ee6ef97d948a83e727886c75c6fe043/packages/%40ember/-internals/routing/lib/system/router.ts#L344 | ||
| this.moduleBasedResolver = true; | ||
| } | ||
|
|
||
| static create(args) { | ||
| return new this(args); | ||
| } | ||
|
|
||
| has(moduleName) { | ||
| return moduleName in (requirejs.entries || requirejs._eak_seen); | ||
| } | ||
|
|
||
| parseFullName(fullName) { | ||
| let prefix, type, name; | ||
|
|
||
| let fullNameParts = fullName.split('@'); | ||
|
|
||
| if (fullNameParts.length === 3) { | ||
| if (fullNameParts[0].length === 0) { | ||
| // leading scoped namespace: `@scope/pkg@type:name` | ||
| prefix = `@${fullNameParts[1]}`; | ||
| let prefixParts = fullNameParts[2].split(':'); | ||
| type = prefixParts[0]; | ||
| name = prefixParts[1]; | ||
| } else { | ||
| // interweaved scoped namespace: `type:@scope/pkg@name` | ||
| prefix = `@${fullNameParts[1]}`; | ||
| type = fullNameParts[0].slice(0, -1); | ||
| name = fullNameParts[2]; | ||
| } | ||
|
|
||
| if (type === 'template:components') { | ||
| name = `components/${name}`; | ||
| type = 'template'; | ||
| } | ||
| } else if (fullNameParts.length === 2) { | ||
| let prefixParts = fullNameParts[0].split(':'); | ||
|
|
||
| if (prefixParts.length === 2) { | ||
| if (prefixParts[1].length === 0) { | ||
| type = prefixParts[0]; | ||
| name = `@${fullNameParts[1]}`; | ||
| } else { | ||
| prefix = prefixParts[1]; | ||
| type = prefixParts[0]; | ||
| name = fullNameParts[1]; | ||
| } | ||
| } else { | ||
| let nameParts = fullNameParts[1].split(':'); | ||
|
|
||
| prefix = fullNameParts[0]; | ||
| type = nameParts[0]; | ||
| name = nameParts[1]; | ||
| } | ||
|
|
||
| if (type === 'template' && prefix.lastIndexOf('components/', 0) === 0) { | ||
| name = `components/${name}`; | ||
| prefix = prefix.slice(11); | ||
| } | ||
| } else { | ||
| fullNameParts = fullName.split(':'); | ||
|
|
||
| prefix = this.namespace.modulePrefix; | ||
| type = fullNameParts[0]; | ||
| name = fullNameParts[1]; | ||
| } | ||
|
|
||
| return { | ||
| prefix, | ||
| type, | ||
| name | ||
| } | ||
| } | ||
|
|
||
| moduleNameForFullName(fullName) { | ||
| let moduleName; | ||
|
|
||
| const { prefix, type, name } = this.parseFullName(fullName); | ||
|
|
||
| if (name === 'main') { | ||
| moduleName = `${prefix}/${type}`; | ||
| } else if (type === 'engine') { | ||
| moduleName = `${name}/engine`; | ||
| } else if (type === 'route-map') { | ||
| moduleName = `${name}/routes`; | ||
| } else if (type === 'config') { | ||
| moduleName = `${prefix}/${type}/${name.replace(/\./g, '/')}`; | ||
| } else { | ||
| moduleName = `${prefix}/${type}s/${name.replace(/\./g, '/')}`; | ||
| } | ||
|
|
||
| return moduleName; | ||
| } | ||
|
|
||
| resolve(fullName) { | ||
| const moduleName = this.moduleNameForFullName(fullName); | ||
|
|
||
| if (this.has(moduleName)) { | ||
| // hit | ||
| return require(moduleName)['default']; | ||
| } | ||
| // miss | ||
| } | ||
|
|
||
| normalize(fullName) { | ||
| if(DEBUG) { | ||
| const { type } = this.parseFullName(fullName); | ||
|
|
||
| if(['service'].includes(type)) { | ||
| warn(`Attempted to lookup "${fullName}". Use "${dasherize(fullName)}" instead.`, !fullName.match(/[a-z]+[A-Z]+/), { id: 'ember-strict-resolver.camelcase-names' }); | ||
| } | ||
| } | ||
|
|
||
| return fullName; | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.