1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Docusaurus に Elm を組み込む

Last updated at Posted at 2021-02-06

普通そのようなことはしないので需要はないと思います。

やること

以下のデモのように Docusaurus のページに Elm のアプリケーションを埋め込みます。

https://n4o847.github.io/docusaurus-elm-demo/elm-project

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
website/package.json
    "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 の設定を追加できる ので、これを使います。

website/plugins/docusaurus-plugin-elm.js
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 に以下を追加します。

website/docusaurus.config.js
  plugins: [
    [
      path.resolve(__dirname, 'plugins/docusaurus-plugin-elm'),
      {
        cwd: path.resolve(__dirname, '../elm-project'),
      },
    ],
  ],

ページを作る

Elm が動作するページを website/src/pages/ 以下に作ります。

website/src/pages/elm-project/index.js
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 のアプリケーションが動作します。

ソースコードはこちらで公開しています。

https://github.com/n4o847/docusaurus-elm-demo

また出来上がったページはここからアクセスできます。

https://n4o847.github.io/docusaurus-elm-demo/elm-project

エイリアスを追加する

相対パスによるインポートがややこしいので、エイリアスを追加しても良いです。

website/plugins/docusaurus-plugin-elm.js
          resolve: {
+           alias: {
+             [options.alias]: options.cwd,
+           },
            extensions: ['.elm'],
          },
website/docusaurus.config.js
    plugins: [
      [
        path.resolve(__dirname, 'plugins/docusaurus-plugin-elm'),
        {
+         alias: '@elm-project',
          cwd: path.resolve(__dirname, '../elm-project'),
        },
      ],
    ],
website/src/pages/elm-project/index.js
- import {Elm} from '../../../../elm-project/src/Main';
+ import {Elm} from '@elm-project/src/Main';
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?