TL;DR
- ReactでAtomicDesignなどを採用していて、コンポーネントを再利用性を加味しながら作成していて、複数のプロジェクトで共通のコンポーネントを使いたい場合がある。(e.g.
User用
とAdmin用
を別のプロジェクトとして作成し、共通のコンポーネントを扱う、等) -
create-react-appでプロジェクトを始めた場合はデフォルトの設定では難しいため、不可逆な操作である
yarn eject
(ornpm run eject
)を行い、手動で設定を行うことで実現した。
Pros & Cons
Pros
- create-react-appの恩恵を受けれる(簡単に構築できる)
- ホットリロードしてくれるので、共通コンポーネントの修正などが爆速でできる
Cons
- monorepoな構成になるため、はじめてコードを見た人にとっては威圧的になる
- 複数プロジェクトを同一の
package.json
で管理するため、複数のプロジェクトで同一のパッケージを使う場合はバージョンを揃える必要がある -
npm run eject
を行うため、create-react-appのバージョンアップに追従できない
方法
yarn eject
-
config/paths.js
を編集 -
src/
,public/
のディレクトリ構成を修正 -
package.json
を編集
前提
create-react-app ( ver1.3.1 )
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"
},