Skip to content
This repository was archived by the owner on Jan 20, 2019. It is now read-only.

Standarize targets#95

Merged
rwjblue merged 15 commits intoember-cli:masterfrom
cibernox:standarize-targets
Feb 18, 2017
Merged

Standarize targets#95
rwjblue merged 15 commits intoember-cli:masterfrom
cibernox:standarize-targets

Conversation

@cibernox
Copy link
Contributor

@cibernox cibernox commented Jan 10, 2017

@cibernox
Copy link
Contributor Author

This RFC is somewhat an extraction of RFC in PR #89, but less controversial in the sense that focuses on standarizing app targets and its syntax but leaves open how ember, ember-cli or addons should use them.

I open this in hope that it can be approved faster and independently of the advances in the babel6 migration.

### Motivation

Javascript and the platforms it runs on are moving targets. NodeJS and browsers release new
versions every few weeks. Browsers auto update and each update bings new language features
Copy link
Contributor

Choose a reason for hiding this comment

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

bings -> brings?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup


The syntax for for this configuration option is even simpler, since apps will only run in a single
version of node and developers are in control of it, so the only thing users must specify is the
minimum supported version of node.
Copy link

Choose a reason for hiding this comment

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

If this is added, I would either let the user specify the node version as they do in the package.json or specify in the name that is the minimum version acceptable. The first option is harder to implement, but people would be more used to it.

Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest that the default would just do node: require('../package').engine (deferring to the engine listed in package.json).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm also ok with that. We can reuse it.


Let every addon that wants to deal with targets to have a `targets`-like option in its configuration
instead of standardizing a single configuration option, which effectively leaves things as they are
right now.
Copy link

Choose a reason for hiding this comment

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

This option opens the door of a misconfiguration, in the sense that you might add support for X browser in autoprefixer but not in babel and suddenly, your life is much more interesting. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't say it was a good alternative 😉 But this is the state of things right now: each addon uses it's own configuration, and possibly its own syntax.

@stefanpenner
Copy link
Contributor

big fan of this direction!

I'll try and fine time over the next few days to thoroughly review.

@cibernox
Copy link
Contributor Author

cibernox commented Feb 1, 2017

@stefanpenner any opinion on core people on this? I could work in the implementation myself. I'm craving for some tooling.

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.

but this RFC doesn't impose any mandatory behavior on addons

I agree that we shouldn't (or can't) mandate anything, but we should recommend that they honor them...


Developers need an easy way to express intention that abstracts them from the ever-changing
landscape of versions and feature matrices, so this RFC proposes to introduce a universal
configuration option to let developers express they intended targets
Copy link
Member

Choose a reason for hiding this comment

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

s/they/their/


Addons that would benefit from this conventions are `babel-preset-env`, `autoprefixer`,
`stylelint` and `eslint` (vía `eslint-plugin-compat`), but not only those. Even Ember itself could,
once converted into an addon, take advantage of that to avoid polyfilling or even taking
Copy link
Member

Choose a reason for hiding this comment

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

it is an addon as of ember-cli@2.11 / ember-source@2.11.0 🎉

once converted into an addon, take advantage of that to avoid polyfilling or even taking
advantage of some DOM API (`node.classList`?) deep in Glimmer's internals.

### Detailed implementation
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if this was intentionally left blank?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It wasn't blank, it's just that it was an h3 and it should be an h1, and the next points are subsections.

Copy link
Member

Choose a reason for hiding this comment

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

aha! thank you!

```

This configuration must be made available to addons. It's up to the addons to use it.
I suggest to make it available in `app.targets`
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer one of these instead:

  • add this.targets property
  • this.project.targets() / this.project.targets


```js
var app = new EmberApp(defaults, {
targets: {
Copy link
Member

Choose a reason for hiding this comment

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

We should avoid tying this target system to the build time only ember-cli-build.js / EmberApp instance since it will be needed from places outside of the build environment. For example, when editing a project I enjoy utilizing my editors built in eslint system to indicate any linting errors/warnings that I have in my code. If I wanted to utilize eslint-plugin-compat, I would have to duplicate the configuration in ember-cli-build.js and .eslintrc.js (or change ember-cli-build.js to have multiple exports).

I'd prefer that we either:

  • put the config in .ember-cli file which is already in the project
  • put the config in another file in config/ (e.g. config/supported-targets.js)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, one interesting approach of this is the one eslint-plugin-compat uses. It reads the browserlist property in the package.json.

If we are cool with reading the engines property of the package.json for the node support it might also be a reasonable place to the list of supporter browsers.

included(app) {
this._super.included.apply(this, arguments);

console.log(app.targets.browsers); // ['>2%', 'last 3 iOS versions', 'not ie <= 8']
Copy link
Member

Choose a reason for hiding this comment

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

The meaning of app changes when using things like fastboot and ember-engines, this is why I would like to decouple storing of target from app...


The syntax for for this configuration option is even simpler, since apps will only run in a single
version of node and developers are in control of it, so the only thing users must specify is the
minimum supported version of node.
Copy link
Member

Choose a reason for hiding this comment

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

I'd suggest that the default would just do node: require('../package').engine (deferring to the engine listed in package.json).

traditionally enforced only with peer reviews.

To ease the transition Ember CLI can also, in the absence of a specific value provided by the user,
default to a predefined matrix of browsers that matches the browsers officially supported by the framework.
Copy link
Member

Choose a reason for hiding this comment

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

👍 - But we should (in this RFC) list out the "default" configuration...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what Ember supports. I know that IE support starts in 9, but no idea about the policy for other evergreen browsers. Is there one? Who knows it?


```js
var app = new EmberApp(defaults, {
targets: {
Copy link
Contributor

Choose a reason for hiding this comment

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

targets object, to be consider together? e.g. lowest common denominator between all properties, or is this 2 separate builds... I believe they should be lowest common denominator

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is affectively how things like babel-preset-env and eslint-plugin-compat works. Browserlist has an evergreen database from caniuse.com with features by browser version, so it calculates the support on a per-feature basis.

I'll add it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added support matrix from the browsers we test in saucelabs & travis. No mention to ios tho, but likely IE9 will be the weakest ring of the chain in everything anyway.

@rwjblue
Copy link
Member

rwjblue commented Feb 2, 2017

Discussed during ember-cli core team meeting today, we were generally very 👍. Main issues are:

  • naming ("target" is hard to use, perhaps we can do somethign like target-platforms, supported-platforms, etc...)
  • determine exactly where to put this config (IMO it should not be in ember-cli-build.js, but that is TBD obviously)
  • confirm if multiple targets are supposed to be considered as a combination (e.g. "lowest common denominator")
  • list the explicit default config that matches ember-source@2.11's supported platforms

@kellyselden
Copy link
Member

If the default is dependent on which ember version you may be using, should it be bundled with ember (like its blueprints)? I'm not sure what this would look like in a way you could override it in ember-cli land...

@cibernox
Copy link
Contributor Author

cibernox commented Feb 3, 2017

@kellyselden It could be part of ember-cli, because a ember drops browser support in major versions only, which would carry (I think) a major version bump in ember-cli as well.

@kellyselden
Copy link
Member

@cibernox True, but we still allow ember 1.13 in ember-cli 2.x, and will be the same for the next cycles. Might be unnecessary friction to have more code in cli that ties to specific ember versions.

@cibernox
Copy link
Contributor Author

cibernox commented Feb 3, 2017

@kellyselden So options:

  • Make it a part of ember-source, like blueprints. In the absence of configuration, we use those values.
  • We trust the file (e.g config/targets.js). This file is part of the default blueprint of an app, and lives wherever blueprints live now (I think they've extracted). If the file is not present, we don't have any default value.

I lean towards the first. At the end ember.js already has (kind of) this information about browser support in the config files for travis and saucelabs.

This library is very powerful and popular, making relatively easy to integrate with a good amount of
tools that use it in little time.

This configuration must be made available to addons but we it's up to the addon authors to take advantage
Copy link

Choose a reason for hiding this comment

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

odd "but we"

@cibernox
Copy link
Contributor Author

cibernox commented Feb 3, 2017

Feedback applied:

  • Per slack bikeshedding, the configuration will be in this.project.targets. The object in that property will have browsers and node properties. There's another RFC Multiple Build Targets #93 that wants to introduce another kind of targets. The chamption (@kratiahuja) seems happy to use this.project.targets.platforms for its concept.

  • Added data of where the config must be placed. Preferred option: config/targets.js, similar to config/ember-try.js, which is also used to build a support matrix, but of ember versions instead of browser versions.

  • Confirmed Minimum Common Denominator of the approach, and added an example.

  • Added list default supported browsers, extracted from the browsers tested in ember in travis and saucelabs.

@kanongil
Copy link

kanongil commented Feb 3, 2017

Does the node property encompass supporting alternative engines, like node-chakracore?

@cibernox
Copy link
Contributor Author

cibernox commented Feb 3, 2017

@kanongil The node property is basically require('package.json').engines. Do you know if node-chakracore is specified that way?

@rwjblue
Copy link
Member

rwjblue commented Feb 9, 2017

Discussed in ember-cli core meeting today, we are 👍 on advancing this to final comment period.

One thing that we would like to see before landing the RFC (after FCP is finished and whatnot) is a spike of the implementation in a PR to ember-cli. This is just to confirm that all of the constraints listed here are addressed and we don't find flaws.

I believe that I will have time to spike this out in the next couple of days...

@cibernox
Copy link
Contributor Author

cibernox commented Feb 9, 2017

Nice! If you don't let me know and I can try.

@Cryrivers
Copy link

speaking of targets, is there any consideration for targets like Cordova, Electron, or "Ember Native" (maybe in the future)?

@rwjblue
Copy link
Member

rwjblue commented Feb 15, 2017

@Cryrivers - Yes, but that is a somewhat separate RFC (see #93 for some background).

@cibernox
Copy link
Contributor Author

@Cryrivers @rwjblue Actually after some investigation there is a small overlapping on the concepts. Some libraries like babel-preset-env consider electron a target, just like any other browser, and use https://github.com/kilian/electron-to-chromium to translate from the version of electron to the equivalent chromium version to know if a feature is supported.

The targets this RFC targets are the javascript runtimes in which this app is going to run. That is the browser or electron version, or even node version in fastboot.

A separate concept is "platforms" (name to be bikeshedded) that only makes sense when you are going to wrap your app and you are going to write javascript code that bridges to the OS using electron/cordoba APIs.

In summary, in this RFC a target is "where my Ember app code is going to run on". The electron specific code is probably going to live in a separate folder and RFC #93 wants to solve that. It's an area I don't have any expertise on, TBH.

@kanongil
Copy link

I'm a bit concerned that the project.targets.browsers naming is a bit too generic. I would prefer that it signals that it only applies to the javascript runtime. Maybe just prefix is with "js" so that it becomes project.jsTargets.browsers ?

As it is, you can confuse it with other runtime capabilities, like css capabilities, which e.g. https://github.com/kimroen/ember-cli-autoprefixer handles.

@rwjblue
Copy link
Member

rwjblue commented Feb 15, 2017

@kanongil - I believe that is entirely the point. We want it to be used for both JS transpilation and CSS transpilation targeting. This is mentioned in the Motivation and Detailed Design sections of this RFC.

@cibernox
Copy link
Contributor Author

cibernox commented Feb 15, 2017

@kanongil exactly. It's not scoped to js. CSS is part of the plan. My example if my app drops support for IE11 then my ember-css-linter (invented addon) can warn me wherever I use -ms-user-select: none, since I don't need the prefix anymore.

@cibernox
Copy link
Contributor Author

I have a working implementation of this ember-cli/ember-cli#6776
It was pretty simple to implement.

I've also spiked how ember-maybe-import-regenerator (used by ember-concurrency) could use it to conditionally avoid including the regenerator polyfill if the built matrix supports generator functions.

@rwjblue
Copy link
Member

rwjblue commented Feb 17, 2017

Discussed in ember-cli core team meeting yesterday, and with some small (scope narrowing) changes we are ready to land this.

Specifically, we would like to restrict targetsto only include browsers at this point (IOW, remove node section). A future RFC can add support for things like fastboot / cordova / etc, and removing node here shouldn't affect the primary motivators of the RFC.

@cibernox - Let me know when you have had a chance to update that, and we are ready to land this...

@cibernox
Copy link
Contributor Author

@rwjblue Amended the RFC to leave node/fastboot out of this RFC, so will cross that bridge another day.

@rwjblue rwjblue merged commit d9e2e5f into ember-cli:master Feb 18, 2017
homu added a commit to ember-cli/ember-cli that referenced this pull request Feb 21, 2017
Implement targets RFC

This PR implements ember-cli/rfcs#95 (still unmerged).

API example

```js
app.project.targets; // { browsers: [...], node: '6.6.0' };
```
@cibernox cibernox deleted the standarize-targets branch February 24, 2017 13:04
@kanongil
Copy link

kanongil commented Apr 3, 2017

In case you missed it, I posted some comments on javascript issues in #104.

kategengler pushed a commit to kategengler/rfcs that referenced this pull request Jan 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.