├── .npmignore ├── README.md ├── package.json ├── syntastic_1.png ├── syntastic_2.png └── wrapper.js /.npmignore: -------------------------------------------------------------------------------- 1 | *.png 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Syntastic Checker for React JSX files 2 | 3 | ## New way using ESLint 4 | 5 | This project has been deprecated in favor of using ESLint, which supports React, JSX, and new ES6 features, and is in very active development. 6 | 7 | To use Syntastic with ESLint: 8 | 9 | Install eslint, babel-eslint (for ES6 support), and [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react): 10 | 11 | ``` 12 | npm install -g eslint 13 | npm install -g babel-eslint 14 | npm install -g eslint-plugin-react 15 | ``` 16 | 17 | Create a config like this in your project's `.eslintrc`, or do so globally by placing it in `~/.eslintrc`: 18 | 19 | ``` 20 | { 21 | "parser": "babel-eslint", 22 | "env": { 23 | "browser": true, 24 | "node": true 25 | }, 26 | "settings": { 27 | "ecmascript": 6, 28 | "jsx": true 29 | }, 30 | "plugins": [ 31 | "react" 32 | ], 33 | "rules": { 34 | "strict": 0, 35 | "quotes": 0, 36 | "no-unused-vars": 0, 37 | "camelcase": 0, 38 | "no-underscore-dangle": 0 39 | } 40 | } 41 | ``` 42 | 43 | Finally, configure Syntastic to use ESLint: 44 | 45 | ``` 46 | let g:syntastic_javascript_checkers = ['eslint'] 47 | ``` 48 | 49 | You should be good to go! See [this issue](https://github.com/jaxbot/syntastic-react/issues/6#issuecomment-86569859) for more info. 50 | 51 | ## Using this project and JSHint instead 52 | 53 | This is a simple wrapper that: 54 | * Tries to compile as JSX 55 | * Checks if the JSX compiler throws errors, and sends them to Syntastic if so 56 | * Otherwise, passes JS to JSHint and outputs any errors found there 57 | 58 | This gives you the power of syntax checking in Vim, without the annoyance of "unexpected regular expression". Awesome. 59 | 60 | Syntastic working with JSHint issues 61 | 62 | Syntastic working with JSX issues 63 | 64 | # Usage 65 | 66 | ``` 67 | npm install -g syntastic-react 68 | ``` 69 | 70 | If you don't have jshint or react-tools, install those too: 71 | 72 | ``` 73 | npm install -g jshint 74 | npm install -g react-tools 75 | ``` 76 | 77 | Add these lines to your vimrc: 78 | 79 | ``` 80 | let g:syntastic_javascript_checkers = ['jsxhint'] 81 | let g:syntastic_javascript_jsxhint_exec = 'jsx-jshint-wrapper' 82 | ``` 83 | 84 | And, of course, install Syntastic. 85 | 86 | # More info 87 | 88 | This is a part of [a blog post on setting up Vim for React development](https://jaxbot.me/articles/setting-up-vim-for-react-js-jsx-02-03-2015). 89 | 90 | ## Why? What about JSXHint? 91 | 92 | JSXHint is being sunsetted and [doesn't handle React errors correctly](https://github.com/STRML/JSXHint/issues/45). This code is a simple wrapper that brings the best of both worlds, though this one is designed specifically for use with syntastic, and thus will not run the same way as the previous JSXHint wrapper. 93 | 94 | # JSON support 95 | 96 | If you receive an `Unexpected token` error when editing JSON files, note that Vim defaults to `json` being `ft=javascript`. Two main options exist to remedy this: 97 | 98 | 1. Use [vim-json](https://github.com/elzr/vim-json) and get proper JSON highlighting and filetype support. 99 | 100 | 2. Override the filetype manually in your vimrc, something like: 101 | 102 | ``` 103 | au BufRead,BufNewFile *.json set filetype=json 104 | let g:syntastic_json_checkers=['jsonlint'] 105 | ``` 106 | 107 | (Thanks, [sharkinsspatial](https://github.com/sharkinsspatial)!) 108 | 109 | ## About me 110 | 111 | I'm Jonathan, I work on random Vim plugins, web development, Node.js, Android, and whatever else I feel like. [Follow me](https://github.com/jaxbot) if you're curious, or just want to make my day! 112 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "syntastic-react", 3 | "version": "1.0.3", 4 | "description": "Drop-in replacement for JSXHint to enable React JSX syntax checking", 5 | "main": "wrapper.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "bin": { 10 | "jsx-jshint-wrapper": "wrapper.js" 11 | }, 12 | "author": "Jonathan Warner (Jaxbot)", 13 | "license": "Public Domain" 14 | } 15 | -------------------------------------------------------------------------------- /syntastic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaxbot/syntastic-react/b5048cacd21cda76bd595447a84d80679f51464b/syntastic_1.png -------------------------------------------------------------------------------- /syntastic_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaxbot/syntastic-react/b5048cacd21cda76bd595447a84d80679f51464b/syntastic_2.png -------------------------------------------------------------------------------- /wrapper.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var child_process = require("child_process"); 3 | var exec = child_process.exec, spawn = child_process.spawn; 4 | 5 | // Syntastic will use this to check if the JSXHint checker is available 6 | // Pretend to exist, but leave a note for the users 7 | if (process.argv[2] == "--version") { 8 | console.log("JSXHint v0.8.3 (2.5) (Impersonating -- This is a drop-in replacement for JSXHint by Jonathan Warner, not the real deal."); 9 | process.exit(); 10 | } 11 | 12 | // Run the transformer 13 | var transformer = "jsx"; 14 | if (process.argv[4] == "--babel") 15 | transformer = "babel"; 16 | exec(transformer + " " + process.argv[3], function(err, stdout, stderr) { 17 | // If any errors were found (multiple lines spit out, by default 1 is sent to stderr for each module built), 18 | // parse the JSX output and convert it into a JSHint format 19 | if (stderr.split("\n").length > 2) { 20 | var regex = /Error: (.*)/g; 21 | var count = 0; 22 | while ((results = regex.exec(stderr)) !== null) { 23 | var line = results[1].match(/Line (\d+)/); 24 | if (line) 25 | line = line[1]; 26 | console.log(process.argv[3] + ": line " + line + ", col 1, " + results[1] + ". (E030)"); 27 | count++; 28 | } 29 | console.log("\n" + count + " errors"); 30 | // Otherwise, just run JSHint and pipe it back out 31 | } else { 32 | var data = ""; 33 | var jshint = spawn("jshint", ["--verbose", "--filename", process.argv[3], "/dev/stdin"]); 34 | jshint.stdin.setEncoding = 'utf-8'; 35 | jshint.stdout.on("data", function(chunk) { 36 | data += chunk; 37 | }); 38 | jshint.stdout.on("end", function() { 39 | // We have to give it the correct filename 40 | // JSHint will define it as "/dev/stdin", which will confuse Syntastic 41 | data = data.replace(/\/dev\/stdin/g, process.argv[3]); 42 | console.log(data); 43 | }); 44 | // Send the compiled JSX output to JSHint 45 | jshint.stdin.write(stdout); 46 | jshint.stdin.end(); 47 | } 48 | }); 49 | 50 | --------------------------------------------------------------------------------