64

How can I get a proper syntax highlighting in Visual Studio 2015 for JSX with ES2015 code?

ES2015 code

It works fine if I remove the import and export keywords: Without import/export

I just updated to Visual Studio 2015 Enterprise Update 1 but it still remains the same.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
user3900456
  • 2,003
  • 3
  • 25
  • 33
  • I would actually recommend switching to typescript and using **TSX** files. I think VS 2015 relies on the typescript compiler for those. And it has proven *much* more reliable in my experience. I recommend this article: https://medium.com/@lucavgobbi/using-react-with-typescript-on-visual-studio-39cd0a77fdd2#.l3vdw8aih. I can write a more thorough answer (updated for webpack2) if anyone would find it useful. – jmathew Nov 11 '16 at 04:33

6 Answers6

77

UPDATE (2017-02)

Node Tools for Visual Studio (NTVS) has been using the Salsa analysis engine since v1.2 and using NTVS is likely the path of least resistance for JSX support.

https://github.com/Microsoft/nodejstools

Read (and upvote) this answer for more details: https://stackoverflow.com/a/41996170/9324


ORIGINAL ANSWER

I ran into the same issue and found two solutions - one using ReSharper and one modifying Visual Studio external web tools.

SOLUTION 1

In ReSharper 10:

  • open the Options dialog
  • under Code Editing > JavaScript > Inspections choose ECMAScript 6 in the JavaScript language level drop down
  • ensure the Enable JSX syntax in .JS files option is selected as well (assuming you use JSX syntax).
  • you also need to disable javascript syntax errors in Visual Studio as follows:
    • go to Tools > Options > Text Editor > JavaScript > IntelliSense
    • uncheck the Show syntax errors box and OK out.
  • reload the VS solution

After reloading the solution, the red squigglies were gone for me. However, the syntax highlighting for JSX doesn't work. The opening segment of any elements I declare in the render function don't have the proper coloring - but that's easy for me to ignore.

I should also mention that the javascript files need to have .js extension. If you give them .jsx extension, you'll get red squigglies on your first import statement. The error message will be JSX Parser: illegal import declaration. (This can be fixed using solution #2 below)

UPDATE: thanks to @SntsDev for this workaround There is a way to avoid naming the .jsx files as .js:

  • in Visual Studio, go to Options > Text-editor > File Extension
  • add jsx and assign it to Javascript Editor

SOLUTION 2

Curiosity got the better of me and I wanted to explore whether or not there was a non-ReSharper solution. Visual Studio uses a locally running node server module named react-server to parse JSX on the fly. This module can be found here:

C:\Program Files (x86)\Microsoft Visual Studio
14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External\react-server

UPDATE for Visual Studio 2015 Update 3 Thanks to @TheQuickBrownFox for the comment/update. For Update 3, the location of the react-server commands is now in this file:

C:\Program Files (x86)\Microsoft Visual Studio 
14.0\Web\External\vs-task-server\react-commands.js

Further examining the server.js or react-commands.js file from the aforementioned folder(s), there is a function named transformJsxFromPost or transformJsx. This method contains the following line: var transformed = reactTools.transformWithDetails(code, { elementMap: true });. This is a reference to the react-tools module (https://www.npmjs.com/package/react-tools), which has more options available for parsing ES6.

Therefore:

  • replace this line:

    var transformed = reactTools.transformWithDetails(code, { elementMap: true });

  • with the following:

    var transformed = reactTools.transformWithDetails(code, { elementMap: true, es6module: "--es6module", harmony: "--harmony" });

    Note the addition of the --es6module and --harmony flags, which instruct react-tools to treat the incoming code as ES6.

  • disable javascript syntax errors in Visual Studio as follows:

    • in Visual Studio, go to Tools > Options > Text Editor > JavaScript > IntelliSense
    • uncheck the Show syntax errors box and OK out
  • IMPORTANT: restart Visual Studio. Your .jsx files with ES6 code should no longer have red squiggles on your ES6 code.


NOTES:

  • I don't know if the change outlined in SOLUTION 2 to the server.js file will impact non-ES6 code. So implement at your own risk.
  • Also, it's quite possible/likely your change could get overwritten with a later update to Visual Studio.
  • It would be cool/fun to replace the use of react-tools within react-server with Babel CLI. UPDATE: Thanks to @NickDewitt, seems he was able to make this work: https://stackoverflow.com/a/36321109/9324
Community
  • 1
  • 1
Adam Weber
  • 2,395
  • 21
  • 24
  • 3
    There is a way to avoid naming the .jsx files as .js: In VS, Options > Text-editor > File Extension, add "jsx" and assign it to "Javascript Editor". This is for Solution 1. Thanks! – SntsDev Feb 09 '16 at 18:23
  • 3
    Is Solution 2 still valid as of VS2015 Update 1? I've applied that fix, and restarted, but VS is still showing red squiggles on the imports and exports in all .jsx files. – Sean Werkema Mar 24 '16 at 16:03
  • 1
    @AdamWeber i managed to swap it out for babel if you are interested, check my answer below –  Mar 30 '16 at 23:49
  • I’m having the same issue as @SeanWerkemawith Solution 2. When using this solution I still get the red squiggles and warnings showing in the Error List. If I revert `server.js` to its original state I get twice as many warnings showing. So something else must be generating the warning messages – Dylan Parry Apr 08 '16 at 11:28
  • 1
    @DylanParry, you need to do the optional step from solution 1: go to Tools > Options > Text Editor > JavaScript > IntelliSense, then uncheck the Show syntax errors –  Apr 08 '16 at 12:40
  • Thanks @NickDewitt, I found if I do that I also lose all errors entirely including ones that aren't related to the import/export statements. Is there any way to not lose these errors? – Dylan Parry Apr 08 '16 at 12:41
  • 1
    @DylanParry yes, you will until you get the react or babel transpiler returning errors, they only return one error at a time so you get highlighting on the first error found in your file, fix that you get the next one etc etc –  Apr 08 '16 at 12:52
  • Ah yes, I see them now. Only seems to show errors that directly affect the JSX bits of my code though. Other regular JS errors are ignored. It’ll do for now though. – Dylan Parry Apr 08 '16 at 12:56
  • Is there something I have to enable for the react-server to run? When I launch Visual Studio, this doesn't seem to be running (at least I don't see it listed as a process under Task Manager). The only node server that appears to be running is for Web Analyzer. – Sara May 26 '16 at 22:26
  • 1
    I don't have that "react-server" folder in my VS 2015 installation. What did you install to get that folder? – Peter Perot May 27 '16 at 19:10
  • I don't have the folder either. Maybe future versions of VS removed it? – Jonn Jul 09 '16 at 11:45
  • 3
    As of Update 2 or 3, not sure which, it is now located under "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External". – Nyatra Jul 25 '16 at 18:18
  • 1
    After installing Update 3, the file to edit is `"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External\vs-task-server\react-commands.js"`. It's a different file but basically the same edit. – TheQuickBrownFox Oct 05 '16 at 14:06
  • I'm having the same problem. I'm using Visual Studio 2015 Update 3 but I don't even have the "react-server" folder under "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External\" How do I install react-server? – Sam Oct 16 '16 at 20:55
  • The comment by @TheQuickBrownFox should be highlighted. That's the file to edit if you're running Visual Studio 2015 Update 3. That fixed the issue for me. – Sam Oct 16 '16 at 21:04
28

In VS2015 Update-3 and NTVS 1.2 installed, simply setting TypeScript Editor as the default editor for file extension jsx did the trick for me.

1) Open Tools>Options>Text Editor>File Extension.

2) Type jsx in Extension, select TypeScript Editor as Editor, and click Apply.

enter image description here

Chebyr
  • 2,171
  • 1
  • 20
  • 30
  • 1
    +1 for using NTVS. I tried using it when I originally posted my answer to this question, but their support for JSX at that time was not good. Now that NTVS uses the Salsa engine, using NTVS is probably a much easier (and more sensible) route than modifying external tools. – Adam Weber Feb 16 '17 at 19:18
  • Formatting sucks. When I auto formatted my jsx document, all indentation was gone. I ended up with an unreadable flat file – Thanasis Ioannidis May 02 '17 at 12:11
  • You can play around with the tab stops and formatting using tools>options>text editor>typescript – Chebyr May 02 '17 at 12:38
  • 1
    it gives no intellisense though – Dynamic May 05 '17 at 12:39
7

EDIT: Visuals studio 15 is renamed to Visual Studio 2017: you can get the RC over here: https://www.visualstudio.com/vs/visual-studio-2017-rc/

Future Solution:

Visual Studio "15" Preview 2 support JSX en React out of the box. You can enable the same (Salsa) Javascript Service library like VS Code.

Here the release notes: https://www.visualstudio.com/en-us/news/releasenotes/vs15/vs15-relnotes

Salsa: https://github.com/Microsoft/TypeScript/wiki/Using-the-Salsa-Preview-in-Visual-Studio-15-Preview

5

SOLUTION '3':

Thanks to the insights from Adam in his answer, I have got this working with babel and it's plugins/presets. It's worth reading his answer first if you are trying this.

You need nodeJs and npm installed before you go any further, and maybe back up any files before you modify them.

I am using react, es2015 plugins with stage1 presets here, but you can use whatever plugins you like

  1. Powershell to C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External\react-server

  2. Install the following packages:

    npm install babel-core --save-dev
    npm install babel-preset-es2015 --save-dev
    npm install babel-preset-react --save-dev
    npm install babel-preset-stage-1 --save-dev
    
  3. Add the dependencies to server.js below childProcess

    var childProcess = require('child_process'); //already there
    var babel = require('babel-core');
    var es2015 = require('babel-preset-es2015');
    var react = require('babel-preset-react');
    var stage1 = require('babel-preset-stage-1');
    
  4. Replace the try{}catch{} section of the req.on('end' assignment in the transformJsxFromPost function:

    try {
    
        var transformed = 
            babel.transform(
                code, 
                {
                    sourceMaps: true, 
                    presets: [
                        es2015, 
                        react, 
                        stage1
                    ]
                }
            );
    
        result = { 
            elementMappings: []
        }
        //I found it least buggy when returning an empty list of elementMappings
        //but i will leave the code i was using to try and dupe it, or 
        //recreate the elementMappings from react-tools
        //
        // result = { 
            // elementMappings: [{
                // 'start': 1,
                // 'end': transformed.code.length,
                // 'generatedCode': transformed.code
            // }], 
            // map: transformed.map, 
            // code: transformed.code
        // }
    }
    catch (e) {
        //the error that react-tools was returning was slightly different, so
        //map the babel error back to the react-tools error that VS 2015 expects
         result = {
             column: e.loc.column,
             description: e.errorMessage,
             errorMessage: e.message + ".. :-(",
             index: e.pos,
             lineNumber: e.loc.line
         };
    }
    
  5. Restart visual studio, close and re-open any .jsx files and enjoy babel syntax highlighting :-)

Notes
Give the parser a chance to kick in after you start, visual studio will do the following when you load into a .jsx file the first time:

  1. Create a folder in %localappdata%\Temp\ with stderr.txt where you can find a log of any errors and stdout.txt which will tell you what {port} the server is running on and also logs other info.
  2. Start a nodeJs server, running on localhost:{port} which accepts JSX as a POST on /transformJsxFromPost and returns the line number and column number of the first error it encounters as a json object to visual studio

I had to turn off javascript intellisense for jsx files as Adam shows in solution 1 in his answer:

In Visual Studio, go to Tools > Options > Text Editor > JavaScript > IntelliSense, then uncheck the Show syntax errors box and OK out.

With javascript intellisense off, both react-server as packaged with vs and babel as i am replacing it here both only return the first error they encounter, so you shouldn't expect to see highlighting on all errors throughout your file, but they do show up as you type if you keep your code error free.

I guess now all is left to do is get the elementMappings over properly - solution 4 maybe? :-)

  • Doesn't want to work for me. I get an error "JSX Parser: Unable to communicate with JSX Parser". I’ve installed the four node modules listed above, but the error occurs as soon as I attempt to import any of them into the `server.js` script. – Dylan Parry Apr 08 '16 at 11:21
  • Meant to say that I’m using VS2015 Update 2. – Dylan Parry Apr 08 '16 at 11:38
  • I looked in the `node_modules` directory inside the `react-server` directory, and the modules are indeed there. Restarted VS after making the changes and closed/reopened the JSX files. It seems that importing `babel-core` is fine, but the errors start appearing as soon as I try to import or load any of the presets. – Dylan Parry Apr 08 '16 at 12:25
  • Tried installing them globally, but hasn't made any difference. Had a look in the temp directory, and it's created an empty `stderr` log and the `stdout` log doesn't say much other than the port's opened and it got a 200 response from the POST attempt. – Dylan Parry Apr 08 '16 at 12:52
  • It seems it's actually working properly, but when first opening a JSX file the parser takes longer to start up than VS is willing to wait (ie. not immediately!) so it shows an error about not being able to communicate with the parser. If I wait a couple of seconds, then start typing, the squiggles disappear and all is fine again. This is a minor annoyance at most, but it would be nice to track down why it's doing it. – Dylan Parry Apr 08 '16 at 15:39
  • 1
    Ah ok I did experience similar, I think it's a side effect of starting and restarting vs and the node server, it seems to update as soon as you modify and text though –  Apr 08 '16 at 15:58
  • @DylanParry free free to +1 my answer if it helped you ;-) –  Apr 09 '16 at 01:10
  • Awesome way, trying to get it to work. I am getting synax error now rather than cannot connect to parser. Looks like it is not understandign ES6 as plain javascript works. Any ideas? – Michal Ciechan Apr 18 '16 at 18:07
  • 1
    @MichalCiechan syntax error indicates it *is* working, is it giving you a line and column number? –  Apr 18 '16 at 19:36
  • 1
    @MichalCiechan did you turn off javascript errors like in the note at the bottom? I just set this up on my work laptop and it still showed `syntax error` for me on there until I turned off js syntax checking –  Apr 19 '16 at 16:43
  • @NickDewitt thanks for the follow-up. And no I haven't turned it off. In the end, I ended up starting new typescript project. And slowly re-importing libraries one by one as I get my head around how all of this works together! Thanks for the help tho! – Michal Ciechan Apr 20 '16 at 18:36
4

Whilst trying to research this I realised a simple way to work with jsx files in all versions of Visual Studio. It's not perfect but works for me.

Download the latest Visual Studio Code [ https://code.visualstudio.com/updates ] then right click a jsx file within whatever version of Visual Studio you have and select 'Open With...'. Select 'Add' and browse to your recently downloaded Visual Studio Code and make this your default.

Hope that helps people worrying about having to upgrade.

Mark Caple
  • 51
  • 3
4

It is mentioned in the comments above by @TheQuickBrownFox, but hidden by default (needed to expand all to see it), so summarizing what I did to fix the issue in the latest Visual Studio 2015 Community Update 3:

100% from Solution 1 by Adam Weber: https://stackoverflow.com/a/34110461/1633913 (setting JavaScript Language Level in ReSharper to ECMAScript 2016, and check Enable JSX ... in the same window + disabling Show syntax errors in VS JavaScript IntelliSense options)

Solution 2 by Adam Weber: https://stackoverflow.com/a/34110461/1633913, but slightly modified; the target file where you should replace:

this: var transformed = reactTools.transformWithDetails(code, { elementMap: true });

with this: var transformed = reactTools.transformWithDetails(code, { elementMap: true, es6module: "--es6module", harmony: "--harmony" });

is indeed here: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Web\External\vs-task-server\react-commands.js

restart VS and you're done.

Community
  • 1
  • 1
Bartosz Lenar
  • 363
  • 5
  • 6
  • The path in this answer was correct for me, but I cant get this to work. Visual Studio still sais `Syntax Error`. Iv tried with both: `var transformed = reactTools.transformWithDetails(code, { elementMap: true, es6module: "--es6module", harmony: "--harmony" });` and `var transformed = reactTools.transformWithDetails(code, { elementMap: true, es6module: true, harmony: true });`, however the `HTML` in the `*.jsx` files no longer show up as syntax errors, its only the import parts... – furier Oct 20 '16 at 11:41
  • Classic one but might help; saving went without errors (as it's in the Program Files editors without admin rights are unable to do this)? did you restart VS and Windows after saving? VS uses node server to do the operation, so restarting Windows surely indicates restarting all of the stuff. – Bartosz Lenar Oct 20 '16 at 12:04
  • I did not restart Windows, but I did restart Visual Studio of course, just as described in the answer. Also I did start my text editior program as an administrator to be able to do changes to the files... – furier Oct 20 '16 at 12:15
  • as @AdamWeber mentioned; VS uses _locally running node server app_ to do the trick. restarting only this app (or the entire node server) might help; I haven't checked this out though, as I was about to restart my Windows 10 anyway due to the new updates. i know it's hardcore, but rebooting OS might be the solution? – Bartosz Lenar Oct 20 '16 at 12:30