フロントエンドプロジェクトでもどんどん複雑になりつつ、深いフォルダの構成が当たり前のことになってきました。例えばcreate-react-appを利用する場合、下記のようなフォルダ構成が普通でしょう。
src
- components
- hooks
- lib
- store
- views
さらに、components、またviewsフォルダの中に、各コンポーネントを独立なフォルダに分けて置くこともよくあります。
src
- views
- MenuView
- MenuView.tsx
- MenuView.style.tsx (styled-components)
- MenuView.test.tsx
- index.ts
となると、MenuView.tsxから、Reduxのストアをimportするとき、たくさん相対パスが現れます。
import { setActiveMenu } from "../../store/menu/actions";
もちろん、階層が変わると、../
も増えるでしょう。これからは絶対パスの登場タイムとなります。
方法はいくつかがありますが、今日はbabel
で実現しましょう。
create-react-appのための設定
tsconfig.jsonの設定
一般的なTypeScriptプロジェクトでは下記のものをtsconfig.json
のcompilerOptions
に書き込めばいいんですが、create-react-appの場合はちょっと違います。react-scriptsで起動するとき、tsconfig.jsonの一部分がデフォルトのものに上書きされる可能性があります。
"baseUrl": "./",
"paths": {
"components/*": ["./src/components/*"],
"store/*": ["./src/store/*"],
"views/*": ["./src/views/*"],
}
なので、新しいファイルを作って、tsconfig.json
にincludeしなければいけません。
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"components/*": ["./src/components/*"],
"store/*": ["./src/store/*"],
"views/*": ["./src/views/*"],
}
}
}
そして、tsconfig.json
の中にはこのように設定 してください。
{
"extends": "./tsconfig.paths.json",
}
これで、VSCodeに絶対パスでimportしてもlintエラーに怒られないでしょう。
babelの設定
TypeScriptの設定をカスタマイズと同じように、create-react-appを使うと、babelをカスタマイズしたいとき、ちょっと工夫する必要があります。
では、まずは何でbabelを選ぶの?
Why babel?
-
個人にとってWebpackの記述よりさらにわかりやすい。
-
Tree-shakingのライブラリいくつがあって、さまざまなライブラリのTree-shakingを対応しやすい。
fontawesome
とramda
みたいに一般的なフォルダ構成を採用していないライブラリであれば、babel-plugin-transform-imports
の存在はとても助かります。
create-react-app with babel
一番簡単な方法はcustomize-cra
とreact-app-rewired
を利用することとなります。
- パッケージをインストール
npm install --save-dev react-app-rewired customize-cra
# yarnの場合
yarn add -D react-app-rewired customize-cra
- そして、プロジェクトのルートフォルダに
config-overrides.js
を作成
const { useBabelRc, override } = require("customize-cra");
module.exports = override(useBabelRc());
package.json
のスクリプトの対応
startなどのスクリプトをreact-scripts
からreact-app-rewired
へ変えます。
--- a/package.json
+++ b/package.json
@@ -5,9 +5,9 @@
"scripts": {
"type-check": "tsc --pretty --noEmit --project ./tsconfig.json",
"lint": "eslint ./src --ext ts --ext tsx --ext js",
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
+ "start": "react-app-rewired start",
+ "build": "react-app-rewired build",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
},
"dependencies": {
@@ -50,7 +50,7 @@
- ルートフォルダの
.babelrc
にbabel設定を記入
※要注意:残念ですが、babel.config.js
だと認識されない(2021.03.11時点)
これで、babelを使えるようになりました。
babelの設定
- babelプラグインの導入
npm install --save-dev babel-plugin-module-resolver
- .babelrcの編集
{
"plugins": [
[
"module-resolver",
{
"root": ["./"],
"alias": {
"components": "./src/components",
"views": "./src/views",
"store": "./src/store"
}
}
]
]
}
完了
これから絶対パスでimportしても問題ありません。VSCodeでもちゃんとヒント出してくれます。
import { setActiveMenu } from "store/menu/actions";
意外に面倒ですね。next.js
に慣れた自分にとって、next.jsのほうがカスタマイズしやすそうですね。