Mendix はナンバーワンのローコード プラットフォームであり、その主な強みの 1 つは拡張性です。React を使用すると、優れたサードパーティ ライブラリを組み込んでアプリケーションを拡張できます。
これは複数部構成のシリーズの第 4 回目のブログです。以前のブログは、次の場所にあります。 ウィジェットを構築する Mendix React を使う — パート 1 — カラー カウンター, ウィジェットを構築する Mendix React パート 2 — タイマー, ウィジェットを構築する Mendix React パート 3 — カンバン.
私たちは何を構築しているのか
最近では、 イヴォ・シュトゥルム 既存の ArcGIS ウィジェットを Dojo から React に変換する方法についてブログを書きました。
面白いと思った ArcGIS マップ ウィジェットのシンプルなバージョンをゼロから構築する.

始める
これまでのプラグインウィジェットブログと同様に、まずは ウィジェットの足場 実行することにより yo @mendix/widget arcGISMap の三脚と テストの設定 Mendix プロジェクト.
始めましょう npmパッケージのインストール ArcGIS JavaScript API 用
npm install @arcgis/core
ArcGIS は、地図を表示したり、レイヤーを追加してさまざまな情報を表示できるオンライン地理情報システムです。

完全なサービスにアクセスするには アクセストークンを登録して作成する必要があります しかし、この簡単な例では、何も指定せずに先に進むことができます。
始める
のレビュー ドキュメント コードを更新して 2 つのファイルを作成できます。
親
「react」から { ReactElement、createElement } をインポートします。「./components/Map」から { MapComponent } をインポートします。「../typings/ArcGISMapBlogProps」から { ArcGISMapBlogContainerProps } をインポートします。「./ui/ArcGISMapBlog.css」をインポートします。
エクスポート関数 ArcGISMapBlog(props: ArcGISMapBlogContainerProps): ReactElement { return ; }
そして子供
「react」から { ReactElement、createElement、useEffect、useRef } をインポートします。「コア/Map"; MapView をインポートします "コア/views/MapView"; 凡例をインポートします "コア/ウィジェット/凡例";
エクスポートインターフェース MapProps { basemap: string; }
関数 MapComponent({ basemap }: MapProps): ReactElement をエクスポートします { const mapDiv = useRef(null);
useEffect(() => { if (mapDiv.current) { MountMap(basemap); } }, [basemap]);
const MountMap = (basemap: string): MapView => { const legend = new Legend(); const map = new Map({ basemap }); const view = new MapView({ map, center: [0.029, 51.256], // 経度、緯度 zoom: 10, // ズーム レベル container: mapDiv.current as unknown as HTMLDivElement });
legend.view = view; view.ui.add(legend, "bottom-right"); view を返します; };
戻る; }
レッツ ArcGISからスタイルシートもインポートします ウィジェットの見栄えを良くするために、UI/{widgetName}.css を次のように変更します。
@import "https://js.arcgis.com/4.24/@arcgis/core/assets/esri/themes/dark/main.css";
ウィジェットを構築します npm run build そして…エラーが発生します:
[!] エラー: オプション「output.file」の値が無効です。複数のチャンクを構築する場合は、「output.file」ではなく「output.dir」オプションを使用する必要があります。動的インポートをインライン化するには、「inlineDynamicImports」オプションを設定します。
では、これをどうやって解決するのでしょうか? 説明するために、少し前に戻る必要があります...
Javascriptの簡単な歴史
次のセクションでは、ソリューションの背景を説明するために、JavaScriptの簡単な歴史を説明します。興味がない場合は、飛ばして例を続けてください。
最初は…
Javascript は 1995 年に Brendan Eich によって発明され、開発の最初の数年間は主に独立したスクリプト タスクに使用されていました。JS がアプリケーションでより多く使用されるようになると、コードの管理が難しくなりました。JS は複数のスクリプトにまたがる複雑な方法で使用されることが多くなり、必然的に機能と名前の競合が発生しました。
そのため、モジュールの概念が導入されました。これにより、他の場所での競合を恐れることなく、内部使用のために閉じた場所でコードを記述できるようになり、開発者は大規模なコードベースを小さな個別の部分に分割できるようになり、コードの作成と保守がはるかに簡単になりました。
これを解決するための最初の試みは 即時呼び出し関数式 (IIFE)これは基本的に各ファイルを関数でラップし、変数と関数をファイル内に保持し、グローバル スコープではなくそのスコープ内に保持します。
(function() {// Your code }) ();
このアプローチには、依存関係の解決の欠如や グローバル名前空間の汚染.
時間が経つにつれて、3 つの別個の (競合する) モジュール仕様が登場しました。
- CommonJS — Nodeでは今でもサーバーサイドJSに広く使用されており、その名前から簡単に認識できます。
require()の三脚とmodule.exports構文 - AMD — 非同期モジュール定義。CommonJS から早期に分離されました。主な違いは、AMD では相互に依存しないモジュールを非同期で読み込むことができることです (名前の通りです)。
- UMD — ユニバーサルモジュール定義は、他のモジュール仕様と「古いスタイル」の「グローバル」変数定義の両方をサポートします。
これは非常に複雑です…そこで良いニュースがあります。2015年にES6がリリースされて以来、 モジュールはJavaScript言語内でサポートされていますこれによって、美しくシンプルなimport の三脚と export コード内で使用している構文です。
では、なぜ歴史の授業が必要なのでしょうか? それは、コードを書くときにこれらすべてのモジュール タイプを処理できる必要があり、そこでバンドラーが役に立つからです。
バンドラー
バンドラーを使用すると、 ビルド時にコードをコンパイルする, 依存関係を処理する, 互換性のある連結ファイルを提供する一般的な解決策としては、 Webpack (で使われる Mendix 8ウィジェット)と 巻き上げる (で使われる Mendix 9 ウィジェット)
これにより、最新の ES6 機能 (必要に応じて Typescript も) を使用してコードをモジュール形式で記述し、ブラウザーに提供される最適化されたファイル (またはファイル セット) を生成できます。
これは素晴らしいことですが、一部のブラウザはまだES6をサポートしていないため、これらの適切にコンパイルされたファイルで何もできません。これを修正するには トランスパイラを使うことができます 例えば、 バベル 読み取り可能な形式でウェブページに提供します。
それで、ウィジェットに戻りましょう...
プラグ可能なウィジェットフレームワークには、Reactコンポーネントを開発するために必要なすべてのツールが必要です。 Mendix アプリ。これには以下が含まれます。
- npm — サードパーティのパッケージを簡単にインストールおよび管理できるパッケージマネージャー
- 巻き上げる — コードをモジュール化して記述し、小さなパッケージにまとめることができるバンドラー
- バベル — JS を古いブラウザ (および Studio Pro) で読み取れる形式に変換するトランスパイラ
それで、このエラーは何を意味するのでしょうか?
[!] エラー: オプション「output.file」の値が無効です。複数のチャンクを構築する場合は、「output.file」ではなく「output.dir」オプションを使用する必要があります。動的インポートをインライン化するには、「inlineDynamicImports」オプションを設定します。
各ウィジェット プロジェクトでは、@mendix/pluggable-widget-tools ライブラリによって提供されるロールアップ構成を使用します。
これは次の場所にあります: node_modules/@mendix/pluggable-widget-tools/configs.rollup.config.js。
この構成では、 ウィジェットにコンパイルされたJSを1つのファイルに吐き出すように指示する。 また、 ArcGIS npm ライブラリ 私たちは提供を使用しています チャンクでの動的インポートデフォルトでは ロールアップはディレクトリに別々のファイルとして吐き出そうとします.
これを修正するには、エラーに書かれている通りに実行し、 inlineDynamicImportsオプションを設定する、すべてを1つのファイルにまとめます。Pluggable Widgetsライブラリのrollup.config.jsファイルを変更することはできますが、これはメンテナンスが難しく、読みにくくデバッグしにくいコードを作成するため、非常に悪いアイデアです。幸いなことに Mendix 独自のロールアップ設定を設定するための機能が組み込まれています.
必要がある ファイルを作成する rと呼ばれるollup.config.js ルート ウィジェット ディレクトリに次の JS コードを追加して、ウィジェットの構築方法を変更します。
export default args => { const result = args.configDefaultConfig; console.warn ('カスタム ロールアップ') return result.map((config) => { config.output.inlineDynamicImports = true console.warn ("動的インポートを設定します") return config; }); };
だから私たちは走る npm run build 再度実行すると、新しいエラーが発生します:
致命的なエラー: ヒープ制限に達しました。割り当てに失敗しました - JavaScript ヒープのメモリが不足しています
ビルドプロセスにはより多くのメモリが必要であることがわかりました。これを更新するには、次のコマンドを実行します。
エクスポート NODE_OPTIONS=--max_old_space_size=5120
再構築するとウィジェットがコンパイルされるようになります。
私たちのバンドラーは、ブラウザで簡単に読み取ることができる単一のファイルを作成するのに役立ちます。
Rollupは他にも非常に賢い機能を持っています。 ツリーシェイク: これは、 コード内の依存関係ツリー の三脚と 実際に必要なコードのみを含めるこれは特に大きなライブラリを使うときに役立ち、ブラウザに大量の未使用のコードをロードすることを避けることができます。このツリーシェイキングは、 Mendix webpackからrollupに切り替えました Mendix 8と9。
バンドラーには他にもたくさんの機能があり、ロールアップではプラグインの形で提供されます。このブログで最後に取り上げたいのは、ウィジェットのロールアップ設定を変更しなければならない非常に一般的なユースケースです。
ウィジェットに必要なファイルを提供する
ArcGISは、マップを作成するために必要なファイルを コンテンツ配信ネットワーク(CDN) しかし、 保存しておきたいインスタンス ウィジェット内でこれらのファイルを管理しますおそらく、組織内のファイアウォール設定が原因です。幸い、ArcGIS Javascript API を使用するとこれが可能になります。
まず最初にすべきことは、コードを更新して APIに伝える 私たちがなること 資産を現地で管理するこれを行うには、コンテナ コンポーネントを更新して次の内容を含めるだけです。
esriConfigを「コア/config.js";
エクスポート関数 ArcGISMapBlog(props: ArcGISMapBlogContainerProps): ReactElement { esriConfig.assetsPath = "./widgets/mendix/arcgismapblog/assets"; 戻り値; }
次に、 update 私たちの 巻き上げる 〜へ ファイルを拾い上げ ノードモジュールから必要なものと ウィジェットに載せる mpk。
これを実現するために ロールアップコピープラグインを使用する (あらゆるものにプラグインがあります)、まずそれをインストールする必要があります
npm i rollup-plugin-copy —save-dev
私たちは、使用 —save-dev コマンドは開発中にのみ必要な依存関係であるため、このコマンドは不要です。次に、rollup.config.js を次のように更新します。
import copy from "rollup-plugin-copy"; export default args => { const result = args.configDefaultConfig; console.warn ('カスタム ロールアップ') return result.map((config) => { config.output.inlineDynamicImports = true console.warn ("動的インポートの設定") const plugins = config.plugins || [] config.plugins = [ ...plugins, copy({ target: { src:"node_modules/@arcgis/core/assets", dest:"dist/tmp/widgets/mendix/arcgismapblog" }]
}), ] config を返します。 }); };
この 「資産」を取得する ArcGIS npmパッケージのフォルダーと dist/tmpフォルダにドロップします これが最終的に圧縮されてmpkが作成されます。アプリケーションを実行すると、ウィジェットmpkの内容が提供されます。 ./widgets/{組織名}/{ウィジェット名}.
これを実際に確認するには、ウィジェットを作成するコマンドを実行してみましょう。
npm ビルドを実行する
その後、アプリを再実行できます。

展開ディレクトリを開くと、ウィジェットがアセットフォルダを提供していることがわかります。また、Chrome 開発ツールでページソースを確認すると、マップが機能していることを確認するために ArcGIS Web アセンブリファイルがブラウザに提供されていることがわかります。
ローカル ファイルを使用するために CSS を更新しませんでした。これを行うには、ファイルを次のように更新するだけです。
@import "../assets/esri/themes/dark/main.css";
シンプル…っぽい…。
あなたが 9.13.2 以下のプラグイン可能なウィジェット ツール Windowsを使用している場合は、 フォントは正しくインポートされませんインポートを修正するには、rollup.config.js に次のコードが必要です。
「postcss-url」から postcssUrl をインポートします。
const cssUrlTransform = asset => { const outWidgetDirForwardSlash = outWidgetDir.replace(/\\/g, "/") return asset.url.startsWith(`${assetsDirName}/`) ? `${outWidgetDirForwardSlash}/${asset.url}` : asset.url; }
export default args => { const result = args.configDefaultConfig; console.warn ('カスタムロールアップ') return result.map((config) => { config.output.inlineDynamicImports = true console.warn ("動的インポートを設定する") const plugins = config.plugins || [] config.plugins = [ ...plugins, postcssUrl (cssUrlTransform)
] config を返します。 }); };
その後、 npm install postcss-url --save-dev ウィジェットがアイコン付きでレンダリングされるようになりました。
これで完了です。
ArcGIS API には素晴らしい機能が満載なので、ぜひ試してみてください。その機能の素晴らしい例を見るには、Ivo Sturm のウィジェットをご覧ください。 GitHub – ivosturm/ArcGIS-React: React をベースにした新しく改良された ArcGIS ウィジェット私の ArcGIS ウィジェットのリポジトリは次の場所にあります: GitHub – joe-robertson-mx/arcGISMapBlog.