A linter would be my guess. Most linters wont let you compile your code with more than 1 blank line between 2 blocks, but sometimes you just need to separate them with 3 or more lines. With this, you can circumvent it.
Highly recomment ESLint for JS-based apps btw.
tl;dr: The compromised version is eslint-scope 3.7.2, released about three hours ago. 3.7.1 and 4.0.0 are safe. If you've done npm install today, reset your NPM token and npm install again. You are affected if you've used eslint-scope 3.7.2, ESLint 4, or any version of Babel-ESLint (which hasn't updated to 4.0.0 yet).
It seems that the virus itself reads the .npmrc file, in order to get more tokens to compromise and spread itself.
Edit: NPM has now responded here with a liveticker. All login tokens created in the last ~40h were revoked.
Edit 2: Official Postmortem.
>The maintainer whose account was compromised had reused their npm password on several other sites and did not have two-factor authentication enabled on their npm account.
Moral of the story, that one IT sec nerd in the office trying to get us all to stop entering our passwords everywhere was right after all, I guess.
Agreed. This method (in the OP) of defaulting args violates no-shadow and no-param-reassign which both exist for good reasons, so personally I would avoid it.
But then, I'm an avid typescript fan and having to manually type check args just looks a bit laboured to me now. Also the suggestion that the only thing typescript can do is keep C# devs happy seems unfounded and slightly bitter which is unnecessary.
If you are following the one class per file rule, the function is still tightly coupled to the class.
However it is implemented, the function should be have regression tests. I can't agree that DRY code or code reuse is bad! Every class that reverses a string shouldn't have to implement string reversal itself.
Yeah I know, but it's generally good coding practice to include them. We also follow eslint rules who also recommend to include them (https://eslint.org/docs/rules/curly)
A lot of things but the most important of all Never ever reassign function parameters. There is an ESLint rule for this and I believe everyone should enable this in their projects.
This bit me badly because a dependency that I was using was reassigning some arrays that I passed and this caused very weird issues in my code. I solved it by sending a new copy of the array every time I used the dependency. I plan on fixing this upstream later this week.
I also realised how hard asset revisioning and live reload is.
Malicious eslint packages were published that stole your NPM credentials. If eslint were run in a sandbox disallowing HTTP requests, this wouldn't be as problematic. https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes
caniuse.com is an invaluable resource for determining which CSS is compatible with which browser. It also includes handy links to external references, alternatives, and workarounds.
CSS linting, like javascript linting, is also invaluable in helping you improve your CSS, and stick to "best" practices, and ensure maximum browser compatibility and code stability.
Hey mate this is an ESLint rule - you can configure ESLint rules to your liking with a .eslintrc.js
file.
The specific rule you're talking about is this one https://eslint.org/docs/rules/no-unused-vars
In your ESLint config file, you can specify if this rule should be an error or a warning or off.
"off" or 0 - turn the rule off
"warn" or 1 - turn the rule on as a warning (doesn't affect exit code)
"error" or 2 - turn the rule on as an error (exit code will be 1)
​
I don't know exactly what you'll need to put in the eslintrc file but it'll be something like:
"rules": {
"no-unused-vars": "warn"
},
​
Up to you but I'd recommend just spending 5-10 minutes understanding how to configure
ESLint to your liking as well, if you're planning on continuing to use the plugin.
Look into linters, specifically eslint, and no-multiple-empty-lines: https://eslint.org/docs/rules/no-multiple-empty-lines
(Edit: hard to believe that I'm doing this. I don't even like eslint and its stupid rules.)
ESLint's documentation for their no-unexpected-multiline rule details some examples where omitting semicolons causes errors.
Line starts with (
var foo = bar (1 || 2).baz();
Line starts with [
var hello = 'world' [1, 2, 3].forEach(addNumber);
Line starts with `
let x = function() {}
hello
Line starts with Regex
let x = foo /regex/g.test(bar)
You'll notice that most of these cases involve creating expressions without assigning a reference to them, so they're typically pretty rare in real code.
What do you mean? This is good: const someFunction = () => {}
, and this is also good: function someFunction () {}
. In the later case, the name "someFunction" gets assigned to the someFunction.name
property, so it can show up in your stack traces and debugger. That's helpful, but not a deal-breaker either way. The first case is arguably prettier.
A less-good option is let someFunction = () => {}
. You should always use const
wherever possible. There is even an eslint rule, prefer-const, that will complain about any let
or var
uses where you don't actually change the value later. Enabling this rule is probably a good idea.
Another option, var someFunction = function () {}
, seems really old-school. I have no idea why you would want to do this. Just use arrow functions, unless you are taking advantage of some obscure Javascript scope rules.
https://eslint.org/docs/2.13.1/user-guide/command-line-interface
eslint --fix
Fix your linting errors as you develop, and they won't pile up. Get in the habit of abiding by your linting rules so you don't have errors to fix. It'll make you a better developer in the long run.
You may need to update your configuration. The no-undef rule should flag that if its turned on.
Edit: BTW, you can play around with things in https://eslint.org/demo and download the config when you got it where you like it (link at the bottom with config box open).
That sounds like the output of eslint. Are you building your project for production
? That should remove all that logging by default.
Alternatively, if it is a eslint issue, there's likely more information shown there, you should find out which one it is and change the rule to your liking - [eslint.org|https://eslint.org/]
ESLint is configurable, here's one of the settings that allow you to customize it. It's down to your specific ESLint config to decide which one you use.
One of the popular styles is StandardJS (and Semi-Standard for those who like semicolons), and it uses this style:
let answer = everything ? 42 : foo
As always, bleeping computer likes to jump on the game late and click bait the fuck out of it.
Previous discussion that occurred less than a day ago (and coincidentally this time it was my post :P). Was also crossposted to /r/javascript.
Another couple tips from a guy who started self taught and has been working in it professionally for a while now:
Make it fun. Build stuff you like and you'll use. Coding is a creative exercise.
Learn how to set up a linter and find a style guide that your language supports. Having consistent code style makes it way easier to focus on the big things when you're reviewing your code and also makes it much easier to go back to after some time away.
If you're using JS, I really like eslint with Airbnb's style guide:
The point of that eslint rule is to avoid mutating function parameters. In general you probably want to prefer an immutable approach, which is what the rule recommends.
However, mutating the request object is exactly how express middleware is supposed to be done. It looks like there are options you can pass to the rule to prevent it from throwing when using req
params. See ignorePropertyModificationsFor
.
Yeah I read that React throws Promises to simulate algebraic effects, and I agree with why it defaults to unknown
.
I guess I was hoping for a way to enforce this within my own codebase in TypeScript itself, not a linter (I'm aware of no-throw-literal), to also get the benefit of not needing to check every single catch
clause. Seems like there's no way around it unfortunately, and I'm stuck working in a codebase with exceptions thrown around everywhere.
> I proceed to install ESLinter
OK, so you've chosen to use ESLint to lint your codebase.
Have you followed the Getting Started page from ESLint's documentation?
This gets you started with ESLint itself. You can use ESLint in many code editors. To use ESLint in VS Code you need to installed the extension for ESLint.
Between the Getting Started and the instructions in the extension itself are you running into any further blockers or issues?
What you want is called a linter. For js/ts the most common linter is eslint.
Quote: > Unlike scripts, ECMAScript modules are always in strict mode. Strict mode directives in ECMAScript modules have no effect.
https://eslint.org/docs/2.0.0/rules/strict
"Strict" is implied in modules, and if you aren't using esmascript modules yet, you probably should. IMO
This is a common misconception.
You don't actually get to skip dealing with ASI (automatic semicolon insertion) just because you place the semicolons by hand.
Case in point:
function something() { return somethingElse(); }
Even though you placed the semicolon by hand, ASI will place a semicolon just after the return, and the code will unexpectedly return undefined
.
The actual way to solve this (apart from learning the ECMAScript standard by heart) is to just use a linter. no-unreachable flags this one as an error. Also, semi and indent make it trivial to spot ASI-related issues.
All things considered, using semicolons everywhere doesn't provide any objective advantage. And in my opinion you should just pick a style (any style is fine) and just have your linter enforce it.
Not really, it's sort of personal preference. I would say what's most important is that whatever you decide to use between the two, just be consistent. There's a lot of opinionated ESLint rules to help you with that.
Unicorn has an ESLint rule no-fn-reference-in-iterator to prevent this gotcha.
It would enforce
let date = "2020-12-12"; let dateParts = date.split("-").map(parseInt);
To be refactored into
let date = "2020-12-12"; let dateParts = date.split("-").map(str => parseInt(str));
And then ESLint's radix would enforce
let date = "2020-12-12"; let dateParts = date.split("-").map(str => parseInt(str, 10));
That Unicorn rule was a little hard for me to get comfortable with, but it's definitely useful in cases like this.
Generally, I try to avoid parseInt()
in favor of Number()
unless I expect that the value may contain units on the end, such as 12px
.
Use ESLint and Airbnb react rules. Palantir has abandoned react rules for TSLint and has really stopped giving TSLint love to the point where Microsoft even started support ESLint.
ESLint has better compatibility now vs before. They now also have TS specific rules if you use the TS parser.
You can learn more here: https://eslint.org/blog/2019/01/future-typescript-eslint
There are style guides out there that are fairly well respected by everyone. Airbnb's style guide is about the top one, and Eslint has an option to automatically select Airbnb's guide when you install it:
https://github.com/airbnb/javascript
The other thing you can do if you haven't already is learn Typescript, which is just Javascript with types added, and that will give you the ability to let your editor (like VScode for example) alert you that you're using Javascrpt in ways you probably shouldn't as you are coding rather than finding out at runtime (or possibly never).
Edit: sorry I only just now noticed you said you're already learning linters -- so that's good. Are you using ES6 modules and imports/exports? If not then start doing that -- it will be the #1 most important way to ensure you are properly organizing your code into independent modules.
Honestly though as to your final question, the best way to know if you should publish code and apply for jobs is to ask yourself:
Those two questions are way more important than whether the style is correct. You'll miss out on a way way more jobs holding out waiting for your code to be perfect than you will applying to jobs that tick off both #1 & 2 above. Good employers understand that style is easy to fix -- a solid understanding of the language/framework itself takes more time.
Good luck!
Call group
using bracket notation. Dot notation doesn't work with variables.
Also, matches
is an array. You should specify which member of matches
you want to call. For example, if you just want the first match:
group = groups[i] var home_team = resultJson.groups[group].matches[0].home_result
Yeah, something like that would be awesome.
I had to help out with a project recently, and I've not really done anything big with node/frontend JS, but I found out that with "create-react-app" things become much easier, as it sets up webpack/babel and deployment for you, along with a hot-reload dev server so you can hit the ground running.
After that I just installed VS code and "ESLint" with "vscode-eslint", and things were peachy.
> Is it returning the value returned by reject(err)?
Yes.
But return;
returns the value undefined
, and nothing actually looks at this function's return value, so the behaviour is the same either way.
He probably wrote it the way he did because it's shorter, but I wouldn't recommend copying him.
Lots of people would prefer your versions, since they're clearer to read, and, it's extremely minor, but there is a justification for returning the callback's result at the end, instead of doing the callback, then returning nothing.
So return resolve(rows)
is the way I'd write it.
Async is pretty well useless without await, which is why the feature is always referred to in the pair "async await".
Theres an eslint rule that you should turn on so you don't accidentally do this: https://eslint.org/docs/rules/require-await
But none the less, as an example...
async function foo() { await Promise.resolve()
return true }
And
function foo() { return Promise.resolve() .then(() => true) }
Are exactly the same thing - though IMO the first is more readable than the second.
edit formatting. stupid mobile.
I'll take a crack at it.
"First, on my getOrderBook and getTicker function I can't find a way to return the values without first assigning to a variable."
See this: https://eslint.org/docs/rules/no-return-await
So it looks like the linter will complain if you directly return await, but it's not really a problem and the warning can be disabled? Am I reading this wrong?
To clean up the 'then' callbacks, you can always move the refactor the function and call something like getOrderBook().then(handleOrderBook);
getTicker().then(handleTicker);
I would also get rid of that global state (the 'lets') and have getCurrencyData do what the function name says... get the currency data. Your function currently 'sets' the currency data on some global variables.
If you use eslint you can enable the no-debugger and no-console rules:
In fact they already come enabled in most popular presets.
That way you can use them in development but the moment you try to build for production it will yell at you.
Refactoring is something i can definitely dig 👍 but i can't see some of the more important features most refactoring tools provide (e.g. extract class, extract method).
Refactoring has an implicit meaning of restructuring / regrouping code. But most of the features in this extension (with a few exceptions) aren't actually restructuring anything, they're just rewriting the same thing with more readable syntax... re-syntaxer, re-adable?
For the features that actually do something closer to restructuring, noteably:
I'd suggest splitting them out into their own extension.
For whatever's left, it might be worth seeing if there's any code you can merge directly with eslint (make auto or manually fixable) as there's still quite a few rules that aren't covered that may have some overlap.
Example:
The rule prefer-spread
: require spread operators instead of .apply()
under the ES6 Ruleset.
This is currently not auto-fixable by ESlint (no wrench icon).
Ultimately you should probably set aside some time to fix these lint issues. If you're using a lint configuration and most of the project is ignoring it, then you're probably not getting a lot of lift out of using a linter and it kind of defeats the purpose.
In the mean time, you could do one of two things:
You are looking for ESLint. Here's the specific rule which would have caught that "error". But it's not a syntax error. It's totally valid, but rarely what you intended which is why linters exist. I highly recommend configuring ESLint. It also has great editor integrations so you can get red underlines while writing code in your editor in real-time.
It's a neat reminder that in most cases Promise.all()
may be appropriate, but using await
in a for...of loop is still the way to go when the iterations need to happen in order.
Here's what the rule has to say about that:
>In many cases the iterations of a loop are not actually independent of each-other. For example, the output of one iteration might be used as the input to another. Or, loops may be used to retry asynchronous operations that were unsuccessful. Or, loops may be used to prevent your code from sending an excessive amount of requests in parallel. In such cases it makes sense to use await
within a loop and it is recommended to disable the rule via a standard ESLint disable comment.
https://plugins.jenkins.io/warnings-ng/ will let you import whatever format you want
https://eslint.org/docs/user-guide/formatters/ has some of eslint formatters. You can tell eslint to format as checkstyle and then import with warnings-ng
I created https://www.npmjs.com/package/eslint-formatter-multiple a year ago to allow stdout and a file formatter
I like #2 better and I disagree with the commenter on that link.
The commenter suggested that code was bad because of its use of rest parameters, asserting that "the correct keyword is arguments
".
I'm under the impression nowadays that arguments
is no longer the recommended approach.
arguments
, it's not declared as the function's parameters, which is inconsistent with other functions.arguments
object doesn't exist for arrow functions.It's a standalone tool that you can run from the terminal/command line, but there are vscode integrations
IMO this is a required tool for JS projects. there are lots of different rules and plugins so that you can set up that will catch so many different issues, enforce code styles, fix problems automatically etc
Those js examples are related to scope concerns not present in VBA I agree. For a better comparison you want the section on "initialized and uninitialized". Also see the link to the "standard" style guide, which says this:
>
> * For var declarations, write each declaration in its own statement.
>
> eslint: <code>one-var</code>
>
>
> // ✓ ok
> var silent = true
> var verbose = true
>
> // ✗ avoid
> var silent = true, verbose = true
>
> // ✗ avoid
> var silent = true,
> verbose = true
There is some discussion on this from a language-agnostic perspective here: https://stackoverflow.com/questions/100633/why-do-you-not-declare-several-variables-of-the-same-type-on-the-same-line
Seems to be that the benefits cited for using a single line per variable declaration are:
How much you agree with/value those points is up to the user at the end of the day, but I'd say the majority (even if not an overwhelming number) of people seem to agree with it as something of a best practise.
Still ultimately a stylistic choice.
Since you say that there is a bug here, which bug is it? Is it that 2 numbers are being concatenated or that 2 strings are being added? Its not obvious; you cannot immediately see which is the intended behavior.
This is why I advocate for always using string templates when concatenating (prefer-template helps a lot) so that there isn't any way to be confused about which behavior is intended.
ASI has the potential to screw up code regardless of whether it uses or omits semicolons. In other words, using semicolons does not save you from unexpected insertions.
ESLint has a rule to warn of these situations: https://eslint.org/docs/rules/no-unexpected-multiline. Since ASI happens regardless of coding style, this rule is useful for everyone, hence its inclusion in the “eslint:recommended” rule-set.
In conclusion, use eslint and then use or omit semicolons as you please.
It's reasonable in theory to do that - the pattern is fairly unusual, but I can't really comment on that without seeing the wider context
A bigger problem is that you're queuing up promises in a loop though. Those can be parallelised - https://eslint.org/docs/rules/no-await-in-loop
It comes more naturally over time. One thing you should do, if you haven't already, is set up your code editor with eslint. That will help guide you in the right direction when you slip up and make mistakes or just in general in some cases with best practices.
You can do it with eslint, it won't catch runtime errors but it will do for the example you gave. Here's a test I just wrote up...
#!/usr/bin/env node
const Linter = require("eslint").Linter;
const linter = new Linter();
const code = `console.log('asdfasdf');
alert('asdf');
this is not valid javascript
alert(pickles);
console.log('hi there');
// This comment was already here
hello, world!
this.is.valid.javascript();`;
function commentBrokeLines(code){
const messages = linter.verify(code);
if(!messages.length) return code;
var lines = code.split("\n");
for(let i=0; i<messages.length; i++){
lines[messages[i].line-1] = `\n// ${messages[i].message}\n// ${lines[messages[i].line-1]}\n`;
}
return commentBrokeLines(lines.join("\n"));
}
console.log(commentBrokeLines(code));
Output is:
console.log('asdfasdf');
alert('asdf');
// Parsing error: Unexpected token is
// this is not valid javascript
alert(pickles);
console.log('hi there');
// This comment was already here
// Parsing error: Unexpected token !
// hello, world!
this.is.valid.javascript();
Best described here:
https://eslint.org/blog/2019/01/future-typescript-eslint
More of my personal opinion tbh but I’ve seen projects that might have a few js files mixed in (like config files) so eslint feels a little more flexible
Oh, my bad. I overlooked that last time.
The issue is that with let diceEmoji
you're creating a new variable inside each if statement. This variable "shadows" the original variable with that name, and is then discarded at the end of the if block. So outside of your if statements, diceEmoji
will always be ":diamond_shape_with_a_dot_inside:".
Just remove the let
at the beginning of the assignments inside the if statements to fix that.
(Incidentally, ESLint's <code>no-shadow</code> rule would have alerted you of this.)
Your webpack.config.js
has a few syntax errors - missing commas, etc. You'd see these if you just try to run node webpack.config.js
, though I'd recommend setting up a linter such as ESLint.
Here's a fixed webpack.config.js
:
const path = require('path'); module.exports = { entry: './src/js/main.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, module: { rules: [{ test: /.css$/, loaders: [ 'style-loader', 'css-loader' ], options: { import: true } }] } };
Un linter ne peut pas inférer les type des variables que tu compare. Donc le jour ou par erreur tu comparera par double égal deux variables de type different mais castable, t'aura aucun filet pour empêcher l'erreur.
C'est pas pour rien que les linters on justement des règles pour forcer à utiliser le triple égal (https://eslint.org/docs/rules/eqeqeq)
Après si tu fait du typescript c'est différent puisqu'il peut inférer les types, mais ça n'est pas un linter
It's a bit too late to be saying this, due to the widespread prevalence of
==
operatorin the javascript community
The original rationale behind dynamic typing has become largely obsolete as developers have realized how silly they are. This doesn't mean dynamically typed languages are obsolete or even that they were designed badly in the first place, but it means a lot of developers will use them like statically typed languages.
The adminSection
isn’t properly closed off. It should look like this:
adminAuth: {
type: "credentials",
users: [{
username: "user",
password: "pwhash",
permissions: "*"
}]
},
To help catch these kinds of errors you can use a linter. ESLint is a popular one for JS which you can use online here: https://eslint.org/demo/
Really good counter point; and the only one which is justified IMO.
One of the principles of secure dev is minimising your attack surface and a large dep tree does the exact opposite.
Mitigations but no real solutions:
According to their blog, its possible that their account had a weak password or an easily brute-forced password or their npm account doesn't have 2FA enabled.
Unless you understand what the other person means, you don't defend it. Assuming you want to defend JS, this is what I do, maybe it will be helpful to you:
Admit you don't understand what they mean. Nothing wrong with this. Being willing to learn shows that you aren't defensive and come from a position of strength. Ask them to explain what they mean by "coercion double equals the this variable problem callback hell". And for them to give concrete code examples of what happens and what problems it causes. At this point about 90% of these types of debates end because the other person is usually regurgitating something they heard from someone else and they actually can't explain what that means. Or it will end up being a problem only in theory and there aren't any concrete examples of it causing a problem for most developers.
In the rare case they aren't trying to BS, actually learn from them what they are talking about. And once you know what category that feature falls into, do your research on the pros on cons. Let's say someone is complaining about dynamic typing vs. static typing. If you don't already know the pros and cons of both, how could you possibly defend your position? You need to hit the books, talk to other devs, and maybe even give both a try in real life to be able to come back with a reasonable defense.
Be honest when JS really does have a wart. No language is perfect. You'll hurt your own credibility if you want to insist that type coercion + boolean evaluation in JS doesn't have some awkward surprises. A language is the sum of its pros and cons. JS has so many pros we can easily live with the cons. Not to mention that with a tool like ESLint (e.g. https://eslint.org/docs/rules/eqeqeq) you can easily avoid the large majority of the warts in JS without even being an expert in what those warts are.
There are tools that help checking your JavaScript code, such as eslint. Be warned that this tool is quite opinionated and can complain about style issues as well. Then again, it is highly configurable, so you can have it match your style.
>but are these rules made to make consistencies on things
Yes. They help automatically enforce code quality. A team can pick exactly the rules they want to adhere to. You can even write your own custom rules without too much difficulty (if you have some experience manipulating ASTs, anyhow)
You can read about each rule in the ESLint documentation
https://eslint.org/docs/rules/class-methods-use-this
https://eslint.org/docs/rules/no-trailing-spaces
> Sometimes in the course of editing files, you can end up with extra whitespace at the end of lines. These whitespace differences can be picked up by source control systems and flagged as diffs, causing frustration for developers.
Also, this isn't a React question.
That's the kind of mistake that linters are for. I mostly write JS and ESLint has a rule to prevent that kind of mistake without sacrificing readability of the code.
Couple of suggestions:
Looks fab though for the most part.
Generally, just use a formatter and linter and do whatever those suggest. For web stuff https://prettier.io/ is a good formatter to use and eslint https://eslint.org/ a good linter. Though eslint does try to enforce style as well which conflict with prettier, but they can be configured to work together: https://www.benmvp.com/blog/prettier-eslint/
> i DO understand the problem with using await in a loop bc i have experienced it first hand.
Nah, guy, you just experienced your own shitty code first hand.
> those eslint rules are pointless.
There's two of them now? I figured you were referring to no-await-in-loop
which, just like everything else I've seen and you've shared, points out that it isn't always applicable.
Seriously. You haven't shown me a single thing that says anything about unexpected behavior, which is what you actually asserted, and what I wanted to know about.
Apparently, backticks won't work in import statements or strict mode pragmas, according to this comment: https://github.com/airbnb/javascript/issues/2015#issuecomment-467092251
Other than that, using backticks all the time should be fine. You can even set your linter to require backticks wherever possible, as described here: https://eslint.org/docs/rules/quotes.html
It didn't take very long. That's a very short piece of code.
For the most part, it's about the same as normal typing to type the code. It's thinking about the code that takes the most time.
Sometimes it's faster than normal typing when you have some tricks you can use. In my editor, I can select a word and press CTRL + Shift + L
to edit all occurrences of that word in my file.
I made a couple of changes to the formatting after I typed it, but a lot of developers don't even need to do that. Many have formatting automated with tooling such as ESLint and Prettier.
With those tools, formatting rules are already defined and you can set it up so that it automatically formats your code when you save the file.
First, you have confused your syntax somewhat. There are basically three (or more!) ways to declare functions. You didn't get any of them quite right.
Function Declaration:
function square(n) { return n * n; }
Function Expression:
const square = function(n) { return n * n; }
Arrow Function:
const square = (n) => { return n * n; }
I would also add that arrow functions have very . . . flexible syntax. If you have a single parameter, you can omit the parentheses. Also, if your function body is just a single expression that you return, you can omit the curly braces and return statement.
Arrow Function (implicit return):
const square = n => n * n;
This is something to get used to with JavaScript. Remember how much of a pain the switch from Python 2 to Python 3 was? How years later, many tools and documentation still were written for Python 2, even after it was deprecated?
Well, for better or worse, JavaScript doesn't do that. JavaScript is backwards compatible all the way back to version 1. Adding a breaking change to JS would mean breaking existing web pages, and that is a non-starter. So all changes to the JS syntax are additive. These days we mostly use const
and =>
, but var
and function
are still there and still work fine.
The way most developers handle this is with a linter, specifically ESLint. A linter can enforce a consistent style across your code base, but more importantly it can reduce the amount of valid JavaScript. You really only want to worry about a subset of the syntax. A linter can automatically flag old stuff and enforce things like "one correct way" to write a function.
This Eslint rule will prevent accidentally mutating function arguments: https://eslint.org/docs/rules/no-param-reassign
And possibly this: https://typescript-eslint.io/rules/prefer-readonly-parameter-types
It doesn’t exactly solve your problem, but it would prevent you from accidentally mutating the inputs.
At work we use Eslint on all projects and lint errors causes a build failure on CI. With this rule in place your linter would have warned you of problems immediately when you did your refactor.
Well, I don't think I misunderstood. The issue isn't in Gitlab, it's with eslint
. One of your parameters causes an exit 0, one of your parameters causes an exit non-zero. Gitlab is doing exactly what it's supposed to do.
> Fixing problems: > --fix Automatically fix problems > --fix-dry-run Automatically fix problems without saving the changes to the file system > --fix-type Array Specify the types of fixes to apply (directive, problem, suggestion, layout)
https://eslint.org/docs/user-guide/command-line-interface
--fix
is fixing your issues, correctly making it pass (zero code). Without, it's not, you have problems, ergo, non-zero code.
Personally, you should probably fix the errors rather than just ignore them. You didn't specify exactly what TS error you're getting to it's hard to know. If it's not really something that should be an error you can force it to be a warning instead.
Shit, is this why all my linting scripts are giving me this error?
ESLint 7.32.0
ESLint couldn't find the config "airbnb-typescript-prettier" to extend from. Please check that the name of the config is correct.
The config "airbnb-typescript-prettier" was referenced from the config file in "[redacted]"
If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.
> So in the first example, because of no callback even thought it uses the previous state , it might be correct but it’s not guaranteed to be the correct form data.
Your takeaway is correct. State updates are asynchronous, so they can be batched together if a bunch happen super close together, we can reduce how many times the component tree has to rerender.
Like 99% of the time, just passing in the state like in the first example is fine, but the callback update guarantees it to be fine every time.
> Do u only need that for objects?
Nope, that's just a weird, ES6+ JavaScript syntax thing.
// These functions are the same: const function1 = (x) => console.log(x); const function2 = x => console.log(x);
If you only have one argument to a function, you don't need the parenthesis. To use it or not is a stylistic choice, some linting rules have opinions on it, but there is no functional difference.
You can use Promise.all
with async/await
const getPokemon = async () => { const response = await axios.get('https://pokeapi.co/api/v2/pokemon?limit=100'); const results = response?.data?.results || [];
return Promise.all(results.map((res) => axios.get(res.url)));
}
await
is just syntax sugar for promises. You don't have to use a for-loop just because you're in an async/await block.
90% of the time you'll want to avoid using await
within a loop, unless you specifically want to do a group of async operations one at a time. There is even an eslint rule for this: https://eslint.org/docs/rules/no-await-in-loop
I dunno whether this is gonna work for y'all, First created a .eslintrc.json
file in the root directory and pasted the code mentioned below. Please take a backup of ur project before proceeding not to mess up in any scenario.
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
},
"parser": "esprima"
},
"rules": {
"semi": 2
}
}
For further info please visit https://eslint.org/docs/7.0.0/user-guide/configuring
thank you!
Most minimal and preferred solution is to make functions and classes fit on one screen in the editor. I usually find if they are over about 50 lines then they need refactoring.
https://eslint.org/docs/rules/max-lines-per-function
If you don't believe me, listen to Martin Fowler:
"Any function more than half-a-dozen lines of code starts to smell to me"
The package I linked has it all configured appropriately. You just need a file with that name as shown in the root of your package (next to your package.json
file). See the docs for more details: https://eslint.org/docs/user-guide/getting-started
I think in general I prefer not using return resolve()
and would probably enforce it using no-promise-executor-return.
I think this is fine:
if (true) { resolve(); return; }
But I think return resolve()
is easy to overlook.
You can use no-restricted-syntax rule to ban arbitrary js/ts/jsx syntax.
'no-restricted-syntax': [ 'error', { selector: 'ArrowFunctionExpression[body.type=JSXElement]:not([returnType])', message: 'Functions returning JSX.Element must specify return type explicitly', }, { selector: 'ArrowFunctionExpression:not([returnType]) ReturnStatement Literal', message: 'Functions returning JSX.Element must specify return type explicitly', }, ],
This will work for
() => { return <whatever />; }
and
() => <whatever />;
This doesn't actually do any type inferring, just queries AST, so it won't work if you return a call of another function which returns a JSX element.
() => whatever(); // No error
const whatever = (): JSX.Element => <whatever />;
You can make whatever rules you want (as long as they don't require type inferring), you just need to build the correct esquery. You can use this https://astexplorer.net/ just set it to @typescript-eslint/parser to make it recognize ts and jsx.
A linter is a tool that analyzes your code for how it is styled (where do curly braces go etc) but can also do things like checking if variables are correctly named or not mutated. In the webdev world 2 popular linting tools are https://prettier.io and https://eslint.org :)
I mean, it should work without an issue. eslint is just forcing you to explicitly assign an expression to a variable https://eslint.org/docs/rules/no-unused-expressions
Depends on what you're formatting?
I assume you mean for more web-y stuff since that's what prettier is about?
For CSS and derivatives, stylelint has formatting options, but it will make your config file extremely verbose. The same for JS / TS and ESlint.
The prettier formatter was made with the goal (mostly) of handling the whitespace options of the above 2 formatters so you wouldn't have to set them manually, that's where they opinionated stuff comes in.
But that doesn't mean you cannot handle it with just stylelint / eslint.
I find the inbuilt VScode formatter to be the best for HTML.
** IMPORTANT:** Set your .editorconfig
file first. It will ensure (assuming the editor in question has the editorconfig extension) that files are created with the proper format settings.
Then when you implement stylelint / eslint, make sure you use the .cjs
version of the config file. Because it means you can require .editorconfig
, parse it as a JS object, so that it will automatically pull in the correct settings (e.g. tab width, etc) that stylelint / eslint should be using.
It looks like you're using a very opinionated code style linter that doesn't just autofix your code for you. I would advise you to use prettier as it will automatically format your code in a consistent style, and eslint for linting other code quality issues as it is by far the most popular linter for JS today. However these are very subjective opinions and I'm sure some will disagree with me.
Anyway, to get your code to pass the JSLint rules, you can assign playerOptions1[prop]
and playerOptions2[prop]
to temporary variables:
function combinePlayerOptions(playerOptions1 = {}, playerOptions2 = {}) { const combined = Object.assign({}, playerOptions1, playerOptions2); Object.keys(playerOptions1).forEach(function checkObjects(prop) { if (typeof playerOptions1[prop] === "object") { const first = playerOptions1[prop]; const second = playerOptions2[prop]; combined[prop] = Object.assign({}, first, second); } }); return combined; }
It's rarely called legacy, so you may not use the right definition
If you want a more objective answer, you can use a linter like ESLint and use their default ruleset to decide what is and isn't acceptable in a codebase. They have a rule about usage of "var"
Ohh those aren't actually errors at runtime in your program but rather linter errors. The goal of a linter is to enforce best practices in your code and prevent coding patterns which often lead to errors. Those may be indicators of an issue in the code, but also may not be.
For example the no-unused-expressions rule is described at that link where you can see what is allowed and prohibited and why.
I have always used eslint's "smart" eqeqeq rule:
https://eslint.org/docs/rules/eqeqeq#smart
It allows variable == null
to check for null and undefined at once. Have heard criticism that it's not super readable. I just can't stand normal undefined checks.
... like eslint for javascript for example.
They're called linters and formatters, you might want to get one for your languages. You can usually hook them up with most editors, so it underlines your formating violations in yellow or something, and most editors can run the autofix of linters to reformat the code back to standard.
Dedicated config files, JSON if I can get by without running logic, JS otherwise.
package.json
. It is meant to be machine- and human-readable project metadata. Why should I know about your eslint config when I just depend on your package?> because YAML allows comments
You can also use comments in .eslintrc.json
and .js
.
> wading through the clutter in my project root directory
Where possible and not too troublesome, I put config files inside a subdirectory (tooling/config/
for me). But I do still have quite some config files at my project root for stuff that either straight-up does not accept a config file in a subfolder (e.g. c8
, ava
) and when where you put the config file matters (e.g. eslintrc
, tsconfig
).
You get immutability with an eslint rule that's on by default: https://eslint.org/docs/rules/no-func-assign
You can also ban hoisting with another eslint rule: https://eslint.org/docs/rules/no-shadow#hoist
I think starting a line with function functionName...
instead of const functionName = ...
makes it clearer that you're defining a function. And I think that readability is more useful than some things you can just enforce with a linter.
That's quite the nuclear option when you could just turn on the eslint rule that disallows implicit type conversion, and enforce it in a pipeline or a pre-commit hook.
TypeScript also does what you want, btw, although I haven't found myself needing to use it so far.
But yeah, I hear you, but there are probably very good reasons the web didn't develop around serving up binaries and DLLs (security comes to mind). IMO, JavaScript is in a great place these days. It is highly modular and can be made into what you want. There are a bunch of interesting frameworks to use, both for rendering and for state management. The language gets new features pretty frequently. Most importantly, it's easy as fuck to pick up, which is essential given the army of inexperienced developers joining the ecommerce ranks.
That being said, I'd only use it for front end web dev, and possibly for server rendering (to share rendering code). Otherwise you're kinda using a hammer on a screw.
I've been programming for 25 years, taught at hacker schools, shipped code to 100s of thousands of people, led cloud development at a major Canadian startup for a while. Some days I feel like I can do this pretty well and some days I don't. It just depends on how many unknown unknowns I get hit by in a given afternoon and how I manage my own expectations around them.
Basic syntactic mistakes? Those get less common with practice but at the end of the day every senior developer (at least that I've met so far) makes mistakes in one way or another.
More importantly whether your "good" today, tomorrow, or next Tuesday is less important then whether your steadily becoming more experienced and finding ways to enjoy that process.
If you are prone to moments of negative self-reflection try not to beat yourself up - look to enjoy coding as you do it (especially if it's what you want to do for the rest of your life!) and it will go better in the long run.
Like you said, "good" is subjective but I would add that it tends to be an ever shifting goal post. As we learn and broaden the domain we are knowledgeable in we become aware of new interests in previously unknown niches and so through learning we naturally realize new ambitions and shift the meaning of "good".
Some disciplines are surprisingly shallow in material to learn and easily absorbed in an afternoon or a week whereas other disciplines are deep like an ocean. Programming is in the latter category and can be a life long exploration to the degree that you'd like it to be that.
PS. Now to round off my novel of a reply with some unsolicited javascript: Semicolons aren't actually required at the end of javascript lines in most situations but follow your teams convention on this / eslint will give you amazing feedback and help you solve lots of javascript problems / enabling visible whitespace in your editor will make it much easier to catch those spacing mistakes.
I wonder if the company actually measured the solution performance or if they simply saw code that wasn't performant. For instance I took over a project, and in hundreds of places I saw code like this.
$('.foo').attr('class', 'bar'); $('.foo').attr('style', 'something'); $('.foo').attr('id', 'buzz');
Instead of assigning $('.foo')
to a variable the previous developer queried for the element over and over.
Problems in your code like the above could be discovered by using eslint. It will point out the commonly made mistakes and will help to make you code cleaner and easier to read.
It's perfectly legal in JavaScript to have different branches of code return different types of things -- or return nothing at all (which effectively returns 'undefined').
What you're seeing is a lint warning, not a true JavaScript error -- although it's possible your project is set up to fail builds on lint warnings. Your options are:
Nah, a sizable minority of JavaScript developers prefer to omit semicolons. It's a stylistic decision and it's not akin to a bunch of sentences without punctuation.
Have you gone through the documentation? Eslint has a CLI that allows you to easily set it up. You can pick AirBnb plugin as part of installation as well which is very popular among JS developers.
The suggestion in other comments to break the if-else statement apart will work, however you can also use a local var to cache the result in the if expression, thusly...
let cf; // Declare var for caching result before if-else block
if (...) {
// cf
will be undefined here
...
} else if ((cf = getConversionFactor(graph.findPath(forwardPair)) !== -1) {
// Use cf
for forwardPair conversion factor here
} else if ((cf = getConversionFactor(graph.findPath(reversePair)) !== -1) {
// Use cf
for reversePair conversion factor here
}
Note: While assigning values conditional expressions like this is valid JS, it is often considered a bad practice and best avoided if possible. You risk bugs arising from misplaced "=" signs. For example, if (x == 123) ...
and if (x = 123) ...
are easy to mistake. Both are valid, but result in very different behaviors.
Yeah, I don't think Excel should necessarily be in charge of deciding the rules - people should be able to use the software they buy as they see fit.
But it would be nice if there was some sort of linting engine built in to Excel that could be configured on the organisational level.
Take eslint as an example. It's just a tool with configurations you provide to determine which rules it applies. You can choose to run a popular style-guide such as airbnb, standard, google, etc, each with various levels of "strictness", or run your own fully custom config.
So the parallel here would not be EUSpRig coming up with the software, but if Excel supported some sort of "Linting" then EUSpRig could share a standard they approve of. We get a lot of posts on here about worksheet best practices, and the ability of people/organisations to come up with their own style-guides that are shareable, importable, and natively supported by Excel could really help for the best to rise to the top and improve the "state of the art" as a whole IMO.
Obviously perhaps the lessons learned from linters in programming languages aren't directly transferable to Excel (though with the new =LET() function programming techniques are increasingly applicable), but's also not that ridiculous of a notion: here is an Excel linter made by Microsoft Researchers which was based on this technical paper.
ps: /u/mh_mike second times the charm?
Of course, because it doesn't come with excel, no one uses it/knows about it.
This would be an example of enforcing style with a rule. (quotes)
And this would be an example of enforcing best practices. (no-var)
The first one is just personal preference and there's no objectively right way to write it, thus just style. But the second one there is a "better" way of writing the same code which the rule enforces.
It's ugly when you inline it, but it certainly isn't "needlessly creative". It's an old problem, and ESLint warns for it, for example.
I'd prefer a simple has()
wrapper over inventing a key naming scheme or needlessly using another data type. That's not to say Map
isn't great, but it is more bothersome to use, and I wouldn't use it just to skip a single line of existence checking.
You can run ESLint from the command line using an npm script- just add a script like this to your package.json's scripts section:
"lint": "eslint ."
And then run that in your CI process with npm run lint
or yarn lint
. I'd personally favour having it fail the CI step rather than auto-fixing, otherwise you run the risk of introducing errors without realising if something is auto-fixed in a way you didn't expect.
It would also probably be beneficial to have all your team members set up their editors with an ESLint plugin so problems can be detected in-line- it's much better to just get the code right before you even open a PR.
That looks like you're getting a linting error because the linter doesn't know that Sk
is defined on the window object at runtime. For what it's worth, this isn't a React-specific issue at all.
The linter configuration should have a way to define global variables that will appear in your app.
You can also try disabling the "no-undef" rule for only that line if you put this comment right above it:
// eslint-disable-next-line no-undef
But that will simply make the linter error go away and allow you to compile. If the Sk
variable isn't actually defined at runtime, the compiled app still won't work. To make sure the Sk
variable is there when you expect it, you'll just want to ensure the lib code is loaded before your app code by having the script tags in the correct order in the HTML page.
Javascript is too flexible, as a language. Box yourself in a bit, in the beginning at least. I like Airbnb's config. When you make a mistake (according to eslint), learn the justification for the rule before fixing it. For more experienced or opinionated devs I also recommend giving the responsibility for code style to prettier rather than eslint
Ha, yeah we spent a lot of time going over vulnerabilities, explaining their mechanisms, and what devs should be on the look out for.
At the end of the day though, we have had to write our own defensiveness around this and protect against bad input that could modify the prototype chain.
There's also rules such as https://eslint.org/docs/rules/guard-for-in which help, but often people // eslint-ignore
them without thinking twice.
I think nonblock-statement-body-position and/or "curly": ["error", "multi"] should take care of it. I don't think it'll cause any Prettier conflicts, but it depends on your exact set-up.