react-adminを使って5分で作るハイカラDashboard
導入
admin dashboardのtemplateを探していたところたまたまプロジェクトをコピーするタイプではなくライブラリ形式で提供している react-admin を見つけました。
これがとてつもなく作業効率が良かったため使い方を備忘録として記録します。
また、知っている人には蛇足な情報も多分に含みますため、不要な方はお手数ですが適宜読み飛ばしていただければと思います。
概要
UIコンポーネントなどをライブラリの形式で提供している管理画面作成用OSS。
画面に表示するデータはAPI(Server side)から取得することが前提の設計になっており、外部通信専用プラグインも別に提供されている。
本記事内の注意
本記事の作成において、筆者がVSCodeを使用している都合上Linterの設定・動作確認はVSCodeで行っています。
またLinterは仕様が頻繁に変わる傾向にあり、少し前の記事になるとうまく動作しない場合もありますので、Linterについては公式のドキュメントを確認するなどしてください。
インストール方法
Reactの一般的なプロジェクト開始方法と同じ手順でプロジェクトを作成します。
以下Terminalのコマンドを記載します。
// npmの場合
$ npx create-react-app ./sampleProject --template=typescript
// yarnの場合
$ yarn create react-app ./sampleProject --template=typescript
$ cd ./sampleProject
// react-admin, および関連パッケージのインストール
$ yarn add -E react-admin ra-data-json-server prop-types
// VSCodeで開く
$ code .
Linterのセットアップ
eslint, preittierのインストールとセットアップをおこないます。
インストール
パッケージインストールは以下のワンライナーでインストールします。
$ yarn add -E -D eslint prettier @typescript-eslint/{eslint-plugin,parser} \
eslint-config-prettier \
eslint-plugin-{import,jsx-a11y,prettier,react,react-hooks}
補足
好みの別れる部分ではありますが、2つのオプションを指定しています。
-E でインストールパッケージのバージョン固定を行っています。
このオプションを指定しない場合、プロジェクト開始直後にインストールした際のバージョン以降の最新版をインストールするような設定になります。
するとチーム開発をしている場合や、ソースを保守する際、あとからプロジェクトに参加した人は最初に追加されたバージョンと異なるバージョンのパッケージがインストールされる可能性があります。
バージョンが異なった環境を複数の人間で開発/保守してしまうと、ライブラリによってはバージョン差異による動作不具合が発生してしてしまったり、さまざまな弊害が発生する可能性があります。
そのため、パッケージインストール時のバージョンを必ず使用するよう固定を行っています。
セッティング
プロジェクトルートにESLint、Prettierの設定ファイルを配置します。
ESLintの設定ファイルは .eslintrc
, Prettierについては .prettierrc
を作成してください。
.eslintrc
{
"env": {
"es6": true,
"node": true,
"browser": true,
"commonjs": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"ecmaFeatures": {
"jsx": true
},
"sourceType": "module"
},
"settings": {
"react": {
"version": "detect"
}
},
"plugins": ["react-hooks", "react", "@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"prettier"
],
"rules": {
"react/prop-types": "off",
"@typescript-eslint/no-explicit-any": 0
},
}
.prettierrc
{
"printWidth": 150,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"arrowParens": "always",
"requirePragma": true
}
補足
eslintのファイル名、というか拡張子については色々なサイトで色々なものが設定されていて混乱している人もいると思います。公式サイト を見ると以下のファイル形式に対応しているようです。
.eslintrc.js
.eslintrc.cjs
.eslintrc.yaml
.eslintrc.yml
.eslintrc.json
package.json
今回使用しているファイル名は .eslintrc
で拡張子を明示していませんが、この場合は少なくともjson形式で書くことで動作します。
package.jsonの場合だけ記述方法が異なるかもしれないので注意が必要です。やったことがないのでわかりませんが...
App.tsxの実装
create-react-appにより src
ディレクトリ配下にApp.tsxが作成されていますので、エディターで開きましょう。
そして中身は全て消して以下の内容に書き換えてください。
import React from 'react';
import { Admin, Resource, ListGuesser } from 'react-admin';
import { createMuiTheme } from '@material-ui/core/styles';
import jsonServerProvider from 'ra-data-json-server';
import './App.css';
// import Dashboard from './dashboard';
const theme = createMuiTheme({
palette: {
type: 'dark',
},
});
// データを取得するクライアントとエンドポイントのベースURLの初期化
const dataProvider = jsonServerProvider('http://localhost:4000/api');
const App: React.FC = () => {
return (
// dataProviderでクライアントを渡す
<Admin theme={theme} dataProvider={dataProvider} >
// Resourceタグによってページが作成される。
// nameプロパティがベースURLの後に続く、取得したいデータのエンドポイントになる。
// この場合は 'http://localhost:4000/api/users' がセットされる
// listプロパティを付与することで取得したデータを形式で表示する
<Resource name="users" list={ListGuesser} />
</Admin>
);
}
export default App;
細かい話
ソース内の細かい部分について補足します。
theme
細かい設定が面倒だったので、あらかじめreact-adminに設定されたテーマを使用することにしました。今回はdarkテーマです。
dataProvider(client)
画面表示をする際に使用するデータの取得用のクライアント設定を行っています。
このデータプロバイダは親コンポーネント(Admin)のプロパティで渡します。
Resource
- name
dataProviderで設定したURLの後に続くpath、及びページ名を設定します。
- list
公式ページ →
エンドポイント: usersから取得したデータをリスト表示するために使用しています。
今回の場合は帰ってきたデータをテーブル形式で表示します。
このテーブル表示時のカラム名について細かく指定することも可能ですが、今回は "返り値のkey情報から勝手にカラム名を設定する" ためにあえて何も書いていません。
Mockサーバーの構築
ここまでUI側の記述を行ってきましたが、データ表示をするためにはAPIサーバー(Server Side)が必要なため、今回はモックサーバーを立ち上げます。
もちろん本番では細部サーバーになりますが、今回は同じローカル環境で同時に起動させます。
(本来はDI技術などを使うべきところだと思います...)
また、本項についてはコチラ の記事内のコードを使用させていただきました。
この場を借りてお礼を申し上げるとともに、何かあればコメントでお知らせいただけますと幸いです。
インストール
今回は json-server
というパッケージを使用します。
もちろん開発環境でしか使いませんので -D
オプションを使用します。
$ yarn add -E -D json-server
コード
まずルートディレクトリに mock
というディレクトリを作成し、その中にルートファイルとなる server.js
を作成してください。
server.jsの中身は今回こんな感じです。
const jsonServer = require('json-server')
const server = jsonServer.create()
server.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, Realm')
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS')
next()
})
server.use('/api/users', jsonServer.router({
'': require('./api/user'),
}))
if (module.parent === null) {
var port = process.env.PORT || 4000
server.listen(port)
console.log('port:' + port)
}
module.exports = server
続いて
server.use('/api/users', jsonServer.router({
'': require('./api/user'),
}))
で宣言している、 /api/users
でリクエストを受けた際に返却するデータの準備をおこないます。
mockディレクトリ配下に api
というディレクトリを作成し、その中に user.js
というファイルを作成してください。
user.jsの中身は以下です。
module.exports = [{
"id": 1,
"name": "user taro",
"username": "taro-chan",
"email": "taro@dummy.com",
"phone": "0x0-xxxx-xxxx",
"website": "https://dummy.com",
"company": {
"name": "paper company",
"catchPhrase": "The internet is difficult for people who can't tell a lie from a lie",
}
}]
package.jsonに追記
開発時は今回作成したreact-adminと一緒にmockサーバーを起動したいのでpackage.jsonのscriptsに以下を追記しましょう。
"scripts": {
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"start": "react-scripts start",
"mock": "npx nodemon ./mock/server.js",
"dev": "yarn mock && yarn start"
},
動作確認
以上が終わりましたら、Terminalにて以下を実行してみましょう。
$ yarn dev
すると自動でブラウザが立ち上がり、ブラウザに作成したreact-adminのアプリケーションページが表示されると思います。
恐ろしくないですか?この程度の記述量でこれほどのものができるとは...
しかもこのデータ、csvで出力できるんです。(右上の EXPOERT
ボタン)
今回はやっていますが、セルの編集ボタンを配置してデータ編集をして更新したりするUIも作れますしchartなんかも使えるみたいです。
またページコンポーネントは結構自由にいじれたりカードスタイルで表示したりかなり便利です。というかプロジェクトの管理画面系は当面これでいこうと思います。
(認証画面も作れるようです。)
また、LINEと連携させるときにSpreadsheetを使おうとするプロジェクトもあると思いますが、Spreadsheetの弱点であるデータ更新系の動きにもこれなら自由度が高まるのでかなり工数的な意味での費用対効果が高いように思いました。
みなさんも是非使ってみましょう!
Discussion