普通そのようなことはしないので需要はないと思います。
やること
以下のデモのように Docusaurus のページに Elm のアプリケーションを埋め込みます。
Docusaurus プロジェクトを用意する
Docusaurus v2 のデフォルトの初期化によって作られる 以下のようなフォルダ構造 を前提とします。
website
├── blog
│ ├── 2019-05-28-hola.md
│ ├── 2019-05-29-hello-world.md
│ └── 2020-05-30-welcome.md
├── docs
│ ├── doc1.md
│ ├── doc2.md
│ ├── doc3.md
│ └── mdx.md
├── src
│ ├── css
│ │ └── custom.css
│ └── pages
│ ├── styles.module.css
│ └── index.js
├── static
│ └── img
├── docusaurus.config.js
├── package.json
├── README.md
├── sidebars.js
└── yarn.lock
Elm プロジェクトを作る
場所はどこでも良いですが、Elm プロジェクトを配置します。
├── elm-project
│ ├── src
│ │ └── Main.elm
│ └── elm.json
└── website
└── ...
elm, elm-webpack-loader, elm-hot-webpack-loader をインストール
$ cd website
$ yarn add elm elm-webpack-loader elm-hot-webpack-loader
"dependencies": {
"@docusaurus/core": "2.0.0-alpha.70",
"@docusaurus/preset-classic": "2.0.0-alpha.70",
"@mdx-js/react": "^1.6.21",
"clsx": "^1.1.1",
+ "elm": "^0.19.1-5",
+ "elm-hot-webpack-loader": "^1.1.8",
+ "elm-webpack-loader": "^7.0.1",
"react": "^16.8.4",
"react-dom": "^16.8.4"
},
elm はグローバルにあれば十分ですが CI 環境でもコンパイルするには必要です。
elm-webpack-loader は Elm を JavaScript からモジュールとして読み込むのに必要です。
elm-hot-webpack-loader は必須ではありませんが、ローカルサーバでの実行中に Elm のソースファイルを変更しても、状態が保存されたままリロードされるようになります。
プラグインを作る
Docusaurus の プラグインの作り方 に従ってプラグインを作ります。
Webpack の設定を追加できる ので、これを使います。
module.exports = function (context, options) {
return {
name: 'docusaurus-plugin-elm',
configureWebpack(config, isServer, utils) {
return {
resolve: {
extensions: ['.elm'],
},
module: {
rules: [
{
test: /\.elm$/,
exclude: [/elm-stuff/, /node_modules/],
use: [
utils.getCacheLoader(isServer),
'elm-hot-webpack-loader',
{
loader: 'elm-webpack-loader',
options: {
cwd: options.cwd,
},
},
].filter(Boolean),
},
],
},
};
},
};
};
(getCacheLoader
が CI 環境では null
を返すというのが引っかかりポイントでした……。)
これを読み込むために website/docusaurus.config.js に以下を追加します。
plugins: [
[
path.resolve(__dirname, 'plugins/docusaurus-plugin-elm'),
{
cwd: path.resolve(__dirname, '../elm-project'),
},
],
],
ページを作る
Elm が動作するページを website/src/pages/ 以下に作ります。
import React, {useEffect, useRef} from 'react';
import Layout from '@theme/Layout';
import {Elm} from '../../../../elm-project/src/Main';
function ElmProject() {
const elmNode = useRef(null);
useEffect(() => {
Elm.Main.init({
node: elmNode.current,
});
}, []);
return (
<Layout>
<div ref={elmNode}></div>
</Layout>
);
}
export default ElmProject;
完成
完成です。website/ 内で yarn start
を実行して上で作ったページにアクセスすると、Elm のアプリケーションが動作します。
ソースコードはこちらで公開しています。
また出来上がったページはここからアクセスできます。
エイリアスを追加する
相対パスによるインポートがややこしいので、エイリアスを追加しても良いです。
resolve: {
+ alias: {
+ [options.alias]: options.cwd,
+ },
extensions: ['.elm'],
},
plugins: [
[
path.resolve(__dirname, 'plugins/docusaurus-plugin-elm'),
{
+ alias: '@elm-project',
cwd: path.resolve(__dirname, '../elm-project'),
},
],
],
- import {Elm} from '../../../../elm-project/src/Main';
+ import {Elm} from '@elm-project/src/Main';