-
Notifications
You must be signed in to change notification settings - Fork 26
Proposal for allowed ES6 features in hapi #58
Comments
I would also like to add promises to this list. Hapi uses callbacks everywhere. I'm not saying module developers should completely switch to promises, but would be good if functions returned a promise when a callback is not passed to arguments. |
That would probably require a massive rewrite of the entire hapi ecosystem in order to be consistent. Not saying that's a bad idea, but gmail marked your message as suspicious :-) |
We can allow exposing a promises API but not using promises internally in hapi modules. |
One comment on map/set: |
For a thing to avoid, I think that provides a pretty weak argument. A performance penalty would be justification to avoid something. Seems Symbols should simply be left to the discretion of the implementor. In fact, for implementations where you really want something to be hidden from the public interface, Symbols provide a great solution. |
This is all open for discussion. I questioned putting Symbols in the things to avoid list. I just don't see them as that useful because |
I really like the list, maybe when there is an agreement add some rules to eslint from lab? |
Would love for hapi server methods to return promises |
A 👍 from me for returning promises. Especially with ES7 |
Agreed on most of it. To the last few comments, this is a language feature debate, please stay on topic, hapi's API (or any other module) should be discussed there, this is not the place. |
@cjihrig: Can you clarify this? |
|
Aren't two tests better here? |
If the tests are there I see no point in removing them. If not testing if Object.assign works seems redundant. |
I'm not advocating for removing existing tests, but for new code it requires writing one instead of two.
I don't think so. |
My point is, there are two options here and you are hiding one of them from the tests. |
Maybe some code will help clear up what @cjihrig is talking about... var hoek = require('hoek');
var defaults = {
foo: 'bar',
protocol: 'http'
};
var register = function (options) {
var hoekApply = hoek.applyToDefaults(defaults, options || {});
var assign = Object.assign({}, options, defaults);
}
register({
foo: 'baz'
}); With this code, |
that makes it clear, thx |
Again, you are making the argument that testing both cases of |
Added an updated test for string-keyed value reading from Map objects to six-speed. Looks like Map is about half the speed for that use case. For my own personal projects, I'm only planning on using Map for rare case that I have non-string key values unless that changes. |
Simplified coverage (if you want to call it that or not) is just a side effect of What are the next steps for moving forward with this? |
A PR on the style guide as well as a new section for allowed language features. Also, are we going to recommend always using let vs var vs const? |
Maybe also propose some eslint configs for the new styles, it will make the transition easier. @cjihrig I can make a PR on the config repo with the ones I added which seemed sane to me (and ofc in line with this discussion) if you want |
This list says what you can use, so we should probably list stuff you should not |
Seems reasonable :P |
I would like to hear what people think about the arrow function rule (require both () and {}). This seems to be going against the trend of keeping things short for a lot of the simple cases. Can we map the pitfalls of omitting them and agree on the limits we want to enforce? |
I prefer requiring both, the auto return and stuff can be confusing. If you really want this mapping the allowed cases and putting them in the style guide is fine. |
These are the rules I try to follow for my projects :
I strongly disagree that implicit returns reduce readability, quite the opposite. |
This is just a matter of opinion :P I just like explicit returns not that leaving them out reduces readability per se, just my preference. |
@Marsup could you expand on your second point please? Not quite sure what is meant by that. I find implicit return more readable and it communicates the intention to just return a value as opposed to perform some other logic first. |
I agree with the rule as stated. It's much easier to remember a single rule than to try to remember three. Also, if you opt for the short syntax, you had to make code changes just to put a I agree with @cjihrig; if we start dropping |
You already have to remember a lot of rules, oh wait... there's eslint for that ;) I'm just reporting what I actually use after almost 2 years of practice with it, agree to disagree ;) |
Agreed. Style guides are like religion, sports, and politics. Serious question though. Are there existing ESLint rules for the items in your list other than |
My point being, I should not have to add The relationship with |
No other rules out of the box, eslint's support for ES6 is fairly recent so... That didn't prevent us from creating our own. If you want to add statements and forget about the braces that's OK, I'm not advocating for banishing them, just allowing the other syntax. |
We already have rules people find odd. I am not worried about that. But rules should enhance the code and I think some arrow function shortcuts make the code more readable. I agree with these:
I am not sure about:
Here are my concerns: first, it is not a well defined rule. It's more about "feeling" and that's never a good idea for a community project. We also don't have line length limit and I don't want to introduce one. We can make a single statement single line rule and this will self-police itself as crazy long lines will just because unreadable and people will break them up and add {}. But the real issue is that we already have a hard rule for how to write functions. We do not allow single line functions because we want the visual cue of the empty line to call your attention you are switching context and potentially event loop tick. That's what I am worried about losing. The context is no longer an issue because of how |
i'm a +1 for allowing single statement implicit returns. there are a lot of scenarios where it's a lot simpler and where a block is really not necessary. i think if your function body is a single statement, then go for it. |
@nlf single statement and single line? |
Could we require an empty line whenever a tick is possibly at stake? Do our rules require that they be fully enforceable by eslint? |
preferably single line, yes. i agree with you that people will end up policing themselves on extremely long lines for their own sanity, so one statement one line makes sense |
@devinivy no one will be able to keep track of that. I think it's ok to not go there and just start simple and see what the code looks like moving forward. |
I expect we'll find that single statement arrow functions rarely will be used in cases that a tick is at stake anyway. |
i agree, i don't think a single statement is going to be asynchronous often at all |
We should also allow ({}) to span multiple lines. |
Conclusion:
|
Sorry, nothing yet. |
I'm tinkering with template strings on joi, it brings a bit more readability. I've tested it against node 5.0 and it's still 2x slower, but it's an unlikely scenario of massive concatenations in a loop, I doubt it would impact the project in any significant way. Do you have thoughts about it ? |
Personally, I prefer template strings over string concatenation for readability. The only tricky part would be enforcing when to use them. Always? Only in place of concatenation? |
how would you deal with splitting strings up on multiple lines when to long? |
@cjihrig it probably adds extra pressure on the VM so only where it makes sense. |
@Marsup not encountered that problem (yet) |
async generator |
Now that hapi 10 is out and using Node 4, we need to consider which ES6 features (and general JS features) should be allowed in hapi modules, as well as style guide issues, etc. To get the discussion going, here is a list that @arb and I came up with.
Strongly Recommend
Strict Mode
Strict mode makes JavaScript more restrictive. It prevents the use of several features that are considered bad practices. It also enables certain new language features. In the past it has been known to help V8 (unsure if this is currently true as V8 changes rapidly). It is trivial to enable. Node core has moved to strict mode everywhere.
Object.assign()
Object.assign()
is the preferred way to copy/merge objects. This can be used as a replacement forfoo || {}
(simpler code coverage), as well as several Hoek methods.const
const
is used to define constants.const
can be used to declare a surprisingly large number of variables that are not what would normally be considered "constants." For example, in Node core, it has become a convention to useconst foo = require('foo');
. In general,const
should be favored and used in any case where a variable’s value doesn’t change.Map
andSet
Node now offers proper map and set data structures. According to six-speed the performance is better than the ES5 alternatives. Maps are preferred over using objects as key-value stores (although this can present problems when returned from public APIs, but works perfectly fine for internal APIs).
New Math and Number Methods
New methods such as
Number.isInteger()
make tasks like checking for an integer, much more readable. Methods likeNumber.isNaN()
provide a stricter alternative to the globalisNaN()
.Nice to Have
Template Strings
Template strings are used as an alternative to string concatenation and often require a few less characters. Performance may still be slightly worse according to six-speed. This is currently used in Node core.
Classes
Classes are syntactic sugar. They currently require strict mode. One thing worth noting is that six-speed indicates
super()
performs poorly.Numeric Literals
The old way of declaring octal literals is forbidden in strict mode. The new octals, as well as binary constants, are more intuitive. This is probably not very common in the hapi ecosystem, but should be allowed, if needed, for readability.
Use with Caution
Object Literal Shorthand and Computed Properties
If deemed suitable, these should be allowed. However, computed properties were broken until relatively recently. According to six-speed, there is a significant performance penalty (although a more fine grained breakdown of shorthand vs computed properties would be nice).
Arrow Functions
Arrow functions do not clobber the existing
this
value, making them very useful as callback functions. However, there are a number of ways to burn yourself with them:()
and{}
.this
is important. For example, when usingthis
inside of an object literal.instanceof
operator.let
let
provides block scoping, and in the general case is comparable tovar
. However, there are some cases where it breaks down. See Trevor Norris's comments here.Things to Avoid
Symbols
Symbols allow you to more effectively hide data. I haven't encountered problems with them, but also don't see a real need for them.
General
Anything that is still behind a flag. These features are generally not complete, hence the flag. If you run into trouble, you will be sent to the V8 issue tracker.
References
The text was updated successfully, but these errors were encountered: