Reactプロジェクトが2つあり、共通のモジュールをcommonというプロジェクトで集約して使うことを想定してmonorepoベースのプロジェクトを構築します。
monorepoとは
1 つのリポジトリの中に複数のパッケージを同梱するリポジトリの運用方法
モノレポ入門 – Gutenberg が採用するリポジトリ戦略
yarnでmonorepo環境を構築する
yarnでmonorepoを使っていく場合は、
yarn workspace
を使います。
subprojectにパッケージをインストールする時は
yarn workspace subproject-name add package-name
となります。
projectの作成
root,subprojectをcreate-react-appで作っていきます。
# root projectを作る
npm init
# create-react-appをinstall
npm install create-react-app
# sub projectを作る
npx create-react-app packages/project1 --typescript
npx create-react-app packages/project2 --typescript
npx create-react-app packages/common --typescript
root project の設定
ルートプロジェクトのpackage.json
を修正
以下の設定を追加します。
{
...
"private": true,
"workspaces": {
"packages": ["packages/*"],
"nohoist": ["**/react-scripts", "**/react-scripts/**", "**/@generated", "**/@generated/*"]
}
...
}
project 共通のtsconfig.json
をルートプロジェクトに作成
tsconfig.jsonを作成します。
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
}
}
ここまで
sub projectの設定(project1,project2)
パッケージのインストール
monorepo化に必要なパッケージをインストールします。
yarn workspace project1 add react-app-rewired
yarn workspace project1 add -D customize-cra
yarn workspace project2 add react-app-rewired
yarn workspace project2 add -D customize-cra
package.json
修正
以下の設定に修正します。
react-scriptsによる実行コマンドからreact-app-rewiredによる実行に変えてます。
```json
{
...
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build"
}
...
}
```
tsconfig.json
修正
以下の設定を追加します。
{
"extends": "./tsconfig.path.json",
...
}
tsconfig.path.json
の作成
tsconfig.path.jsonを作成します。
共通モジュール用のディレクトリを「@common」という名前で認識できるようにします。
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@common/*": ["../common/src/*"]
}
}
}
config-overrides.js
の作成
config-overrides.jsを作成します。
const { removeModuleScopePlugin, override, babelInclude } = require('customize-cra');
const path = require('path');
function addAlias(config) {
config.resolve = {
...config.resolve,
alias: { '@common': path.resolve(__dirname, '../ common/src') },
};
return config;
}
module.exports = override(
addAlias,
//remove limitations of create-react-app
removeModuleScopePlugin(),
babelInclude([path.resolve('src'), path.resolve('../ common/src')])
);
ここまで(sub projectの中)
sub projectの設定(common)
いらないものを削っていきます。
src
ディレクトリ配下のソース全部消すpublic
ディレクトリも消すcreate-react-app
コマンドで作られた不必要なファイルを消す
最終的に残るもの
src
ディレクトリpackage.json
readme.json
tsconfig.json
後始末
各 project のnode_modules
とyarn.lock
を消して再インストールし直しておきます。
これでmonorepo環境の構築は完了です。
commonのソースをsub projectで使う
common project に共通的に使いたいファイルを作る
common/src/Hello.tsx
import React, { ReactElement } from 'react';
interface Props {}
function Hello({}: Props): ReactElement {
return <div>view from Common packages!</div>;
}
export default Hello;
sub project 内で import する
import Hello from '@common/Hello'
で importproject1/src/app.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Hello from '@common/Hello';
function App() {
return (
<div className='App'>
<header className='App-header'>
<img src={logo} className='App-logo' alt='logo' />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a className='App-link' href='https://reactjs.org' target='_blank' rel='noopener noreferrer'>
Learn React
</a>
<Hello></Hello>
</header>
</div>
);
}
export default App;
yarn start
yarn workspace project1 start
下段にcommonモジュールに作成した Helllo.tsx の「view from Common packages!」が表示されています。
関連
SonarQubeとprojectの連携方法(monorepo+React + TypeScript)
コメントを書く