はじめに
今年のはじめにIonic 4がリリースされました。
Ionic 4では、UIコンポーネントがWebComponentsで再実装されたことにより、ReactやVueでもIonicが利用できるようにななっています。
ということで、早速React版の @ionic/react を動かしてみたいと思います。
(バージョン4.8.0-rc.0で動作確認しました。)
@ionic/react を利用するためにはWebpackでいくつかの設定が必要です。
Ionic CLIやcreate-react-appを利用することで、それらが設定済みの状態で@ionic/reactの利用ができます。
(どちらも内部的には react-scripts を使用しています。)
しかし、それらの環境では不必要なパッケージもたくさん導入されてしまうでしょう。
ビルド環境を自分でカスタマイズしたい人や、既存のReactアプリにIonicを組み込みたい人向けに、最小構成で@ionic/reactが動く環境を作ってみます。
パッケージのインストール
以下のようにパッケージを初期化し、必要なパッケージをインストールします。
$ npm init -y
$ npm i @ionic/react react react-dom react-router@4 react-router-dom@4
$ npm i -D @babel/core @babel/preset-react @svgr/webpack babel-loader css-loader style-loader url-loader webpack webpack-cli webpack-dev-server
Webpackの設定
以下のように webpack.config.js
を書きます。
const path = require('path')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react']
}
},
include: [
path.resolve(__dirname, 'src')
]
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
}
]
},
{
test: /\.svg$/,
use: [
'@svgr/webpack',
'url-loader'
]
}
]
},
entry: {
bundle: './src/index'
},
output: {
path: path.join(__dirname, 'public'),
filename: '[name].js'
},
devServer: {
historyApiFallback: true,
contentBase: path.join(__dirname, 'public')
},
mode: process.env.NODE_ENV || 'development'
}
アプリの実装
こんな感じでアプリを実装します。
説明を簡単にするために1ファイルだけの簡単なものです。
Reactに使い慣れた方であれば普通のコンポーネントライブラリとして利用できるでしょう。
import '@ionic/core/css/core.css'
import '@ionic/core/css/ionic.bundle.css'
import React from 'react'
import { render } from 'react-dom'
import {
BrowserRouter as Router,
Route,
Switch
} from 'react-router-dom'
import {
IonApp,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonList,
IonTitle,
IonToolbar
} from '@ionic/react'
import { add } from 'ionicons/icons'
const MainPage = () => {
const [items, setItems] = React.useState(['A', 'B', 'C'])
return <>
<IonContent>
<IonList>
{
items.map((item, i) => {
return <IonItem key={i}>{item}</IonItem>
})
}
</IonList>
</IonContent>
<IonFab vertical='bottom' horizontal='end' slot='fixed'>
<IonFabButton
onClick={() => {
const newItems = Array.from(items)
newItems.push('new item')
setItems(newItems)
}}
>
<IonIcon icon={add} />
</IonFabButton>
</IonFab>
</>
}
const App = () => {
return <Router>
<IonApp>
<IonHeader>
<IonToolbar>
<IonTitle>Hello @ionic/react</IonTitle>
</IonToolbar>
</IonHeader>
<Switch>
<Route path='/' component={MainPage} />
</Switch>
</IonApp>
</Router>
}
render(<App />, document.getElementById('content'))
HTMLファイルはこんな感じです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width">
<title>@ionic/react minimum start</title>
</head>
<body>
<div id="content"/>
<script src="bundle.js"></script>
</body>
</html>
以下のコマンドで実行します。
$ npx webpack-dev-server
http://localhost:8080/ にアクセスすると以下のように表示されます。
(Chromeのモバイルエミュレーションでの画面です。)
おわりに
最後に、わかった範囲で @ionic/react を正しく動かすためのポイントをまとめます。
-
@ionic/core/css/core.css
と@ionic/core/css/ionic.bundle.css
を読み込む- 今回は
style-loader
とcss-loader
を使用しましたが、結果的に必要なcssが読み込めれば手段は何でもOKです
- 今回は
-
ionicons
内のSVGファイルを正しく読み込む-
IonIcon
の動作に必要です -
@svgr/webpack
とurl-loader
を使うことで、importしたSVGがData URI形式で扱われます -
file-loader
でも代替可能ですが、全てのSVGファイルがアセットとして書き出されます
-
もっと良い方法があったら教えてください。
Ionicは元々Angularをベースに作られていました。
Ionic 4では、これぐらいの最小限のReactプログラムでIonicを利用できるようになっていて素晴らしいですね。