🕸️

FileMaker JavaScript アドオンのようなReact Appを作る

2021/02/28に公開

はじめに

  1. JavaScriptをGoogle使えばそれなりに書けること
  2. Terminalなどのコマンドラインを使ったことがること
  3. Node.js を自力でインストールできること

を想定しています。

今回Reactはほぼ使わないので、知らなくても大丈夫だと思います。
気になることがあれば公式ドキュメント参照してください。
Hello World – React

事前に FileMaker Web ビューアとJavaScriptアドオンを分析 を見ておくと理解が深まるかも。

また、今回のコードはGitHubにおていあります。
コピーしてそのまま使っていただいて問題ありません。

GitHub: hazi/fmapp_calculator_sample

Node.js

色々なインストール方法がありますが、これから開発をするのであれば、nodebrewなどを使い複数のバージョンのNode.jsが管理できるような環境をお勧めします。

下記の環境での実行となります。

node -v
> v15.9.0
yarn -v
> 1.22.10

作るもの

今回は簡単な計算機アプリを作り、1つのHTMLファイルにコンパイルするまでを目的とします。

FileMaker向けWebアプリを開発する際に手動で1つのHTMLファイルにまとめる作業からの脱却を目標としいます。

とにかく手早くWebアプリを作ることを目標としているため、場合によっては(React使わない場合など特に)適さない場合もありますのでご注意ください。

create-react-app

webpackを1から書いて管理するのはとても面倒なので、サクッとReact Appが作れる create-react-app を使って簡単な計算機を作りましょう。

npx create-react-app fmapp_calculator
cd fmapp_calculator
yarn start

ブラウザが開き、デモアプリがブラウザ上で動作することを確認します。

1. 簡易計算機を作る

src/app.js を開き下記のコードをコピペしてください。

src/app.js
import './App.css';
import * as React from 'react';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      result: 0
    };

    this.onChange = this.onChange.bind(this);
  };

  onChange(event) {
    const result = this.calculation(event.target.value);
    this.setState({result});
  };

  calculation(formula) {
    try {
      const filterd = formula.match(/[0-9]|\.|\*|\+|-|\/ /g);
      if (filterd === null) return "";

      return Function('"use strict"; return (' + filterd.join('') + ')')();
    } catch (error) {
      console.log({error: error});
      return "?";
    }
  };

  render() {
    return (
      <div>
        <h1>簡易計算機</h1>
        <p>
          <input type="text" onChange={this.onChange} /> = <input type="text" value={this.state.result} readOnly />
        </p>
      </div>
    );
  }
}

左のフィールドに 1 + 1 と入れると、右のフィールドに 2 が出るような計算機です。

yarn start

で動作確認を行い問題がなく動作することを確認してください。

2. とりあえずbuildしてみる

yarn build コマンドでとりあえずビルドしてみましょう

yarn build

すると、build ディレクトリにファイルが出力されます。
これをサーバーにアップロードすれば先ほどの yarn start と同じアプリが動きます。

3. HTML 1ファイルにまとめる

通常のWebアプリとしてはこのままで大丈夫ですが、FileMakerでは複数のCSS, JavaScript, HTMLを扱うのは難しいので、1つのファイルにまとめます。

通常は、webpack.config.js を使ってwebpackの設定をカスタマイズするのですが、今回はcreate-react-app を使っているためそれが行えません(create-react-app は複雑な設定不要でアプリを作れることを目標としているためそういう仕様)。

yarn eject を使って、それらの設定を行えるようにすることもできますが、大量の設定ファイルが剥き出しになって create-react-app を使っている意味が薄れるので、今回は react-app-rewired を使用します。

参考: react-create-appで作成したTypeScriptのプロジェクトのwebpack.configを上書きする | I am mitsuruog

まず、react-app-rewired をパッケージに追加します。

yarn add -D react-app-rewired

その後、package.json を下記のように書き換えます。

package.json
"scripts": {
-  "start": "react-scripts start",
-  "build": "react-scripts build",
-  "test": "react-scripts test",
+  "start": "react-app-rewired start",
+  "build": "react-app-rewired build",
+  "test": "react-app-rewired test",
   "eject": "react-scripts eject"
},

次に、HTMLを1つにまとめてくれる html-webpack-inline-source-plugin を追加します。
ただ、現在(2021/02/28)beta版の1.0.0-beta.2 でないとうまく動きませんので、beta指定します。

正式版がリリースされてたらそっちを使いましょう。

バージョン情報: html-webpack-inline-source-plugin - npm

yarn add -D html-webpack-inline-source-plugin@1.0.0-beta.2

準備ができたので、webpack.config.js を書き換えるための config-overrides.js を作成します。

config-overrides.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');

module.exports = function override(config, env) {
  if (env === 'production') {
    config.plugins.find(plugin => Object.getPrototypeOf(plugin).constructor.name === 'HtmlWebpackPlugin')
      .options.inlineSource = '.(js|css)$'
    config.plugins.push(new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin))
  }
  return config
}

これで yarn build すれば完成するのですが、現在不要なファイルが多いのでそれを削除します。

./public 以下の index.html 以外を削除します。

終わったら

yarn build

でビルドします。

4. FileMaker に組み込む

あとはお好きな方法でHTMLをFileMakerに取り込んでもらっていいのですが、私が現在採用している方法は下記の方法です。

  1. サーバー内に1つWebアプリのソースを管理するためのテーブルを作る(Library.fmp12など)
  2. WebApps テーブルを作り、下記のフィールドを追加
    • name(文字列)
    • html(オブジェクト)
    • source(計算フィールド)
      計算結果: テキスト
      計算式
      TextDecode(html; "utf-8")
      
  3. ExecuteSQL を使って WebApps::source フィールドを利用時に引っ張る。
    キーは name を使う。
    ExecuteSQL(
      "SELECT source FROM WebApps WHERE name = 'calculator'";
      ""; "")
    

です。

複数箇所で同じアプリを使う際に一括アップデートが行えるようにテーブルで管理するのがおすすめです。
またコピペでソースをインポートしたりする作業が危ないので、オブジェクトフィールドにコンパイルしたindex.html をドラッグ&ドロップで設置できるようにオブジェクトフィールドを利用しています。

必要に応じてバージョン情報などを追加してあげるといいかもしれません。

リポジトリの example/library.fmp12 に簡易的なファイルを置いてあります。

example/library.fmp12

おわりに

今回はあくまで簡単なReact AppをFileMakerに持っていくところまでをご紹介しました。
create-react-app のおかげでパッと作ることができました。

好きなエディタを使って、編集・保存したらブラウザで自動的に更新される開発環境も整いました(書き忘れてましたが yarn start したら自動更新されます)。

ただ、ここからReactの枠組みを超えたことをしようとしたり、Reactをそもそも使わない場合などはwebpackの設定を自分で作る方法を使わなくてはいけません。

そのあたりはまた今度。

Discussion