React+ReduxのプロジェクトにTypeScriptを導入する その1(準備・設定)
はじめに
趣味で開発しているReact+ReduxのプロジェクトにTypeScriptを導入したので、その内容をまとめておきます。
Reduxを使っていない、ReactだけのプロジェクトにTypeScriptを導入する流れは以前Qiitaの記事でまとめました。 qiita.com
React+ReduxのプロジェクトにTypeScriptを導入する作業としてやったことは以下の通り
- Babel+webpackでTypeScriptのコンパイルを行えるように設定を変更
- tsconfig.jsonでコンパイルの設定を記述
- ESLintでTypeScriptをチェックできるように
@typescript-eslint/eslint-plugin
のインストールと設定 - Reactのファイルは.tsx、それ以外のJSファイルは.tsに拡張子を変更
- プロジェクト内で必要な型定義ファイルをインストール
- 各コンパイルエラーに対応/修正
- prop-typesを削除
TypeScriptを用いたReactのファイルは拡張子が.tsx
、それ以外のJavaScriptファイルは.ts
になります。
なので今回は「Babelとwebpackの設定をTypeScript用に適切に変更した状態で、Reactのファイルが全て.tsx、それ以外のファイルは.tsになりコンパイルが通る」ことがゴールです。
ここから、各作業の内容について記載します。
なお、この記事ではTypeScriptを導入するにあたり、行う設定などの準備段階(作業1~3)のみ紹介します。
なので、この記事ではReduxに関する内容は登場せず、ReactのプロジェクトにTypeScriptを導入する際の設定内容とほぼ同様です。
実際にTypeScriptで型を導入する(手順4~7)については、後日に別記事で紹介しようと思います。
Babel+webpackでTypeScriptのコンパイルを行えるように設定を変更
まずは、Babel+webpackのビルドプロセスでTypeScriptのコンパイルを行えるようにします。
TypeScriptをwebpackで処理する場合、ts-loader
を使う方法とBabel(@babel/preset-typescript)
を使う方法があるようです。
Babelは、設定でTarget Browserを指定してPolyfillが使えたり、pluginを使って新しいプロポーザルの機能を使えること、またLinterやテストランナー、ビルドシステムなどはBabelをサポートしているので別途考慮する必要(ts-jest, ts-node, ts-karma etc)がなくなる。など、結局Babelを使うことになりそうで、使った場合の方がメリットが多そうに思ったので今回はts-loaderではなく、Babel(@babel/preset-typescript)を使うことにしました。
ts-loaderとpreset-typescriptの比較はこの記事が分かりやすかったです。
必要なライブラリをインストールします。
$ npm i -D typescript @babel/preset-typescript
webpackの設定
webpack.config.jsを以下のように変更しました。
今回、エントリーファイルはindex.tsx
としました。
... module.exports = { - entry: path.resolve(__dirname, 'src/index.js'), + entry: path.resolve(__dirname, 'src/index.tsx'), output: { path: path.resolve(__dirname, 'public'), module: { rules: [ { - test: /\.(js|jsx)$/, + test: /\.tsx?$/, exclude: /node_modules/, loader: 'babel-loader' } }, resolve: { - extensions: ['.js', '.jsx'] + extensions: ['.ts', '.tsx', '.js'] }, ...
Babelの設定
babel.config.jsを以下のように変更しました。
presets: [
...
+ '@babel/preset-typescript',
'@babel/preset-react'
],
...
tsconfig.jsonでコンパイルの設定を記述
TypeScriptのコンパイルに関する設定はtsconfig.json
に記載します。
以下のコマンドでtsconfig.json
の雛形を作成できます。
$ ./node_modules/.bin/tsc --init
作成されたファイルを編集して、必要な設定を行いました。
※ compilerOptionsの各設定は、まだちゃんと確認できていないので、不要な設定も入っていると思います。
{ "compilerOptions": { /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "ESNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ "lib": [ "dom", "es2018" ], /* Specify library files to be included in the compilation. */ "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ "outDir": "./dist/", /* Redirect output structure to the directory. */ /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ /* Additional Checks */ "noUnusedLocals": true, /* Report errors on unused locals. */ "noUnusedParameters": true, /* Report errors on unused parameters. */ "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ /* Module Resolution Options */ "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ "typeRoots": ["node_modules/@types"], /* List of folders to include type definitions from. */ "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ }, "include": ["src"], "exclude": ["node_modules"] }
これでコンパイルの設定が行えました。
ESLintでTypeScriptをチェックできるように@typescript-eslint/eslint-plugin
のインストールと設定
TypeScript用にLintの設定も行いました。
これまでTypeScriptのLinterはTSLintがメジャーでしたが、今は@typescript-eslint/eslint-plugin
により
ESLintでのチェックも行えるようになっているので、TSLintではなくESLintにTypeScriptの設定を追加する形で行いました。
参考にした記事はこちらの記事です。
※ 作業の途中でESLintの実行時にエラーが発生したが、ESLint周りのライブラリバージョン(ESLint, eslint-config-airbnb)が古かったのが問題っぽく、ライブラリを上げると直りました。
@typescript-eslint/eslint-plugin
をインストール
$ npm i -D @typescript-eslint/eslint-plugin
.eslintrc.jsを以下のように変更しました。
...
- parser: 'babel-eslint',
parser: "@typescript-eslint/parser",
parserOptions: {
"sourceType": "module",
"project": "./tsconfig.json",
"ecmaFeatures": {
"jsx": true
}
},
...
extends: [
...
"plugin:@typescript-eslint/recommended",
...
"prettier/@typescript-eslint",
],
plugins: [
...
"@typescript-eslint",
...
],
rules: {
...
// TypeScript
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/no-object-literal-type-assertion": "off",
"@typescript-eslint/prefer-interface": "off",
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/explicit-function-return-type": "off",
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
...
とりあえずルールとして@typescript-eslint/recommended
を設定していますが、TSLint互換の結構厳しいルールが多く入っているので、個別に必要なルールだけ追加した方がいいかもしれません。
また、VSCodeでもTypeScriptのファイルをESLintでチェックしたかったのでVSCodeのsettings.jsonにも設定を追加しました。
"eslint.validate": [ "javascript", "javascriptreact", "typescript", "typescriptreact" ], "eslint.autoFixOnSave": true,
※ たまにTypeScriptのファイルのautoFixがVSCode上で動作しない事態が発生してるのですが、理由はまだ調べれてないです。
まとめ
この記事では、React+ReduxのプロジェクトにTypeScriptを導入するにあたり
準備段階として、webpack、Babel、TypeScript、ESLintの設定を行いました。
これでTypeScriptでコードを書く準備は整ったので、次の記事では実際にその流れを紹介していこうと思います。