TypeScript環境構築 ESLint+Prettier+TailWindCSSの導入
お久しぶりです。
今回は、自分の備忘録的な内容です。
今回作業する環境は以下の通り
$ node -v
v16.13.0
$ yarn -v
1.22.17
Typescriptのプロジェクト作成
$ yarn create react-app ts-sample --template typescript
作成直後のディレクトリはこちら。(node_modulesは多いので除外しています)
$ cd ts-sample
$ tree -I node_modules 水 12/22 15:04:13 2021
.
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
├── tsconfig.json
└── yarn.lock
2 directories, 19 files
ESLintの導入
基本的にはこちらの記事と同じですが、Typescript用に少し変更する必要があります。
まずは、前回と同じようにinitします。
$ yarn eslint --init
対話型の設定で1箇所変更する必要があります。
$ yarn eslint --init 水 12/22 15:23:39 2021
yarn run v1.22.17
$ ~/ts-sample/node_modules/.bin/eslint --init
✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · react
? Does your project use TypeScript? › No / Yes
こんかいは、TypeScriptを使うので、「Does your project use TypeScript ?」の質問には、「Yes」と回答しましょう。
他は、過去の記事と同じでOKです。
次は必要なパッケージをインストールします。
$ yarn add -D eslint-plugin-react eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react-hooks
ちゃんと動くか確認します。
$ yarn run eslint --ext tsx src/ 1007ms 水 12/22 15:30:52 2021
yarn run v1.22.17
$ ~/ts-sample/node_modules/.bin/eslint --ext tsx src/
~/ts-sample/src/App.test.tsx
3:17 error Unable to resolve path to module './App' import/no-unresolved
3:17 error Missing file extension for "./App" import/extensions
5:1 error 'test' is not defined no-undef
6:10 error JSX not allowed in files with extension '.tsx' react/jsx-filename-extension
8:3 error 'expect' is not defined no-undef
~/ts-sample/src/App.tsx
5:1 error Function component is not a function expression react/function-component-definition
7:5 error JSX not allowed in files with extension '.tsx' react/jsx-filename-extension
11:16 error `code` must be placed on a new line react/jsx-one-expression-per-line
11:40 error ` and save to reload. ` must be placed on a new line react/jsx-one-expression-per-line
~/ts-sample/src/index.tsx
4:17 error Unable to resolve path to module './App' import/no-unresolved
4:17 error Missing file extension for "./App" import/extensions
5:29 error Unable to resolve path to module './reportWebVitals' import/no-unresolved
5:29 error Missing file extension for "./reportWebVitals" import/extensions
8:3 error JSX not allowed in files with extension '.tsx' react/jsx-filename-extension
11:34 error Missing trailing comma comma-dangle
✖ 15 problems (15 errors, 0 warnings)
4 errors and 0 warnings potentially fixable with the `--fix` option.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ずらっとエラーが出たので修正していきましょう。
とりあえずfix
4 errors and 0 warnings potentially fixable with the --fix option.
と書いてあるので、自動で直せるものは直してもらいましょう。
$ yarn run eslint --ext tsx src/ --fix 1442ms 水 12/22 15:33:49 2021
yarn run v1.22.17
$ ~/ts-sample/node_modules/.bin/eslint --ext tsx src/ --fix
~/ts-sample/src/App.test.tsx
3:17 error Unable to resolve path to module './App' import/no-unresolved
3:17 error Missing file extension for "./App" import/extensions
5:1 error 'test' is not defined no-undef
6:10 error JSX not allowed in files with extension '.tsx' react/jsx-filename-extension
8:3 error 'expect' is not defined no-undef
~/ts-sample/src/App.tsx
5:13 warning Unexpected unnamed function func-names
7:5 error JSX not allowed in files with extension '.tsx' react/jsx-filename-extension
~/ts-sample/src/index.tsx
4:17 error Unable to resolve path to module './App' import/no-unresolved
4:17 error Missing file extension for "./App" import/extensions
5:29 error Unable to resolve path to module './reportWebVitals' import/no-unresolved
5:29 error Missing file extension for "./reportWebVitals" import/extensions
8:3 error JSX not allowed in files with extension '.tsx' react/jsx-filename-extension
✖ 12 problems (11 errors, 1 warning)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
少し減りましたね。(react/jsx-one-expression-per-lineとか)
残りの修正方法を書いていきます。
import/no-unresolved
こちらは、./App
をインポートしようとして出ているエラーです。
これは、拡張子が.tsx
に変わったことに起因するエラーで、.tsx
も探してくれるように設定する必要があります。
設定箇所は、.eslintrc.yml
参考:既存プロジェクトを TypeScript に移行する際の ESLint の対応
settings:
import/resolver:
node:
extensions:
- '.js'
- '.jsx'
- '.ts'
- '.tsx'
こうすることで、指定した拡張子も探してくれてエラーが出なくなります。
import/extensions
次の記述をrulesに追加します。
参考:eslint-plugin-importでTypeScriptのimport問題を解決する
rules: {"import/extensions":[1, {".js", ".jsx", ".ts", ".tsx"}]}
no-undef
App.test.ts
内で使われている関数の定義が見つからないといっていますね。
デフォルトのESLintでは、定義されている場所を見つけることができないので、envブロックに追記してあげます。
参考:Environment key “jest/globals" is unknown
env:
browser: true
es2021: true
jest: true # 追加
react/jsx-filename-extension
こちらは、.tsxという拡張子がESLintで許可されていないため発生しています。
以下をrulesに追加して、.ts
と.tsx
を許可してあげましょう。
参考:JSX not allowed in files with extension '.tsx’eslint(react/jsx-filename-extension)
'react/jsx-filename-extension': [2, { 'extensions': ['.js', '.jsx', '.ts', '.tsx'] }]
最終的な.eslintrc.yml
こうなります。
env:
browser: true
es2021: true
jest: true
extends:
- plugin:react/recommended
- airbnb
settings:
import/resolver:
node:
extensions:
- '.js'
- '.jsx'
- '.json'
- '.ts'
- '.tsx'
parser: '@typescript-eslint/parser'
parserOptions:
ecmaFeatures:
jsx: true
ecmaVersion: 12
sourceType: module
plugins:
- react
- '@typescript-eslint'
rules: {"import/extensions":[2, {".js", ".jsx", ".ts", ".tsx"}], 'react/jsx-filename-extension': [2, { 'extensions': ['.js', '.jsx', '.ts', '.tsx'] }],}
ESLintを実行した結果は以下の通りです。
$ yarn run eslint --ext tsx src/
yarn run v1.22.17
$ /Users/tohi/RaiseTech/react/task/task11/ts-sample/node_modules/.bin/eslint --ext tsx src/
/Users/tohi/RaiseTech/react/task/task11/ts-sample/src/App.tsx
5:13 warning Unexpected unnamed function func-names
✖ 1 problem (0 errors, 1 warning)
✨ Done in 4.61s.
警告は残りましたが、とりあえずOKです!
このあと、Prettierの導入も行いましたが、過去記事と同じなので割愛します。
TailWindCSSの導入
リッチなUIを提供するライブラリです。
cracoの導入
今回、$ yarn create react-app
でプロジェクトを作っているので、色々細かい調整をするのにejectしないといけません。
cracoを使うと、ejectせずに設定を上書きすることができます。
$ yarn add -D @craco/craco
cracoを使うと、create react-app
で作成したプロジェクトをejectせずにいじれます。
インストールしたらpackage.jsonのscriptsを書き換えます。
{
"name": "ts-template",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@testing-library/user-event": "^13.2.1",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.13",
"@types/react": "^17.0.20",
"@types/react-dom": "^17.0.9",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"typescript": "^4.4.2",
"web-vitals": "^2.1.0"
},
// ここから
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
},
// ここまで
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"autoprefixer": "^10.4.0",
"eslint-config-airbnb": "^19.0.2",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"postcss": "^8.4.5",
"prettier": "^2.5.1",
"tailwindcss": "^3.0.7"
}
}
次は、craco.config.jsを作成します。
$ touch craco.config.js
内容は以下の通りです。
module.exports = {
style: {
postcssOptions: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
},
},
}
Tailwindのインストール
まずは必要なパッケージのインストールしてinitします。
$ yarn add -D tailwindcss postcss autoprefixer
$ npx tailwindcss init -p
Created Tailwind CSS config file: tailwind.config.js
Created PostCSS config file: postcss.config.js
実行すると、tailwind.config.js
とpostcss.config.js
が作成されます。
作成されたtailwind.config.js
にpurgeオプションを追加します。
buildする時に余計なスタイルを含めないようにしてくれるようです。
module.exports = {
content: [],
purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
theme: {
extend: {},
},
plugins: [],
};
最後に、./src/index.css
にtailwnid
を追加します。
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}