Comments (16)
Another option is to require "static" imports into the component itself of everything it could possibly render via "dynamic" lookup. This could be opt-in behavior which makes it a concept you can put off "until you need it." (Power user feature with a mostly painless late-opt-in strategy.)
This means you don't have to specify what is whitelisted per component
helper (though that could become a perf optimization) you would just do it per template (since the template truly drives what is included, not the backing JS file).
from rfcs.
"Power user feature" is the last resort when there is no solution that stays within concepts everybody needs to learn anyway. That is a high bar and I don't think we've hit it here.
In-template import
is a pretty large design space that goes beyond this particular issue. If we were to introduce it, it would need to actually do all the things people might reasonable expect it to do, and I think it will rapidly become all of ECMA import
. And it would risk bifurcating community efforts between people who think you should import everything and people who think you should use the resolver. There needs to be an unambiguous answer to "which way should I do this?" that is not "whatever floats your boat".
I think we can just make the resolver itself sufficiently static, fast, and friendly that it does the right thing for beginners and power users alike. And we have public API for writing your own resolver anyway, which is the true power user escape valve.
from rfcs.
/cc @chadhietala @trentmwillis
from rfcs.
It might be useful to be able to specify a pattern, which would cover what is in my experience the most common use case for the component helper (rendering a family of similarly named components), minimize the hassle of remembering to update the whitelist as new variation are added, and still allow for graph resolution.
from rfcs.
Not sure why you can't just do this:
import ShareUpdate from './share-update';
import ViralUpdate from './viral-update';
const VALID_TYPES = [ViralUpdate.type, ShareUpdate.type];
export default class Feed {
constructor(attrs) {
this.updates = attrs.updates.filter((update) => VALID_TYPES.indexOf(update.type) > -1)
}
}
export const template = hbs`
{{#each updates as |update|}}
{{component update.type}}
{{/each}}
`
Colocation solves this pretty nicely for these types of problems.
from rfcs.
I don't see how we can (within 2.x) make any currently valid name a build time error. The only thing that would be SemVer compatible would be something that errors today. whitelist
is currently a valid property to pass into, and in general seems like a fairly common name to already be in use. In theory we could try to hedge our bets and make it something less likely to conflict, but without additional syntax anything we pick would technically be a breaking change.
Not sure why you can't just do this
You absolutely could! But yuck
from rfcs.
As an alternative to "whitelisting" components in the templates, I tend to favor an idea like what @chadhietala suggested, where we whitelist components on the JS side of things. I don't necessarily think we need to colocate templates in the JS (though that is an option). Instead we could introduce a simple new class that represents a "union" of classes:
import SomeComponent from './some-component';
import OtherComponent from './other-component';
const SomeOtherComponent = UnionComponent.from(
SomeComponent,
OtherComponent
);
export default SomeOtherComponent;
Pros:
- No build time magic needs to happen
- Mapping dependencies should require no extra logic beyond what we need for normal components
- New API (no backwards compatibility issues)
Cons:
- New API
- Requires more overhead than using a solely template-based solution
from rfcs.
@trentmwillis We are sort of re-creating a type system as I don't know what the return type UnionComponent.from
would return.
from rfcs.
@rwjblue You're correct that this would be a breaking change. Anything in this proposal (or the alternatives described by Chad/Trent) would be implemented as an addon and then possibly be imported into core. Since this is relatively simple to implement as an addon I don't care about timeline. It could probably be implemented in 2.X as a positional parameter with something like (whitelist "component-name other-name")
but that's likely a bad idea for perf reasons.
@trentmwillis / @chadhietala Both of your proposals are easy to accomplish with a stupid-simple addon. It's effectively a custom component
helper with a custom backing class. We can identify dependencies by tracing imports in the backing JS file.
The big tradeoffs I see:
- The attribute would be a lot easier to teach and a bit more difficult to code up as it requires walking the HBS files to calculate the dependency graph.
- The explicit imports are a lot more clear as to what's happening and would require no additional pass of the HBS files to calculate the dependency graph.
from rfcs.
So I decided to take a stab at implementing my UnionComponent
idea. To answer @chadhietala's question, from
returns a "component factory". The implementation is pretty straightforward, but suffers from one big issue: re-rendering with a different component type doesn't work. Now I'm not sure if that's a major use-case, but given that it is supported by the {{component
helper it would probably be a desirable feature for parity.
The only way I can think of supporting it at this time would be via registering all "unions" as new keywords (similar to {{component
), but that obviously has large, negative consequences with it.
from rfcs.
I'd suggest this be done with a linting rule and a helper to allow static analysis. Create a helper for whitelisting:
At dev-time, allow-components
can assert for unexpected values. At prod time it is cheap enough to leave probably, or you can strip it out.
And then add a rule for the https://github.com/rwjblue/ember-cli-template-lint linter that requires all {{component
helpers to be passed an allow-components
subexpression.
Hell if you went wild with the template pre-processors, you could make the whitelist=
syntax work and just compile it to be above :-)
I'm not sold on the value of making this into an Ember feature though, since the main value seems to be for a static analysis tool from outside of Ember.
from rfcs.
@mixonic I think the purpose was to tie everything together e.g. JS + HBS. When you are trying to resolve the dependency graph it's probably best to use Import/Export declarations than having to parse both JS and templates to arrive at the final graph.
from rfcs.
@chadhietala can you say more? I'm not clear on why an argument to the component helper is easier to resolve dependency-wise than a user-space helper. Seems basically the same?
from rfcs.
Not really arguing framework v. user space. I'm coming from the approach that if you want to understand how components are used in your application, its easier to do static analysis on something that has a module system.
from rfcs.
This came up in discussion of module unification and static resolver. A leading idea was a 'namespace' option on the component helper. Namespaces are already a thing in rfc 143 and they make a good-sized bucket for restricting dynamic component resolution. We can even forbid unqualified targeting of other namespaces as part of the module unification rollout.
This has nice behaviors even for people who don't do anything special: unused components could be shaken out of all their addons, despite usage of the dynamic component helper in their apps namespace. And people who want shaking within their app can segregate dynamically targeted components into their own package.
from rfcs.
This will be addressed by "template imports" which is currently being discussed in #454. Closing this in favor of that PR.
from rfcs.
Related Issues (20)
- Switch default package manager to pnpm for new projects + C.I. HOT 44
- Public API support disparity with Glint and typed templates with custom managers -- currently no story for TS support (for now?) HOT 5
- Deprecate support for `ember-cli-qunit` and `ember-cli-mocha` when generating test blueprints HOT 3
- Standardize the use of yarn and npm scripts in the Ember experience, for test and start HOT 11
- V2 addons' build-time integration HOT 4
- Deprecate all of Ember Classic HOT 16
- Build-time configuration of index.html HOT 3
- Deprecate support for Travis CI HOT 6
- Deprecate `ember-mocha`? HOT 2
- Deprecate `ember-export-application-global` addon? HOT 4
- Run Prettier separately in `app` blueprint HOT 9
- Deprecate `app.import`
- Thoughts on this more ergonomic way to wire up the owner + destroyable association? HOT 2
- Explore "official" pod deprecation HOT 19
- {{else}} should render a value rather than be a control-flow keyword. HOT 5
- new primitive: transition, similar to modifiers, except they block certain render events HOT 2
- Numbers in PR titles affect automation
- Asset import spec RFC HOT 2
- Implement import spec RFC HOT 1
- Replacing `moduleName` in template meta HOT 11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rfcs.