ESLint prefer-arrow-functions not flagging correctly - javascript

Currently working on an .eslintrc file and I have implemented this so far
"prefer-arrow/prefer-arrow-functions": [
"warn",
{
"disallowPrototype": false,
"singleReturnOnly": true,
"classPropertiesAllowed": false,
"allowStandaloneDeclarations": true
}
],
const a = activeABTests.reduce(function(accumulator: number, abtest: ABTestFunnelType): number {
I want this function above ^ to flag. It is not warning me in the Github check. It should flag and ask to be converted to an arrow function that looks like this:
const a = activeABTests.reduce((accumulator: number, abtest: ABTestFunnelType) => number {
I don't want to flag functions like this. I think the allowStandaloneDeclarations was the fix, but I am not sure.
I am getting two types of warnings:
Warning: 105:36 warning Prefer using arrow functions over plain functions prefer-arrow/prefer-arrow-functions
Warning: 31:5 warning Use const or class constructors instead of named functions prefer-arrow/prefer-arrow-functions
What can I do to make sure that the right functions are being flagged? I'm currently getting a ton of warnings but want to eliminate them/make sure they are the right ones.

Related

"process is not defined" when used in a function (Vue/Quasar)

The following snippet represents a Pinia store in my Vue 3 / Quasar 2 application. This store uses the environment variable VUE_APP_BACKEND_API_URL which shall be read from either the window object or process.env.
However I don't understand why the first variant is wokring but the second is not. Using the getEnv function always results in a Uncaught (in promise) ReferenceError: process is not defined error.
import { defineStore } from 'pinia';
function getEnv(name) {
return window?.appConfig?.[name] || process.env[name];
}
// 1. this is working
const backendApiUrl = window?.appConfig?.VUE_APP_BACKEND_API_URL || process.env.VUE_APP_BACKEND_API_URL;
// 2. this is NOT working
const backendApiUrl = getEnv('VUE_APP_BACKEND_API_URL');
export const useAppConfigStore = defineStore('appConfig', {
state: () => ({
authorizationUrl: new URL(
'/oauth2/authorization/keycloak',
backendApiUrl,
).toString(),
logoutUrl: new URL('/logout', backendApiUrl).toString(),
backendApiUrl: new URL(backendApiUrl).toString(),
}),
});
NodeJS-specific stuff like process doesn't exist in the browser environments. Both Webpack and Vite implementations work by replacing process.env.XYZ expressions with their values on build time. So, just process.env, or process.env[name] will not be replaced, which will lead to the errors you are experiencing. See the caveats section and related Webpack/Vite docs and resources. So, unfortunately, the only easy way seems to be the first long and repetitive way you've tried(const backendApiUrl = window?.appConfig?.VUE_APP_BACKEND_API_URL || process.env.VUE_APP_BACKEND_API_URL;). You can try embedding this logic in a single object, then use the function to access it.
const config = {
VUE_APP_BACKEND_API_URL: window?.appConfig?.VUE_APP_BACKEND_API_URL || process.env.VUE_APP_BACKEND_API_URL
}
export function getEnv(name) {
return config[name];
}
This way it will be longer and more repetitive to define it the first time, but at least you will be able to use it easily through the code base.
This is late, but it might help someone, I was able to resolve this by adding below to my quasar.conf.js
build: {
vueRouterMode: 'hash', // available values: 'hash', 'history'
env: {
API_ENDPOINT: process.env.API_ENDPOINT ? process.env.API_ENDPOINT : 'http://stg.....com',
API_ENDPOINT_PORT: process.env.API_ENDPOINT_PORT ? process.env.API_ENDPOINT_PORT : '0000',
...env
},
}
For more information ge here: https://github.com/quasarframework/quasar/discussions/9967

Is it safe to apply autofix from ESLint?

I'd like to format several files but I'm worried about breaking code.
When I'm saying if it is safe for not, I'm saying that the execution of the code before and after is exactly the same.
For instance, there are rules that look pretty safe to be applied (like indenting). I suppose that changing the number of spaces won't affect the execution of the code.
Then, there are rules that don't look so safe. For instance, changing var to let or const could cause a different execution as var is not exactly the same as let.
So, I'm wondering if there are any auto-fix rule from ESLint that can change the code so the execution is different when applied the --fix thing.
Yes, it's safe, because the --fix flag does not fix all your JS issues [1].
So you have to fix some eslint warnings/errors yourself.
[1] https://eslint.org/docs/user-guide/command-line-interface#--fix
Mostly yes, but I recently came across an issue when using the autofix option. The codebase I work with uses Mithril v.0.2, which initializes the component's controller using the new keyword. The new keyword only works on constructors, but the eslint --fix command (specifically the prefer-arrow-callback replaced some of my anonymous functions with arrow functions. Which caused some errors, since arrow functions are not constructors.
So my case was like this:
const component = {};
// My method in this object used to be a regular function like the one below
component.normalFunction = function () {
return {
test: true
};
}
// Eslint autofix changed it to be an arrow function
component.arrowFunction = () => {
return {
test: true
};
}
try {
new component.normalFunction();
new component.arrowFunction();
} catch (err) {
document.body.prepend(err);
}
So far that was the only issue I have found with the autofix rule. In my case I ran eslint autofix excluding that rule.

Tern Fails to use JSDoc Type Information

I'm trying to use Tern to perform type inference on some Javascript code. However, the type inference doesn't seem to be using the JSDoc comments alongside the code.
I'm using the code /** #type {Foo} */ let x; as an example of the problem. On the Tern website's demo page (which uses CodeMirror), the editor is able to infer that the type of x is Foo.
Yet, when run locally via node, I get this back: { type: '?', exprName: 'x' }.
Here's a snippet that replicates the issue:
const tern = require('tern');
const ternServer = new tern.Server({
plugins: {
doc_comment: {
strong: true
}
}
});
const js = `/** #type {Foo} */ let x;`;
ternServer.addFile("main", js);
ternServer.request({
query: {
type: "type",
file: "main",
start: js.length - 2,
end: js.length - 2
}
}, console.log);
Tern has otherwise been working perfectly fine for type inference. It's when using the JSDoc comments that it doesn't seem to work with the way I've initialized and called it.
I even set the doc_comment plugin to strong, which means that JSDoc types are preferred over normally inferred types, but to no avail.
Any ideas how to get this to work?
As it turns out, you have to import the doc_comment plugin in order to use it. Otherwise, setting the plugins option for the tern server won't do anything.
Simply adding require("tern/plugin/doc_comment"); to the top of the file solved the problem.

CodeMirror - get linting result from outside of the editor

I'm using the CodeMirror library which is awesome. The code editor that I'm istantiating is a part of a form and therefore I want to do a basic check with linting to see whether the user's input seems valid. Unless the code is fine, I don't want to process the form.
So the question is: is there a method on the CodeMirror editor instance that would allow me to retrieve the result of linting? I'm looking through the docs and Google but failed to find anything helpful. There's this performLint method that is added to the editor, however it does not return the results of linting.
There isn't a specific method to get the linting results, but there is a hook provided when you define a getAnnotations property in the lint options object.
Here's a basic options object that would trigger linting:
var codeMirrorOptions = {
"lineNumbers": true,
"indentWithTabs": true,
"mode": "css",
"gutters": ['CodeMirror-lint-markers'],
"lint": true
}
You can specify an object (instead of a boolean) as the lint property:
"lint": {
"getAnnotations": css_validator,
"async": true
}
Then, define your own validator function. This function can just call CodeMirror's bundled validator:
function css_validator(cm, updateLinting, options) {
// call the built in css linter from addon/lint/css-lint.js
var errors = CodeMirror.lint.css(cm);
updateLinting(errors);
}
At this point you've replicated the behavior of lint:true -- but now the errors variable contains an array of lint errors. If errors.length == 0, no errors were found.
Note: this sample assumes you are linting CSS, but the same would apply for other types.
The updateLinting function in lint.js passes its annotations (and editor) to the onUpdateLinting option:
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
so all you have to do is have your handler as the lint option property:
lint: { onUpdateLinting: handleErrors }
This is a hint for Dezzas Answer:
Write,
var errors = CodeMirror.lint.css(cm, options);
Otherwise, it will fail.
#Clem's answer led me in the right direction, though I did run into a few issues. The first was seeing Bad option: onUpdateLinting repeatedly in the console (See this reported Codemirror issue). The second was seeing the annotations array containing null entries sometimes. Here is my linting configuration passed into Codemirror that solves these issues. Note that I'm using react-codemirror2, but the options get passed into Codemirror in the same format. My component has an optional onLintingComplete callback that can be provided by the consuming component and you'll see that callback referenced below where it is passed the array of lint annotations:
lint: onLintingComplete
? {
onUpdateLinting: (_annotationsNotSorted, annotations) =>
onLintingComplete(
// sometimes codemirror includes null annotations in the array, so we want to filter these out
annotations.filter(annotation => annotation != null)
),
// This empty lint options object is needed here, see: https://github.com/codemirror/CodeMirror/issues/4198
options: {},
}
: true,

Adding to ace-editor wise autocomplete: List user-defined functions and variables (javascript language)

I want to add list of user-defined functions and variables to ace editor's auto-complete.
To do it I want to examine all the code user inserted to the document, find defined functions (and their arguments), defined variables and their scope, etc.
Main question
Is that data already calculated somewhere in the ace source-code (or language-plugin) and I can just grab it in a way?`
What I want
for exapmle, if user inserted code like this:
var var0 = 'abcd';
function foo(var1, var2){
var var3 = 'efg';
}
I want to add to the auto-complete box, function called 'foo' with two parameters - var1 and var2. I want to add also var0 to variables list, and to add var3 just when user writes in the scope it's defined (in the function).
What I already knows :
I know how to enable auto-complete and live auto-complete.
I know how to add new completer
I know that built-in Basic auto-complete adding all the words in document Indiscriminately
I know about ace-tern plugin, and I don't think I want to use it. For now it's still hackish, documention-less, and I can't figure how to enable it.
I know that Ace already have some of the data I'm after. For example it warns when a variable is re-defined when already defined in the same scope. So it had list of variables and their scope. My guess it's using jshint - but Is there a way to grab it from there?
I read ace documation and find a lot useful methods I can use to extract the data, if I have to. The question is if I really need to do this myself.
UPDATE: I implied that in my answer, but to clarify - Tern will do exactly what you are asking in what i want. Snippet below solves one more problem of providing some context which you do not want user even see in the editor. See screenshots of your code used at Ace.Tern live demo
That is opionated,but imo the best option for adding auto-complete in ace is Tern.
Tern accepts typedef configuration option ( described here: http://ternjs.net/doc/manual.html#typedef), but what is more interesting, it will accept your custom js object as a child, ie:
var myContext = {
name: 'myContext',
obj: obj
}
Where obj is your js object. Then in Tern configuration you will use it as:
defs: ['underscore', myContext]
Which will use both your custom object and underscore module for autocomplete.
Tern related ace.js config: (See https://github.com/sevin7676/Ace.Tern/blob/master/demo.html for comments on config options)
var myContext = { ... }
var editor = ace.edit("editor");
editor.getSession().setUseWorker(true);
ace.config.loadModule('ace/ext/tern', function () {
editor.setOptions({
enableTern: {
defs: ['browser', 'ecma5', myContext],
plugins: {
doc_comment: {
fullDocs: true
}
},
useWorker: true,
startedCb: function () {
console.log('editor.ternServer:', editor.ternServer);
},
},
enableSnippets: true,
enableBasicAutocompletion: true,
});
});

Categories