How to disable usage of certain ES2015 features with ESLint 2? - javascript

In ESLint 1, I can use the ecmaFeatures option to disable or enable certain language features. E.g.
ecmaFeatures:
defaultParams: false
Above config disables defaultParams.
This is very useful because in runtime like Node, not all features are available, and I don't want to use a transpiler.
But in ESLint 2, that was removed. You only got ecmaVersion, which doesn't alerting on usage of ES2015 features at all even if you give it a ecmaVersion of 5. I guess this make sense since the JavaScript interpreter will complain about the usage of unsupported syntax at interpretation time, but what about developing for browsers have different level of ES2015 support? Syntax that works for Chrome won't work for IE9.
Is there any way to lint the usage of language features, e.g. disable destructuring?

no-restricted-syntax rule disallows specific syntax. This "syntax" is meaning the types of AST nodes. The spec of AST is here: https://github.com/estree/estree
eslint-plugin-node's no-unsupported-features rule disallows unsupported ECMA features by specific Node's version. I don't know whether a similar rule for browsers exists or not.

Related

ESlint: Highlighting ES6 code in an non-transpiled ES5 codebase

We currently have a problem with our build pipeline that prevents certain parts of our legacy codebase from being transpiled.
Subsequently parts of our codebase have to be written in ES5 in order to be backwards compatible with older browsers.
The problem we're having is enforcing the use of ES5 code within these legacy scripts. There are a lot of places in the code where ES6 features (let, const, destructuring, object shorthand) are already used.
Adding an eslint config with the ecmaVersion set to 5 is not ideal because of the way the parser throws an exception on reaching an es6 feature, subsequently meaning no additional linting of the file happens. So you need to resolve all es6 type exceptions before this becomes an option.
We are unable to undertake a grand refactor of the code like this at present. As some parts are still being actively worked on. It is, in a word, a sh*tshow.
My question is, short of building some custom eslint plugin that highlights es6 features, is there any other solution that I may have missed?
As per #VLAZ' suggestion
https://github.com/nkt/eslint-plugin-es5
using the following config in eslintrc:
{
"plugins": [
"es5"
]
}
Worked perfectly for what we needed it for.

Do I ever need explicit allowSyntheticDefaultImports if esModuleInterop is true configuring TypeScript transpilation?

I need confirmation on the following theory. According to TS docs, there are two options that can be set in tsconfig.json.
--allowSyntheticDefaultImports: Allow default imports from modules with no default export. This does not affect code emit, just typechecking.
--esModuleInterop: Emit __importStar and __importDefault helpers for runtime babel ecosystem compatibility and enable --allowSyntheticDefaultImports for typesystem compatibility.
When I google around, I see both being set to true (at least in regard to the behavior I'm aiming at). However, as far I understand the docs, TS and transpilation to JS, it makes no sense to use them both.
The way I figure, I might use the latter only and entirely remove the former. However, being cautious and humble, I'm not entirely certain and worry that I'm doing something less bright without realizing it at the moment.
I fear that it's something inappropriate that's going to bite me in the donkey later on causing hours of lamenting and hair-pulling while desperately trouble-shooting. The basis for the skepticism is that both options are available, so I'm inferring that there are four cases where all the combinations (true/false etc.) are required but I can't imagine which they are.
Is it entirely safe to skip --allowSyntheticDefaultImports if --esModuleInterop: true in compilerOptions? ANd if so, why do we have that option?
Bonus question: when is it required with all the four combinations (true/false) for those two options?
If you mean can you leave allowSyntheticDefaultImports undefined and define only esModuleInterop, the answer should be YES moving forward, but there has been an issue with this. PR #26866 seems to be a fix, only merged September 17, so it there may be some risk in the short term.
As why both exist, I believe these were both a part of addressing compatibility issues with imports of Babel-transpiled modules, the original PR added the allowSyntheticDefaultImports option to certain compile-time messages, but in practice didn't address the runtime behavior of the imports. So --esModuleInterop was added later. See TypeScript-Handbook/#816 for discussion of how to update the docs...
Well, my understanding is that the allowSyntheticDefaultImports is for being able to load CommonJS libraries in a simpler way if you target es6+ (in dev time) while esModuleInterop is for simplifying these imports (in runtime) if you target for example AMD (like I do).
According to the docs you shouldn't need to specify allowSyntheticDefaultImports explicitly if you have esModuleInterop enabled, but the reason I had to enable also the allowSyntheticDefaultImports is that Resharper seems to look at that that flag when doing syntax checking in Visual Studio. Sure it built and worked ok anyway with only esModuleInterop, but I got a lot of red warnings from Resharper until I enabled also the other flag.
According to the relevant documentation here : https://webpack.js.org/guides/typescript/, both options have different significance. Based on the project code and dependent library syntax, either/both options may be required.

How to get rid of editor’s error for object.key

I have the following code that basically gets some JSON data, looks for the keys with "servergenre", and saves the results in an array.
This is a follow up of this question.
let result = [];
Object.keys(data).forEach( key => {
if(/servergenre/.test(key)){
result.push(data[key])
}
});
Even though the code is working correctly, in some editors it raises syntactic errors:
"key": unsolvable variable or type key
"=>": expression expected
"if( / server...": formal parameter name expected
")){": , expected
"});": statement expected
Here is an image to show you where the errors are:
As I said the code is working fine, I just need it to be fixed or another approach to get rid of the errors.
Furthermore, many compressors and minifiers do not support this bit of code. So I can’t minify it.
Thanks in advance.
ES2015, formerly known as ES6, is a more recent version of JavaScript, which introduces features such as the => syntax for functions you are using.
Not all features of ES2015 are fully supported in all browsers, so many people who use it pass it through a compiler (“transpiler”) first to convert it to ES5, which is supported by all browsers. Babel is one such transpiler. But if you are only targeting newer browsers, that would explain why the => syntax is working for you.
You just need to change your editor settings to understand that syntax. Exactly how you do that depends on what text editor you are using. It could be that your editor's built-in JavaScript mode doesn't know how to read ES2015 syntax, and you need to either upgrade your editor or install a third-party plugin that provides an updated error-checker. Or it could be that your editor supports both ES5 and ES2015, and it thinks you are trying to write your project only in ES5. In this case you just need to go to the settings and tell your editor that you mean for this project to use ES2015 (or ES2016, which is currently the most recent version).
Fat arrows are ES6 syntax. If that causes trouble, just write good old ES5 :
let result = [];
Object.keys(data).forEach( function(key) {
if(/servergenre/.test(key)){
result.push(data[key])
}
});

SonarQube analysis fails on ES2015 syntax - but it's apparently supported?

It says here (http://docs.sonarqube.org/display/PLUG/JavaScript+Plugin) that the SonarQube JS plugin has supported ES6 (which I believe is also know as ES2015) since version 2.0.
I have version 2.8 installed in SonarQube 4.5.6, but I see errors like this in my analysis log -
17:54:58.185 ERROR - Parse error at line 21 column 17:
'individualIndex': -1,
'individualName': {},
'individualSearchResults': [],
'individualEmail': '',
'individualMobile': '',
'dunsNumberRequired': false,
'allDone': false
});
}
static actions = {
^
...and that looks to me like SonarRunner is tripping on the static keyword.
So - does SonarQube really support ES2015? Or do I need to configure it differently, perhaps? My config is as follows -
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.projectVersion=$BUILD_NUMBER
sonar.exclusions=node_modules/**,tests/**,bin/**,config/**,docs/
sonar.sources=.
sonar.javascript.lcov.reportPath=coverage/lcov.info
Thanks.
static actions = {
This is a static class property and those are not part of the ES 2015 spec. So the SonarQube JS plugin is right to complain about it. Class properties are currently at a proposal stage, so it's unclear when (or if) they will make it into the language.
The status and development of the ECMAScript language can be confusing at times. The fact that transpilers support most proposals (i.e. features that are not part of any specification yet) makes the situation even worse.
If you want to target a specific version of ECMAScript, but are unsure about the supported features, then you can, of course, consult the language sepecification. I can also recommend this compatibility table.

Is there support for static typing in ECMAScript 6 or 7?

Is there any support for static typing in ECMAScript 6? How about ECMAScript 7?
No.
But on the ECMA-Script Wikipage there is a paragraph about changes in ECMA-Script 7:
The Seventh Edition is in a very early stage of development, but is intended to continue the themes of language reform, code isolation, control of effects and library/tool enabling from ES6. New features proposed include promises/concurrency, number and math enhancements, guards and trademarks (an alternative to static typing), operator overloading, value types (first-class number-like objects), new record structures (records, tuples and typed arrays), pattern matching, and traits.
Which may interest you.
Though this isn't part of the ES6 spec, Closure Compiler enforces JSDoc argument type annotations in JavaScript code when using its Advanced compilation level. Type annotations are specified using comments so they're ignored in development, but when you build your app for a production release a type mismatch will result in a compiler warning or, optionally, a compiler error.
An example of an enforced JSDoc type annotation:
/**
* #param {string} stringValue
* #return {number}
*/
function toInt(stringValue) {
return parseInt(stringValue, 10);
}
var val = toInt("10"); // Good
var val = toInt(false); // NaN in development, but throws an error (optional)
// or prints a warning (default) at build time
As an added bonus, JSDoc can build API documentation using this same syntax. So it's also handy if you document your code.
But a warning: for Closure Compiler to do its advanced optimization magic, every engineer on your project has to follow certain strict coding conventions. The compiler cannot enforce types unless it can reliably figure out what your code is doing, and that means giving up some of JavaScript's dynamic and wishy-washy syntax. If you don't follow them, errors can creep into your app and they can be very hard to diagnose after the fact. Most popular JavaScript frameworks and libraries do not follow them, though you can sometimes work around that using Compiler's externs feature. (jQuery is supported using externs, for example.)
So if you do use it, make sure you test your app thoroughly. I personally wouldn't even consider using this feature on a web app unless it has a Jenkins build bot and near-100% automated test coverage that can be run against your code after it's been optimized. That's a lot of work and is not for everyone; it took me months to get one of my projects up to that level. But personally, I think it's well worth the effort.
For more information, check out Advanced Compilation and Externs and Annotating JavaScript for the Closure Compiler.
No, there is no support for static typing in either ECMAScript 6 (ES2015).
As for ECMAScript 7 (ES2016), there is no proposal at any of stages 1, 2, 3, 4 or stage 0 for static typing.
I've seen a few proposals/ideas for static typing appear on the es-discuss mailing list, but none of these have actually been proposed for ES7 (ES2016).
If you want static typing right now, you're probably best looking into TypeScript or Flow.
Althought it's not pure ES6, Google's AtScript extending ES6 with type annotations and compiles into valid ES6 code once the compiler gets public: AtScript primer
As an option you can take a look at EsLint plugin https://github.com/yarax/typelint
It's not static check, but optional. The benefit of TypeLint is using already existing app data to build and use types automatically, unlike for example TypeScript or Flow, where you have to describe complex types by yourself.

Categories

Resources