Is there an ESLint rule to detect if the code can be detected when it's not using guard clauses?
This is related to this post- https://elliotekj.com/2016/12/02/guard-clauses-in-javascript/
for example, this should HAVE a warning:
function doSomething(obj) {
if(obj) {
console.log('I did something');
}
return null;
}
This should have NO warning
function doSomething(obj) {
if(!obj) {
return null;
}
console.log('I did something');
}
I would prefer the latter. Please don't comment on the 'opinionated' aspect of this question. I just want to know if there is an ESLint specific rule or something similar that I can work with.
Or is ESLint even the right tool to detect/correct this kind of code style enforcement?
Thank you.
PS. I did do some research and did not found any rules that related to this my specific need on ESLint Rules. Now, I'm just a newcomer JS developer and would like to know if I miss anything that I should have checked before I go any deeper into writing my own rule.
There is no ESLint rule that will catch that (up to v5.8.0). You provided the source yourself :)
I'm all in for guard clauses but I don't think this is a feature coming anytime soon because it's very context dependent and difficult to correctly identify it on all cases.
A sidenote from looking at your snippet, if you want to follow ESLint best practices, you should be returning a undefined/void instead of null in cases you don't expect a value to be returned (check https://eslint.org/docs/rules/consistent-return#require-return-statements-to-either-always-or-never-specify-values-consistent-return)
how can i turn the following alert into an acceptable alert for ESLint?
svg.onerror = function() {
alert("File cannot be loaded");
};
My build fails because apparently i cant use "alert". I want to call this alert when there is an issue loading something. This code works successfully but it does not comply with ESLint.
http://eslint.org/docs/rules/no-alert
how can i modify my code to make it build successfully?
thanks in advance :)
If you think you have a good reason for not observing an eslint setting, then you can disable that specific rule for that specific line by specifying eslint-disable-line in a comment on the offending line, like so:
svg.onerror = function() {
alert("File cannot be loaded"); // eslint-disable-line no-alert
};
A better solution might be to implement a modal or show an error to the user in another less-intrusive way (eg: toggle visibility of an error element, or use something like Bootstrap's modal).
Some ESLint rules don't make sense to include in every project, and no-alert is definitely one of them. While critics might say alert is obtrusive, that fails to account for the fact that obtrusive can be good!
To disable this rule, disable it in your ESLint configuration file by setting it to "off."
...
"rules": {
...
"no-alert": "off",
...
}
ESlint: Turning off a specific rule across a project
I am working in one example and that at some point(when something specific happen) to stop the execution of javascript code.
Here is the row where I detect the error(rows number 36 at the DEMO):
if(error_print === null){
s += "errors+='"+"You have error in row :" + (i+1) + "';";
//here I want to stop the code execution
} else{ //continue...}
So I want:
1- to stop the code execution when this error is detected
2- to clean the #output textarea from the messages that are print before
(so if the error occured I want only to have the message error in the #errors textarea). So I dont want the #output text area to have this values:
This " is my first program
My name is XXX
but I want it to be empty after error detection.
I have tried to use return; and throw new Error('You have an error'); but these have not function. Please can you help me? Thanks in advance.
Here is the demo you can play with.
First, allow me to make a few remarks on the code in your fiddle:
an if inside a while inside an if inside an if inside an if inside a function, ... That is just horrible code to read and bugs waiting to happen. Please refactor that code (work with early returns, divide it up into functions, ...). My rule of thumb is never nest more then 2 levels deep. Good written code should document itself, and I can't realy say your code is self explanatory.
Why are you inserting that script bloc? I see no need for that at all. It is almost as bad as using eval()...
try to use sensible variable names. s may seem clear at the moment you are writing the code, but I promise you it won't in six months when you have to go and hunt down a bug.
Note that I am just trying to help you here, not trying to break you down.
As for your question, why don't you just keep a error boolean somewhere. Default it to false and set it to true when an error occurs. Before outputting your result, just s-check the state of that boolean. When it is true, don't output anything. That should be by far the easiest solution imo.
var hasErrors = false;
...
// an error occurs
if (this.notRight) { hasErrors = true; }
...
if (! hasErrors) {
$('#output').html(output);
}
I'm using SublimeLintern package, but I'm experiencing some issues. I would like to toggle that "laxcomma" warning that appears each time I save my files: I do prefer putting my commas at the beginning of each row
{
"item1": val1
,"item2": val2
,"item3": val3
}
Hence, I tried to look for some piece of documentation that explained how to enable or disable each check. I bumped into this that should explain what I need.
So, my SublimeLinter.sublime-settings is now like this:
{
"jshint_options": {
"laxcomma": false
}
}
but it doesn't seem to be working. I still see that bothering warning! What's wrong with my settings?
Bizarre. For me, the issue was that I had a .jshintrc file in the local directory of my project. Despite the fact that laxcomma wasn't being overridden there EITHER, apparently it just completely overrides your jshint_options (or maybe it does a top-level extend and doesn't recursively merge the config objects...)
The solution was to add (to the local .jshintrc file):
"laxcomma": true
The word "lax" means not strict or severe; if you want to put your commas at the beginning of each line, try setting "laxcomma" to true:
{
"jshint_options": {
"laxcomma": true
}
}
I'm looking into different ways to minify my JavaScript code including the regular JSMin, Packer, and YUI solutions. I'm really interested in the new Google Closure Compiler, as it looks exceptionally powerful.
I noticed that Dean Edwards packer has a feature to exclude lines of code that start with three semicolons. This is handy to exclude debug code. For instance:
;;; console.log("Starting process");
I'm spending some time cleaning up my codebase and would like to add hints like this to easily exclude debug code. In preparation for this, I'd like to figure out if this is the best solution, or if there are other techniques.
Because I haven't chosen how to minify yet, I'd like to clean the code in a way that is compatible with whatever minifier I end up going with. So my questions are these:
Is using the semicolons a standard technique, or are there other ways to do it?
Is Packer the only solution that provides this feature?
Can the other solutions be adapted to work this way as well, or do they have alternative ways of accomplishing this?
I will probably start using Closure Compiler eventually. Is there anything I should do now that would prepare for it?
here's the (ultimate) answer for closure compiler :
/** #const */
var LOG = false;
...
LOG && log('hello world !'); // compiler will remove this line
...
this will even work with SIMPLE_OPTIMIZATIONS and no --define= is necessary !
Here's what I use with Closure Compiler. First, you need to define a DEBUG variable like this:
/** #define {boolean} */
var DEBUG = true;
It's using the JS annotation for closure, which you can read about in the documentation.
Now, whenever you want some debug-only code, just wrap it in an if statement, like so:
if (DEBUG) {
console.log("Running in DEBUG mode");
}
When compiling your code for release, add the following your compilation command: --define='DEBUG=false' -- any code within the debug statement will be completely left out of the compiled file.
A good solution in this case might be js-build-tools which supports 'conditional compilation'.
In short you can use comments such as
// #ifdef debug
var trace = debug.getTracer("easyXDM.Rpc");
trace("constructor");
// #endif
where you define a pragma such as debug.
Then when building it (it has an ant-task)
//this file will not have the debug code
<preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.js"/>
//this file will
<preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.debug.js" defines="debug"/>
Adding logic to every place in your code where you are logging to the console makes it harder to debug and maintain.
If you are already going to add a build step for your production code, you could always add another file at the top that turns your console methods into noop's.
Something like:
console.log = console.debug = console.info = function(){};
Ideally, you'd just strip out any console methods, but if you are keeping them in anyway but not using them, this is probably the easiest to work with.
If you use the Closure Compiler in Advanced mode, you can do something like:
if (DEBUG) console.log = function() {}
Then the compiler will remove all your console.log calls. Of course you need to --define the variable DEBUG in the command line.
However, this is only for Advanced mode. If you are using Simple mode, you'll need to run a preprocessor on your source file.
Why not consider the Dojo Toolkit? It has built-in comment-based pragma's to include/exclude sections of code based on a build. Plus, it is compatible with the Closure Compiler in Advanced mode (see link below)!
http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t
Even though its an old question. I stumbled upon the same issue today and found that it can be achieved using CompilerOptions.
I followed this thread.
We run the compiler, from Java, on our server before sending the code to the client. This worked for us in Simple mode.
private String compressWithClosureCompiler(final String code) {
final Compiler compiler = new Compiler();
final CompilerOptions options = new CompilerOptions();
Logger.getLogger("com.google.javascript.jscomp").setLevel(Level.OFF);
if (compressRemovesLogging) {
options.stripNamePrefixes = ImmutableSet.of("logger");
options.stripNameSuffixes = ImmutableSet.of("debug", "dev", "info", "error",
"warn", "startClock", "stopClock", "dir");
}
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);
final JSSourceFile extern = JSSourceFile.fromCode("externs.js", "");
final JSSourceFile input = JSSourceFile.fromCode("input.js", code);
compiler.compile(extern, input, options);
return compiler.toSource();
}
It will remove all the calls to logger.debug, logger.dev...etc.etc
If you're using UglifyJS2, you can use the drop_console argument to remove console.* functions.
I use this in my React apps:
if (process.env.REACT_APP_STAGE === 'PROD')
console.log = function no_console() {};
In other words, console.log will return nothing on prod enviroment.
I am with #marcel-korpel. Isn't perfect but works. Replace the debug instructions before minification. The regular expression works in many places. Watch out unenclosed lines.
/console\.[^;]*/gm
Works on:
;;; console.log("Starting process");
console.log("Starting process");
console.dir("Starting process");;;;;
console.log("Starting "+(1+2)+" processes"); iamok('good');
console.log('Message ' +
'with new line'
);
console.group("a");
console.groupEnd();
swtich(input){
case 1 : alert('ok'); break;
default: console.warn("Fatal error"); break;
}
Don't works:
console.log("instruction without semicolon")
console.log("semicolon in ; string");
I haven't looked into minification so far, but this behaviour could be accomplished using a simple regular expression:
s/;;;.*//g
This replaces everything in a line after (and including) three semicolons with nothing, so it's discarded before minifying. You can run sed (or a similar tool) before running your minification tool, like this:
sed 's/;;;.*//g' < infile.js > outfile.js
BTW, if you're wondering whether the packed version or the minified version will be 'better', read this comparison of JavaScript compression methods.
I've used following self-made stuf:
// Uncomment to enable debug messages
// var debug = true;
function ShowDebugMessage(message) {
if (debug) {
alert(message);
}
}
So when you've declared variable debug which is set to true - all ShowDebugMessage() calls would call alert() as well. So just use it in a code and forget about in place conditions like ifdef or manual commenting of the debug output lines.
I was searching for a built-in option to do this. I have not found that yet, but my favorite answer also does not require any changes to existing source code. Here's an example with basic usage.
Assume HTML file test.html with:
<html>
<script src="hallo.js"></script>
</html>
And hallo.js with:
sayhi();
function sayhi()
{
console.log("hallo, world!");
}
We'll use a separate file, say noconsole.js, having this from the linked answer:
console.log = console.debug = console.info = function(){};
Then we can compile it as follows, bearing in mind that order matters, noconsole.js must be placed first in the arguments:
google-closure-compiler --js noconsole.js hallo.js --js_output_file hallo.out.js
If you cat hallo.out.js you'd see:
console.log=console.debug=console.info=function(){};sayhi();function sayhi(){console.log("hallo, world!")};
And if I test with mv hallo.out.js hallo.js and reload the page, I can see that the console is now empty.
Hope this clarifies it. Note that I have not yet tested this in the ideal mode of compiling all the source code with ADVANCED optimizations, but I'd expect it to also work.