让 Facebook 的 react.js 库 JSX 语法与 jslint 完美搭配?
Posted
技术标签:
【中文标题】让 Facebook 的 react.js 库 JSX 语法与 jslint 完美搭配?【英文标题】:Getting Facebook's react.js library JSX syntax to play nicely with jslint? 【发布时间】:2013-06-19 08:49:38 【问题描述】:我正在玩 Facebook 的 react.js 库。我正在尝试使用他们的 JSX 语法,它通过以下方式描述创建视图。
/** @jsx React.DOM */
var HelloMessage = React.createClass(
render: function()
return <div>'Hello ' + this.props.name</div>;
);
React.renderComponent(<HelloMessage name="John" />, mountNode);
JSLint 显然不喜欢这样(“需要一个标识符,而是看到 '
【问题讨论】:
你没有。它不是有效的 javascript,所以可以理解 JS 静态分析工具无法处理它。您必须修改 JSLint/JSHint 才能添加此功能。 你是对的。维护 repo 的人可能会创建一个 jshint 的分支。 【参考方案1】:我尝试在此线程上遵循 Dustin's 和 STRML's 的建议,这是最适合我的方法。
开发设置
我将 Sublime Text 与 SublimeLinter + SublimeLinter-jshint + SublimeLinter-jsxhint 一起使用。 这些是非常不错的插件,可以让我在保存文件时看到错误,both 用于 JS 和 JSX 文件:
这些插件尊重您项目的.jshintrc
,我怎么推荐它们都不为过。
确保遵循所有三个软件包的安装说明,否则它们将无法工作:
安装 SublimeLinter 很简单 (instructions);
SublimeLinter-jshint 在你的系统中需要一个全局的jshint
(instructions);
SublimeLinter-jsxhint 在你的系统中需要一个全局的jsxhint
,以及Packages/JavaScript
内部的JavaScript (JSX) bundle (instructions)。
您可以将 linter 配置为每隔几秒执行一次、在文件保存时执行或手动执行。
构建步骤、提交钩子等
我们将 JSHint 用作 Git 工作流程的一部分,并作为执行准则的构建步骤。我们本来可以使用jsxhint,但我们想继续使用grunt-contrib-jshint,所以这不是一个选择。
现在,我们正在运行正常的 jshint
作为构建步骤在 react
转换之后,所以它只处理输出的 JS 文件。
如果有人分叉grunt-contrib-jshint 并制作了一个与jsxhint
兼容的版本,那就太酷了,但对我来说这似乎不是一件容易的事。 (更新:有人 did just that 但我还没有测试过。)
忽略生成代码中的违规行为
JSX 编译器生成的代码打破了我们的一些约定。
我不想使用ignore:start
和ignore:end
as suggested by Dustin,因为这会有效地禁用render
方法中的所有 linting。在我的书中这是一个坏主意。例如,从 linting 中排除 render
方法会使 linter 认为我不使用我在文件顶部使用 require
声明的一些库和子组件。 因此,忽略事物的需要从render
方法扩展到文件的其余部分,这完全违背了ignore:start
的目的。
相反,我使用 JSX 编译器(当前)为我中断的三个 JSHint 选项显式装饰每个 render
方法:
render: function ()
/* jshint trailing:false, quotmark:false, newcap:false */
这对我来说就足够了;对于您的.jshintrc
,这可能需要一些调整。
【讨论】:
我按照您的指示进行操作,但无法让 Sublime 为 .jsx 文件使用正确的 linter。它总是使用 jshint 而不是 jsxhint。您是如何解决这个问题的? @NilsMagneLunde 是否显示右下角正在使用 JSX 语法?你重启了 Sublime 吗? 不,它没有。将其更改为 jsx 似乎已经解决了问题 :-) 现在我只需要弄清楚如何让 Sublime 自动识别 jsx 文件。谢谢! @NilsMagneLunde 也许您需要“使用当前扩展名打开所有内容”?见i.imgur.com/3thgqp6.png 我希望得到一个更通用的答案。这个假设 sublime 是使用的 IDE。 :(【参考方案2】:JsxHint 和 JSHint 并不是检查 JSX 的最佳工具。 JSHint 不支持 JSX,JsxHint 所做的只是转换 JSX,然后在转换后的代码上运行 JSHint。 我一直在使用(并且强烈推荐)ESLint 和React plugin。这更好,因为 Eslint 可以使用自定义解析器解析任何 Javascript 风格,例如 esprima-fb 或 babel-eslint(请参阅下面的更新)。
示例.eslintrc
文件:
"parser": "esprima-fb",
"env":
"browser": true,
"node": true
,
"rules":
"no-mixed-requires": [0, false],
"quotes": [2, "single"],
"strict": [1, "never"],
"semi": [2, "always"],
"curly": 1,
"no-bitwise": 1,
"max-len": [1, 110, 4],
"vars-on-top": 0,
"guard-for-in": 1,
"react/display-name": 1,
"react/jsx-quotes": [2, "double", "avoid-escape"],
"react/jsx-no-undef": 2,
"react/jsx-sort-props": 0,
"react/jsx-uses-react": 1,
"react/jsx-uses-vars": 1,
"react/no-did-mount-set-state": 2,
"react/no-did-update-set-state": 2,
"react/no-multi-comp": 0,
"react/no-unknown-property": 1,
"react/prop-types": 2,
"react/react-in-jsx-scope": 1,
"react/self-closing-comp": 1,
"react/wrap-multilines": 2
,
"ecmaFeatures":
"jsx": true
,
"plugins": [ "react" ],
"globals":
"d3": true,
"require": "true",
"module": "true",
"$": "true",
"d3": "true"
更新
esprima-fb 很快就会被 Facebook 弃用。使用 babel-eslint 作为 eslint 的解析器。了解更多关于如何设置 Babel 和 Eslint 以使用 React 的好地方是 this Github project。
【讨论】:
同意。查看更多信息:medium.com/@dan_abramov/lint-like-it-s-2015-6987d44c5b48 作为 JSXHint 的作者...我完全同意。 JSXHint 是我在一个周末整理的一个 hack,所以我可以在没有可怕的ignore
hack 的情况下进行一些基本的 linting 工作。 ESLint 实际上正确地解析了代码,并且支持更多的 ES6/ES7 特性来启动。这是一个更好的项目,我在自己的工作中也转向了它。【参考方案3】:
(更新:这篇文章来自 2013 年,现已过时。)
我使用 JSHint + JSX。
它不应该需要 JSHint 的分支,应该有一种方法可以告诉 JSHint 禁用代码块的所有警告。不幸的是,没有这种方法可以禁用所有警告,只有一组特定的警告,所以我最终可能会提交一个拉取请求来添加它,或者更改 linter。
更新: We submitted a pull request which was accepted。要禁用所有警告,请添加 /*jshint ignore: start */
开始该部分,并添加 /*jshint ignore: end */
结束它。
如您所述,Facebook 和 Instagram 使用的工作流程是从命令行在 IDE 外部进行 lint。
您的另一个选择是将所有 JSX 模板提取到它们自己的文件中,并使它们成为范围的函数,而不是存在于隐式词法范围内。我们试过了,不喜欢样板的数量。
(注意:我不隶属于 React 团队。)
【讨论】:
一直在专门研究这个。 IRC 频道的建议是对 jsx“transpiler”的输出进行 lint。我实际上一直在研究一个包装 jshint 的节点模块,该模块将转换它找到的任何 jsx 文件。 拉取请求被合并,顺便说一句,至少在 JSHint 2.4 中是这样。但是,我强烈建议使用细粒度选项而不是ignore:start
: see rationale。【参考方案4】:
请参阅JSXHint,它是我编写的 JSHint 的包装器,它对来自 react-tools
的输出进行 lints。这是忽略一行代码的一个步骤,因为它实际上会对生成的 javascript 进行 lint。
它可以通过 this plugin 的 SublimeLinter 与 Sublime Text 一起使用。
【讨论】:
还有在线版:www.jsxhint.com【参考方案5】:维护回购的人非常乐于助人。你只需要运行它就可以抛出 JSX 转换来生成有效的 javascript,除非有人创建了 jshint 的分支。如果有足够的兴趣,它可能会被列入未来发布反应框架的路线图。可以看覆盖帖here。
【讨论】:
我最近在 jshint 中添加了一个 pull request,它添加了一个功能,可以忽略 javascript 中的一行代码并在之后恢复 linting。我特别想到了 JSX。【参考方案6】:我使用 grunt + react-tools + jshint 来检查使用 react-tools 构建的 .js 文件。在将 .jsx 转换为 .js 时,react-tools 的输出非常适合保持间距、缩进等,因此它为您提供了一个准确的文件来进行 lint。
要进行设置,请安装 grunt the normal way。然后安装 grunt-contrib-watch、react-tools、grunt-react 和 grunt-contrib-jshint。
npm install grunt-contrib-watch react-tools grunt-react grunt-contrib-jshint --save-dev
这是一个示例 grunt 文件:
'use strict';
module.exports = function (grunt)
// Project configuration
grunt.initConfig(
// Task configuration
jshint:
options:
jshintrc: true,
,
react:
src: ['react/**/*.js']
,
react:
files:
expand: true,
cwd: 'react/',
src: ['**/*.jsx'],
dest: 'react/',
ext: '.js'
,
watch:
jsx:
files: ['react/**/*.jsx'],
tasks: ['react', 'jshint:react']
);
// These plugins provide necessary tasks
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-react');
// Default task
grunt.registerTask('default', ['react', 'jshint:react']);
;
在此文件中,运行“grunt”会将您的 .jsx 编译为 .js,然后对 .js 文件进行 lint。您可以在每次保存后运行“grunt watch”。
以这种方式运行时,我的大部分常用 .jshintrc 设置都有效。我最初遇到了一些问题,但大多数都通过更改 .jsx 文件得到解决。例如,我将“newcap”设置为 true。当我遵循React tutorial's 命名约定并将标签的第一个字母大写时,这会引发 lint 错误。它是通过小写标签的第一个字母来修复的。
我确实必须在我的 .jshintrc 中设置 "trailing": false。生成的 .js 文件有尾随空格,用于将标签转换为 Javascript。我还没有弄清楚是否有一个 react-tools 配置来改变它。如果您不想更改 .jshintrc,可以使用 Dan 帖子中描述的方法。
除了 linting,此过程还有助于发现 .jsx 到 .js 转换的问题。
此过程的问题/缺点是您无法在编辑器中对 .jsx 文件进行 lint。但是,在编辑时保持打开的终端窗口是一个有用的替代方法。在不同的窗格中使用 TMUX 与 Vim 和 Grunt 是我首选的使用方式。
【讨论】:
【参考方案7】:Amey 的回答是正确的,但今天也可以更新:
eslint 和 eslint-plugin-react 对现在支持 es6+jsx+react 所以 babel-eslint 只有在你使用时才需要一些特定的东西,比如类属性、装饰器、异步/等待、类型。
不带 babel-eslint 的 react+jsx+es6 的示例 .eslintrc 配置:
"parserOptions":
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures":
"jsx": true
,
"rules":
"semi": 0
,
"plugins": [
"react"
],
"extends": ["eslint:recommended", "plugin:react/recommended"]
您可以查看 eslint-plugin-react 说明以获取更多详细信息/信息。
【讨论】:
以上是关于让 Facebook 的 react.js 库 JSX 语法与 jslint 完美搭配?的主要内容,如果未能解决你的问题,请参考以下文章