JavaScript color highlighting error in VScode - javascript

I have fresh install of VScode editor (v.1.14.2). Doesn't have any installed extensions. I have problem with javaScript highlighting in very simple file.
The same code in Sublime Text 3:
Default VScode theme (Dark+), doesn't have this bug, and all function names and methods have the same colors. But many another themes (monokai and Abyss for example) have this bug/feature.
I want to have for function names and methods the same color (line 10, 11, 13, 16). Ideally, all lines like in ST3 - blue (line 13 - green). But, it's ok if it would be a green.
I read scope naming link, try to compare different themes. Install all monokai-based themes, but all of theme, has this bug. I tried to create new one, but I didn't do what I need.
So, does it possible to fix this?

You can use vscode command Developer: Inspect TM Scopes for scope inspection. This color changes because vscode thinks click(), addEventListener()... is special DOM-related properties and should be highlighted.
Workaround would be modifying monokai-color-theme.json in
Microsoft VS Code\resources\app\extensions\theme-monokai\themes.
In this array "tokenColors": [] add:
{
"name": "DOM & invocation color fix",
"scope": "meta.function-call.js entity.name.function, meta.function-call.js support.function.dom.js",
"settings": {
"foreground": "#66D9EF"
}
}
This will make function calls & DOM-methods sublime-like.
P.S. If theme updates it will most likely overwrite this file.
Edit:
From some version it is possible to modify theme from settings.json Ctrl+,
"editor.tokenColorCustomizations": {
"textMateRules": [
{
"scope": ["meta.function-call.js entity.name.function",
"meta.function-call.js support.function.dom.js"],
"settings": {
"foreground": "#66D9EF"
}
}
]
}

Your function should not have an end-line ";" added. Your variable test however should have one, this is simple syntax error and doesn't always get caught. This post is years late but it came up in search and the above suggestion is too much work.

Related

Babel is trying to import a module that doesn't exist

My compiled Babel output tries to import a function/file that does not exist. Am I missing a configuration or step in my Mix/Babel/Webpack configuration that would output this file?
I am using Laravel Mix (5.0.4) with its default configurations.
I've recently used the Javascript await operator for the first time. It is causing an issue with Babel. When Babel processes await to make it backwards compatible, it adds import _regeneratorRuntime from "#babel/runtime/regenerator"; to the beginning of the Javascript file. However, babel/runtime/regenerator doesn't actually exist. This causes the Javascript to fail when the browser attempts to load it, producing the error Error resolving module specifier: #babel/runtime/regenerator.
I am beyond my understanding of how Mix, Babel, and Webpack work together. I do not know how to tell Mix/Babel/Webpack to produce file(s) that contain the necessary module(s), or if there's something else I need to be doing.
I've tried many solutions via googling, played with the configuration files, and hit my head against my desk a bunch of times. None of these worked. I'm not sure if I am even asking the right questions.
Debugging info:
webpack.mix.js looks like this:
const mix = require('laravel-mix');
// Use of mix.babel() is imperative as this is legacy code and cannot leverage mix.js()
mix.babel('public/js/helpers.js', 'public/js/processed/helpers.js')
.babel('public/js/main.js', 'public/js/processed/main.js')
.babel('public/js/stripe.js', 'public/js/processed/stripe.js');
The problematic Javascript looks like this:
function foo() {
const bar = document.getElementById('bar');
bar.addEventListener('click', async (event) => {
// ('async' is the part which causes the `import` to be added)
});
}
And when run through Babel, looks like this:
import _regeneratorRuntime from"#babel/runtime/regenerator";function asyncGeneratorStep(n,e,r,t,o,a,u){try{var c=n[a](u),i=c.value}catch(n){return void r(n)}c.done?e(i):Promise.resolve(i).then(t,o)}function _asyncToGenerator(n){return function(){var e=this,r=arguments;return new Promise(function(t,o){var a=n.apply(e,r);function u(n){asyncGeneratorStep(a,t,o,u,c,"next",n)}function c(n){asyncGeneratorStep(a,t,o,u,c,"throw",n)}u(void 0)})}}function foo(){document.getElementById("bar").addEventListener("click",function(){var n=_asyncToGenerator(_regeneratorRuntime.mark(function n(e){return _regeneratorRuntime.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:case"end":return n.stop()}},n)}));return function(e){return n.apply(this,arguments)}}())}
When I dig into Mix's default Babel config, I think it's using this:
{
cacheDirectory: true,
presets: [
[
'#babel/preset-env',
{
modules: false,
forceAllTransforms: true
}
]
],
plugins: [
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-proposal-object-rest-spread',
[
'#babel/plugin-transform-runtime',
{
helpers: false
}
]
]
}
Use js mixin instead:
const mix = require('laravel-mix');
mix.js('public/js/helpers.js', 'public/js/processed/helpers.js')
.js('public/js/main.js', 'public/js/processed/main.js')
.js('public/js/stripe.js', 'public/js/processed/stripe.js');
I was not able to find a working solution in a reasonable time for the legacy project I was working on, so I just used a workaround and documented it. I tried various solutions, different libraries and compilers, upgrading existing libraries, better workarounds and so on. Because this was a legacy project, most changes/updates/tool swaps resulted in a cascade of changes needed (and it still didn't work in the end after making all of those changes).
Ultimately, all I did was take the offending bit of Javascript (it was only one small function) and moved it to its own Javascript that does not get processed by Babel.
// The code that gets processed fine is here:
mix.babel('public/js/stripe.js', 'public/js/processed/stripe.js')
// The code that doesn't get processed without error is here:
.copy('public/js/stripeUnminified.js', 'public/js/processed/stripeUnminified.js');
Considering the time I had invested, this workaround was an ok solution. Running the offending bit of Javascript through a compiler such as Babel just wasn't actually a super critical priority considering all of the headache it was causing and time it was taking. It was looking like I was going to have to rework and update a lot of the project just to fix this one little problem (and still a fix was not guaranteed).

how to fix error for "Expected an assignment or function call and instead saw an expression" [duplicate]

In my Chai tests I often find myself wanting to use their assertions that are something like .to.be.empty, .to.be.true e.t.c., because I find them to be cleaner to read than .to.be.length(1) or .to.be.equal(true). However, this breaks my linter (I'm using default Airbnb linting).
I could use the // disable-eslint-line syntax, but then I'd have to add it to every single line that reads like that and that seems tedious.
I've also read about the DirtyChai library, but that would require me to go back through my entire testing library adding brackets to them all which seems like something I shouldn't have to do simply to get my linter to pass something it should probably be OK with in the first place.
Does anyone know a nicer way to handle this than the ways I've outlined above?
You can disable the rule for the entire file using eslint-disable at the top of the file in question:
/* eslint-disable no-unused-expressions */
expect(someTrueValue).to.be.true;
However, adding this at the top of every test file can be tedious. To disable this rule for all relevant files, you can:
Put a new .eslintc configuration file in the same directory as your test files, configured to disable that rule. This allows you to use the default configuration for all other rules while ignoring that rule specifically only on files in that folder. ESLint calls this Configuration Cascading.
{
"rules": {
"no-unused-expressions": "off"
}
}
Use the overrides key in your main .eslintrc file to disable rules for groups of files with glob pattern matching:
{
"overrides": [
{
"files": ["*.test.js", "*.spec.js"],
"rules": {
"no-unused-expressions": "off"
}
}
]
}
This also allows you to disable other rules which become troublesome in testing, such as no-underscore-dangle when using rewire.
Just found another option using Relative Glob Patterns:
In your .eslintrc file:
"overrides": [
{
"files": "*.test.js",
"rules": {
"no-unused-expressions": "off"
}
}
]
I've made a small plugin called eslint-plugin-chai-friendly that overrides the default no-unused-expressions rule and makes it friendly towards chai. The modified rule ignores the expect and should statements while keeping default behavior for everything else.
Combining jonalvarezz's answer with Ihor Diachenko's answer gave me exactly what I wanted:
npm install --save-dev eslint-plugin-chai-friendly
// .eslintrc.js
module.exports = {
// ...
plugins: ['chai-friendly'],
overrides: [{
files: '*.test.js',
rules: {
'no-unused-expressions': 'off',
'chai-friendly/no-unused-expressions': 'error',
},
}],
// ...
}
This way, the no-unused-expression rule will only be overridden in *.test.js files
AND
a no-unused-expression rule will still be in place to catch any unused expressions in the test files that are unrelated to chai.
In case anyone is stumbling upon this today, I had the same issue and found this solution on eslint documentation. In your eslint configuration file, you can specify one or several environments, which will predefine global variables for this environment. For us, it'd be mocha, and you'd configure like this in your .eslintrc.json:
{
"env": {
"mocha": true
},
...
...
...
}
As a result, it will remove all false positive about mocha describe, it, beforeEach, etc. without needing to completely disable eslint or completely disable any specific rule.
Tested with ESLint v.4.11 and mocha 5.0
I had this issue with tslint and solved it by simply moving the rule for unused expressions down one level. My ./tslint.json has all the other rules I care about, then I made ./src/tslint.json that just looks like
{
"rules": {
"no-unused-expression": true
},
"extends": "../tslint.json"
}
tslint automatically checks for a config file in every level as it descends the tree (with --project or using the VSCode extension) so this means that my tests (under ./test/) have all the other rules applied, but no-unused-expression only applies to files under ./src/.

VSCode user snippet doesn't works inside jsx

I have a some snippet:
"JSON stringify": {
"prefix": "jst",
"body": [
"<pre>{JSON.stringify($1, null, 2)}</pre>"
]
},
and it works inside js scope, but when I'm trying to do same trick inside jsx render - it dont want to be working.
How to tell my VSCode, that I want to do same things inside jsx?
Maybe adding "scope" to your snippet:
"scope": "javascript,typescript,javascriptreact",
javascriptreact ---> jsx files
It should be like this...
"JSON stringify": {
"scope": "javascript,typescript,javascriptreact",
"prefix": "jst",
"body": [
"<pre>{JSON.stringify($1, null, 2)}</pre>"
]
},
Putting that snippet into your global snippets file should work.
Gear Icon/User Snippets/ myGlobalSnippets.code-snippets
It looks like inside jsx, the type of proposed snippets is not "javascript" but "jsx":
When you go to File / Preferences / User snippets you can look for the jsx format (file name jsx.json)
If you put your snippet in that file, it should be available inside your jsx
I had to put "scope": "javascript,jsx,jsx-attr". Perhaps there's a neater way but that did it for me.
In vscode Press the gear button then choose User Snippets then type javascriptreact if you are using "javascript" or typescriptreact for"typescript" then past the snippet code that you want :D

Debugging current file in VS Code

I am writing javascript and am currently doing simple exercises/programs. At times, I wish to run my file for testing purposes. I am aware I could create an HTML file and do this within the console. In Sublime, there exists a way to "build" the current file and immediately see the results (say, whatever is sent to console.log).
With VS Code, it seems that for every file I want to "build"/debug in this manner, I must manually change the launch.json file to reflect the name of the current program.
I have been researching a way around this, and I learned that there are variables like ${file} , but when I use that in the launch.json "program" attribute, for example:
"program": "${workspaceRoot}/${file}"
with or without the workspaceRoot part, I get the following error:
Attribute "program" does not exist" (file name here).
Am I missing a simple way to accomplish this, or must I keep editing launch.json every time I want to run the file?
Thanks in advance!
Change to:
"program": "${file}"
For reference this is the full launch.json
{
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "Node.js - Debug Current File",
"type": "node",
"request": "launch",
"program": "${file}"
}
]
}
}
There are many different ways you may need to access a file that are provided by Predefined variables:
Supposing that you have the following requirements:
A file located at /home/your-username/your-project/folder/file.ext opened in your editor;
The directory /home/your-username/your-project opened as your root workspace.
So you will have the following values for each variable:
${userHome} - /home/your-username
${workspaceFolder} - /home/your-username/your-project
${workspaceFolderBasename} - your-project
${file} - /home/your-username/your-project/folder/file.ext
${fileWorkspaceFolder} - /home/your-username/your-project
${relativeFile} - folder/file.ext
${relativeFileDirname} - folder
${fileBasename} - file.ext
${fileBasenameNoExtension} - file
${fileDirname} - /home/your-username/your-project/folder
${fileExtname} - .ext
${lineNumber} - line number of the cursor
${selectedText} - text selected in your code editor
${execPath} - location of Code.exe
${pathSeparator} - / on macOS or linux, \ on Windows
For a single file, you can skip the launch.json file entirely. Just click the green arrow in the debugger panel and choose Node as your environment.
From here.

Sublime Linter/ ReferenceError: window is not defined?

I know this is very basic question, but it's very strange that I cannot make it work, after spending hours, I really need help.
OSX 10.8.4
sublime Text 2 Version 2.0.2 Build 2221
node v0.10.15
jshint v2.1.7
Actually, I clean-installed sublime Text 2 just for this; just Sublime Package Control has been installed.
Firstly, I prepared a foo.js code:
function x(a, b)
{
return a + b
res = x(10, 20)
console.log("res = " + res);
which result:
$ jshint foo.js
foo.js: line 3, col 17, Missing semicolon.
foo.js: line 6, col 16, Missing semicolon.
foo.js: line 2, col 1, Unmatched '{'.
3 errors
So, jshint works as expected so far for the simple test.
I tried many things to get it work with Sublime Linter, but with no success, I clean-installed the sublime app, then followed a tutorial video:
https://tutsplus.com/lesson/sublime-linter/
Looks easy, and Sublime Linter appearrently successfully installed and readme appears as the video show at 00:30, but in my case, after that, saving or whatever never triggers anything.
Well, I'm totally lost. Please advise. Thanks.
UPDATE:
I noticed sublimeText console shown a error!
Traceback (most recent call last):
File "./SublimeLinter.py", line 431, in _update_view
File "./SublimeLinter.py", line 143, in run_once
File "./sublimelinter/modules/base_linter.py", line 291, in run
File "./sublimelinter/modules/javascript.py", line 72, in parse_errors
ValueError: Error from jshint: /Users/ken/Library/Application Support/Sublime Text 2/Packages/SublimeLinter/sublimelinter/modules/libs/jshint/jshint.js:7881
})(window)
^
ReferenceError: window is not defined
at Object.require.util (/Users/ken/Library/Application Support/Sublime Text 2/Packages/SublimeLinter/sublimelinter/modules/libs/jshint/jshint.js:7881:4)
EDIT:
ok, this seems bug, I should have checked there first..
https://github.com/SublimeLinter/SublimeLinter/issues
There is currently a workaround for this:
The hotfix for this is - in Linux installations - to add
global.window = {};
to the top of the file
~/.config/sublime-text-2/Packages/SublimeLinter/sublimelinter/modules/libs/jshint/jshint.js
For Windows or OS/X installations you need to find the location of your Sublime Text package configurations.
For those that are still getting this error, edit the JSHint configuration file and add the following option:
"jshint_options": {
"undef": true,
"unused": true,
"browser": true, /* Defines DOM globals such as window, navigator, FileReader, etc. */
"jquery": true, /* OPTIONAL: globals exposed by jQuery */
"devel": true, /* OPTIONAL: globals such as debugging, alert */
"globals": { /* OPTIONAL: set others that aren't predefined by JSHint */
"Modernizr": true
}
}
Learn more about the pre-defined JSHint global variables

Categories

Resources