当前位置: 首页 > 工具软件 > react-app > 使用案例 >

React 学习笔记 - create-react-app踩坑 & eslint

郎伟兆
2023-12-01

问题

最近使用create-react-app创建了一个项目,然后使用npm run eject使配置文件暴露
此时,产生了错误 Using babel-preset-react-app requires that you specify NODE_ENV or BABEL_ENV environment variables. Valid values are “development”, “test”, and “production”. Instead, received: undefined.

这个问题困扰我很久,近期找到了create-react-app的相关issueBabel error immediately on eject #12070。根据issue中提出的临时解决方案,进行如下总结

解决方案

解决方案1:修改package.json

{
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "parserOptions": {
      "babelOptions": {
        "presets": [
          ["babel-preset-react-app", false]
          "babel-preset-react-app/prod"
        ]
      }
    }
  }
}

解决方案2:添加.eslintrc.json,推荐使用此方法对eslint进行详细配置

{
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react/jsx-runtime"
  ],
  "parserOptions": {
    "babelOptions": {
      "presets": [
        ["babel-preset-react-app", false],
        "babel-preset-react-app/prod"
      ]
    }
  },
  "env": {
    "es6": true,
    "browser": true,
    "node": true,
    "commonjs": true
  }
}

同时,这里使用了eslint-plugin-react配置库

$ npm install eslint eslint-plugin-react --save-dev

eslintrc配置文件解析

parserOptions 解析器配置

  • ecmaVersion:按照 ecma 哪个版本语法做检查
  • sourceType:默认是 script。模块化的代码要写:module(当前最常见做法)
  • ecmaFeatures:一个配置对象,可配置项如下(value 均为 true/false)
    • globalReturn:允许在全局作用域下使用 return 语句
    • impliedStrict:启用全局 strict mode (如果 ecmaVersion 是 5 或更高)
    • jsx: 启用 JSX

env 代码运行环境

  • browser - 浏览器环境中的全局变量。
  • node - Node.js 全局变量和 Node.js 作用域。
  • commonjs - CommonJS 全局变量和 CommonJS 作用域 (用于 Browserify/WebPack 打包的只在浏览器中运行的代码)。
  • shared-node-browser - Node.js 和 Browser 通用全局变量。
  • es6 - 启用除了 modules 以外的所有 ECMAScript 6 特性(该选项会自动设置 ecmaVersion 解析器选项为 6)。
  • worker - Web Workers 全局变量。
  • amd - 将 require() 和 define() 定义为像 amd 一样的全局变量。
  • mocha - 添加所有的 Mocha 测试全局变量。
  • jasmine - 添加所有的 Jasmine 版本 1.3 和 2.0 的测试全局变量。
  • jest - Jest 全局变量。
  • phantomjs - PhantomJS 全局变量。
  • protractor - Protractor 全局变量。
  • qunit - QUnit 全局变量。
  • jquery - jQuery 全局变量。
  • prototypejs - Prototype.js 全局变量。
  • shelljs - ShellJS 全局变量。
  • meteor - Meteor 全局变量。
  • mongo - MongoDB 全局变量。
  • applescript - AppleScript 全局变量。
  • nashorn - Java 8 Nashorn 全局变量。
  • serviceworker - Service Worker 全局变量。
  • atomtest - Atom 测试全局变量。
  • embertest - Ember 测试全局变量。
  • webextensions - WebExtensions 全局变量。
  • greasemonkey - GreaseMonkey 全局变量

extends

用于继承某些基础配置。值可以是字符串/数组。值为数组时,每个配置继承它前面的配置。
说白了,就是别人提前写好了一套 rules,你直接拿过来用就行。不用自己一个一个一个的,写 rules 规则

rules

手动自定义代码规范

  • off不检查
  • warning报警告
  • error报错

plugins

使用第三方插件。(要先安装才能使用)

  • Q: 第三方插件是用来做什么的?
  • A: 插件的作用,通常都是用来增强一款框架能力的。在这里,也就是增强 eslint 的能力。

因此,可以理解为,plugins 就是在 eslint 常规检查 js 代码规范这个能力之外,给它增加一些新的能力。

ESLint 默认使用Espree作为其解析器,你可以在配置文件中指定一个不同的解析器,只要该解析器符合下列要求:

  1. 它必须是一个 Node 模块,可以从它出现的配置文件中加载。通常,这意味着应该使用 npm 单独安装解析器包。
  2. 它必须符合 parser interface

注意,即使满足这些兼容性要求,也不能保证一个外部解析器可以与 ESLint 正常配合工作,ESLint 也不会修复与其它解析器不兼容的相关 bug。
为了表明使用该 npm 模块作为你的解析器,你需要在你的 .eslintrc 文件里指定 parser 选项。例如,下面的配置指定了 Esprima 作为解析器:

{
  "parser": "esprima",
  "rules": {
    "semi": "error"
  }
} 

以下解析器与 ESLint 兼容:

注意,在使用自定义解析器时,为了让 ESLint 在处理非 ECMAScript 5 特性时正常工作,配置属性 parserOptions 仍然是必须的。解析器会被传入 parserOptions,但是不一定会使用它们来决定功能特性的开关。

Parser

ESLint 默认使用Espree作为其解析器,你可以在配置文件中指定一个不同的解析器,只要该解析器符合下列要求:

  1. 它必须是一个 Node 模块,可以从它出现的配置文件中加载。通常,这意味着应该使用 npm 单独安装解析器包。
  2. 它必须符合 parser interface

注意,即使满足这些兼容性要求,也不能保证一个外部解析器可以与 ESLint 正常配合工作,ESLint 也不会修复与其它解析器不兼容的相关 bug。
为了表明使用该 npm 模块作为你的解析器,你需要在你的 .eslintrc 文件里指定 parser 选项。例如,下面的配置指定了 Esprima 作为解析器:

{    
  "parser": "esprima"
} 

以下解析器与 ESLint 兼容:

注意,在使用自定义解析器时,为了让 ESLint 在处理非 ECMAScript 5 特性时正常工作,配置属性 parserOptions 仍然是必须的。解析器会被传入 parserOptions,但是不一定会使用它们来决定功能特性的开关。

使用decorator

ESLint的默认解析器和核心规则只支持最新的最终ECMAScript标准,不支持Babel提供的实验性(如新特性)和non-standard(如流或TypeScript类型)语法。@babel/eslint-parser是一个解析器,它允许ESLint在Babel转换的源代码上运行。
注意:如果不使用experimental语法则无需使用@babel/eslint-parser,因为默认解析器支持所有non-experimental语法和JSX

要使您的eslint支持decorator特性,需要将parser设为如@babel/eslint-parser这种支持experimental语法的解析器

npm i @babel/eslint-parser @babel/eslint-plugin --save-dev
module.exports = {
  "parser": "@babel/eslint-parser",
  "plugins": [
    "@babel/eslint-plugin"
   ]
}

同时,应该安装decorator对应的babel插件

npm i @babel/plugin-proposal-decorator --save-dev

package.json中启用该插件

{
  "babel":{
    "plugins": [
      [
        "@babel/plugin-proposal-decorators",
        {
          "legacy": true
        }
      ]
    ]
  }
}

配置jsconfig.json

{
  "complierOptions": {
		"experimentalDecorators": true
  }
}

使用TypeScript

//.eslintrc.js
module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  plugins: [
    '@typescript-eslint',
  ],
  extends: [
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    'plugin:@typescript-eslint/recommended',
  ],
};
npm install --save-dev eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin
 类似资料: