LoginSignup
12
9

More than 5 years have passed since last update.

Reactで複数のプロジェクトで共通のコンポーネントを扱う方法[create-react-app]

Last updated at Posted at 2018-12-05

TL;DR

  • ReactでAtomicDesignなどを採用していて、コンポーネントを再利用性を加味しながら作成していて、複数のプロジェクトで共通のコンポーネントを使いたい場合がある。(e.g. User用Admin用を別のプロジェクトとして作成し、共通のコンポーネントを扱う、等)
  • create-react-appでプロジェクトを始めた場合はデフォルトの設定では難しいため、不可逆な操作であるyarn eject (or npm run eject)を行い、手動で設定を行うことで実現した。 movie.gif

Pros & Cons

Pros

  • create-react-appの恩恵を受けれる(簡単に構築できる)
  • ホットリロードしてくれるので、共通コンポーネントの修正などが爆速でできる

Cons

  • monorepoな構成になるため、はじめてコードを見た人にとっては威圧的になる
  • 複数プロジェクトを同一のpackage.jsonで管理するため、複数のプロジェクトで同一のパッケージを使う場合はバージョンを揃える必要がある
  • npm run ejectを行うため、create-react-appのバージョンアップに追従できない

方法

  1. yarn eject
  2. config/paths.jsを編集
  3. src/,public/のディレクトリ構成を修正
  4. package.jsonを編集

前提

create-react-app ( ver1.3.1 )

サンプル(Github)
commit

1. yarn eject

$ yarn eject

 注意このコマンドを実行すると(git操作以外では)元に戻すことができなくなります

2. config/paths.jsを編集

paths.js
 ~ 省略 ~ 
// デフォルトは'user' 
const ENTRY_NAME = process.env.ENTRY_NAME || 'user' //追加

module.exports = {
  dotenv: resolveApp('.env'),
  appPath: resolveApp('.'),
  appBuild: resolveApp('build/' + ENTRY_NAME),                      //
  appPublic: resolveApp('public/' + ENTRY_NAME),                    //
  appHtml: resolveApp(`public/${ENTRY_NAME}/index.html`),           //  編集
  appIndexJs: resolveModule(resolveApp, `src/${ENTRY_NAME}/index`), //  
  appPackageJson: resolveApp('package.json'),
  appSrc: resolveApp('src'),
  appTsConfig: resolveApp('tsconfig.json'),
  yarnLockFile: resolveApp('yarn.lock'),
  testsSetup: resolveModule(resolveApp, 'src/setupTests'),
  proxySetup: resolveApp('src/setupProxy.js'),
  appNodeModules: resolveApp('node_modules'),
  publicUrl: getPublicUrl(resolveApp('package.json')),
  servedPath: getServedPath(resolveApp('package.json')),
};


3. src/, public/のディレクトリ構成を修正

config
scripts
public
  index.html
  favicon.ico
  manifest.json
src
  index.js
  index.css
package.json

config
scripts
public
  admin
    index.html
    favicon.ico
    manifest.json
   user  
    index.html
    favicon.ico
    manifest.json
src
  admin
    index.js
    index.css
  user
    index.js
    index.css
  shared
    MySharedComponent.jsx
package.json

4. package.jsonを編集

package.json
  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js",
    "start:admin": "ENTRY_NAME='admin' node scripts/start.js",
    "build:admin": "ENTRY_NAME='admin' node scripts/build.js",
    "test:admin": "ENTRY_NAME='admin' node scripts/test.js"
  },
12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9