2021年3月11日 • ☕️ 4 min read

フロントエンドプロジェクトでもどんどん複雑になりつつ、深いフォルダの構成が当たり前のことになってきました。例えばcreate-react-appを利用する場合、下記のようなフォルダ構成が普通でしょう。

Copy
src
 - components
 - hooks
 - lib
 - store
 - views

さらに、components、またviewsフォルダの中に、各コンポーネントを独立なフォルダに分けて置くこともよくあります。

Copy
src
 - views
   - MenuView
     - MenuView.tsx
     - MenuView.style.tsx (styled-components)
     - MenuView.test.tsx
     - index.ts

となると、MenuView.tsxから、Reduxのストアをimportするとき、たくさん相対パスが現れます。

Copy
import { setActiveMenu } from "../../store/menu/actions";

もちろん、階層が変わると、../も増えるでしょう。これからは絶対パスの登場タイムとなります。

方法はいくつかがありますが、今日はbabelで実現しましょう。

create-react-appのための設定

tsconfig.jsonの設定

一般的なTypeScriptプロジェクトでは下記のものをtsconfig.jsoncompilerOptionsに書き込めばいいんですが、create-react-appの場合はちょっと違います。react-scriptsで起動するとき、tsconfig.jsonの一部分がデフォルトのものに上書きされる可能性があります。

Copy
"baseUrl": "./",
"paths": {
  "components/*": ["./src/components/*"],
  "store/*": ["./src/store/*"],
  "views/*": ["./src/views/*"],
}

なので、新しいファイルを作って、tsconfig.jsonにincludeしなければいけません。

tsconfig.paths.json
Copy
{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "components/*": ["./src/components/*"],
      "store/*": ["./src/store/*"],
      "views/*": ["./src/views/*"],
    }
  }
}

そして、tsconfig.jsonの中にはこのように設定 してください。

tsconfig.json
Copy
{
  "extends": "./tsconfig.paths.json",
}

これで、VSCodeに絶対パスでimportしてもlintエラーに怒られないでしょう。

babelの設定

TypeScriptの設定をカスタマイズと同じように、create-react-appを使うと、babelをカスタマイズしたいとき、ちょっと工夫する必要があります。

では、まずは何でbabelを選ぶの?

Why babel?

  1. 個人にとってWebpackの記述よりさらにわかりやすい。

  2. Tree-shakingのライブラリいくつがあって、さまざまなライブラリのTree-shakingを対応しやすい。

    fontawesomeramdaみたいに一般的なフォルダ構成を採用していないライブラリであれば、babel-plugin-transform-importsの存在はとても助かります。

create-react-app with babel

一番簡単な方法はcustomize-crareact-app-rewiredを利用することとなります。

  1. パッケージをインストール
Copy
npm install --save-dev react-app-rewired customize-cra 

# yarnの場合
yarn add -D react-app-rewired customize-cra 
  1. そして、プロジェクトのルートフォルダにconfig-overrides.jsを作成
config-overrides.js
Copy
const { useBabelRc, override } = require("customize-cra");

module.exports = override(useBabelRc());
  1. package.jsonのスクリプトの対応

startなどのスクリプトをreact-scriptsからreact-app-rewiredへ変えます。

package.json
Copy
--- 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 @@
  1. ルートフォルダの.babelrcにbabel設定を記入

※要注意:残念ですが、babel.config.jsだと認識されない(2021.03.11時点)

これで、babelを使えるようになりました。

babelの設定

  1. babelプラグインの導入
Copy
npm install --save-dev babel-plugin-module-resolver
  1. .babelrcの編集
.babelrc
Copy
{
  "plugins": [
    [
      "module-resolver",
      {
        "root": ["./"],
        "alias": {
          "components": "./src/components",
          "views": "./src/views",
          "store": "./src/store"
        }
      }
    ]
  ]
}

完了

これから絶対パスでimportしても問題ありません。VSCodeでもちゃんとヒント出してくれます。

Copy
import { setActiveMenu } from "store/menu/actions";

意外に面倒ですね。next.jsに慣れた自分にとって、next.jsのほうがカスタマイズしやすそうですね。


関連投稿

コストコオンラインの商品価格変動チェックのバッチを作ってみた

2021年3月23日

ThunderMiracle

Blog part of ThunderMiracle.com