让 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:startignore: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 的回答是正确的,但今天也可以更新:

eslinteslint-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 完美搭配?的主要内容,如果未能解决你的问题,请参考以下文章

Facebook发布React 16 专利条款改为MIT开源协议

es6+react.js组件入门初探

2019年React.js开发者路线图

每日一翻React和Vue.js2.0哪一个更好?

让一线公司软件工程师都疯狂的React JS究竟是什么?

25react入门教程