npx create-react-app
で React のアプリを作ったら v17 系になっていました。
今までのプロジェクトで使っていた ESLint の設定を持ってきたらエラーになる部分があったのでメモ
- react
17.0.1
- react-scripts
4.0.1
- eslint
7.14.0
- eslint-plugin-react
7.21.5
.eslintrc.js
(前使ってたのをコピペして持ってきた)
module.exports = { env: { browser: true, es6: true, node: true, }, extends: [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:prettier/recommended', 'prettier', 'prettier/react', 'prettier/standard', ], globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly', }, parserOptions: { ecmaFeatures: { jsx: true, }, ecmaVersion: 2018, sourceType: 'module', }, plugins: ['react', 'prettier'], root: true, rules: { 'eol-last': ['error', 'always'], 'indent': ['error', 2, { SwitchCase: 1 }], 'newline-before-return': 'error', 'no-console': 'warn', 'no-dupe-class-members': 'error', 'no-var': 'error', 'object-shorthand': ['error', 'always'], 'prefer-arrow-callback': 'error', 'prefer-const': 'error', 'prefer-spread': 'error', 'react/prop-types': 'off', 'require-yield': 'error', }, };
JSX で React をインポートしてないと 'React' must be in scope when using JSX エラー
React v17 からは JSX を使っているファイルに import React from 'react';
を書かなくてもOKになっていました。(使ってるように見えない React
を import しなくて良くなったのは個人的には嬉しい)
従来、JSX記法を使用するファイルでは以下の記述を含める必要がありました。
import React from "react";これは、JSXがReact.createElement
に変換されるのであらかじめこちら側でReact
を用意しておく必要があったからです。新しい記法では、React
をあらかじめインポートしておく必要がありません。 cf. [https://zenn.dev/uhyo/articles/react17-new-jsx-transform:title]
React v17 からは JSX を React.createElement
の形式ではなく、動的にインポートされる _jsxs
を使って変換するようになったので React
をインポートしなくても済むようになったみたいです。
しかし ESLint で plugin:react/recommended
を指定していると JSX で import React from 'react'
が無いとエラーになってしまっていました。
.eslintrc.js
module.exports = { //... extends: [ 'eslint:recommended', 'plugin:react/recommended', // … ], // … }
create-react-app
で作られた App.js
には import React from 'react'
が無いのでエラーになる。
// App.js import logo from './logo.svg'; import './App.css'; function App() { return ( <div className="App"> {/* 略 */} </div> ); }
=> error 'React' must be in scope when using JSX
react/react-in-jsx-scope のルールを off にする
v17 以前は import React from 'react'
が無いとエラーになっていたので、おそらく書き忘れ防止のルールだと思うのですが、react/react-in-jsx-scope
が recommended で有効になっているので、これを off にしてあげれば OK
.eslintrc.js
module.exports = { // … rules: { // … 'react/react-in-jsx-scope': 'off', }, }
₍ ᐢ. ̫ .ᐢ ₎👌
テストファイルで 'test' is not defined, 'expect' is not defined のエラー
Jest が使われているテストファイルで、Jest の 関数が定義されてないというエラー
// src/App.test.js import { render, screen } from '@testing-library/react'; import App from './App'; test('renders learn react link', () => { render(<App />); const linkElement = screen.getByText(/learn react/iu); expect(linkElement).toBeInTheDocument(); });
=> 'test' is not defined
=> 'expect' is not defined
Jest を import してるわけでもないので、エラーが出るのもまぁ解るって感じ。
Jest の関数を global にすれば OK
$ npm install --save-dev eslint-plugin-jest
.eslintrc.js
module.exports = { env: { browser: true, es6: true, node: true, 'jest/globals': true, // ←追加 }, // … plugins: ['react', 'prettier', 'jest'], // 'jest' を追加 };
₍ ᐢ. ̫ .ᐢ ₎👌
Dynamic import で import' and 'export' may only appear at the top level エラー
生成された reportWebVitals.js
内で Dynamic import が使われていてこれがエラーになっていました。
// reportWebVitals.js const reportWebVitals = (onPerfEntry) => { if (onPerfEntry && onPerfEntry instanceof Function) { import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { // ... }); } };
=> error Parsing error: 'import' and 'export' may only appear at the top level
parserOptions ecmaVersion 2020 を指定
parserOptions.ecmaVersion
を 2020
にすれば Dynamic imports がサポートされる
.eslintrc.js
module.exports = { // … parserOptions: { ecmaFeatures: { jsx: true, }, - ecmaVersion: 2018, + ecmaVersion: 2020, sourceType: 'module', }, }
₍ ᐢ. ̫ .ᐢ ₎👌
babel-eslint を使う
検索すると parser
に babel-eslint を使う方法が結構ヒットする。
ESLint が ES2020 をサポートする以前は babel-eslint を使うことで Dynamic imports を通していたっぽい。
parserOptions
が ecmaVersion: 2018
でも babel-eslint の設定をすれば Dynamic imports を使ってもエラーにならないようにできた。
$ npm install --save-dev babel-eslint
.eslintrc.js
module.exports = { parser: 'babel-eslint', // ← 追加 parserOptions: { ecmaFeatures: { jsx: true, }, ecmaVersion: 2018, sourceType: 'module', }, // … }
eslint v6.2.0 以降では parserOptions.ecmaVersion: 2020
とすれば Dynamic imports 大丈夫なので、2020 に出来ない理由がない限りこの方法は使わなくても良さそう。(create-react-app
で作ったアプリは内部的に babel-eslint
を使ってる)
所管
これで creat-react-app
で作ったままのアプリで ESLint が通るようになりました!
webpack もだけど設定ファイルって一回作ったらコピペで使いまわしちゃうから、変更が入ってエラーが出てしまうと毎回これ何の設定だったっけ〜ってなってしまう。(記憶力0)
設定を作る機会が少ないから記憶に定着しないんだよね…って言い訳させてくれ。
[参考]
- React v17.0 – React Blog
- React v17.0 Release Candidate: 新機能「なし」 – React Blog
- import React from 'react'
- Jest
- Dynamic Imports