RemixのQuickStartで入門してみる。

## 背景
普段はNext.jsを使って開発をしているのですが、下記の記事で色々話題になったRemixについて気になったので、アドベントカレンダー消化ついでにチュートリアルを走ってみます。

https://www.epicweb.dev/why-i-wont-use-nextjs

ZennでのScrapをまとめた記事です。

https://zenn.dev/rurucun/scraps/770d2a8d4fc387

## 参考

https://remix.run/docs/en/main/start/quickstart

## Installation 

```sh
mkdir my-remix-app
cd my-remix-app
npm init -y

# install runtime dependencies
npm i @remix-run/node @remix-run/react @remix-run/serve isbot react react-dom

# install dev dependencies
npm i -D @remix-run/dev
```

## Root Route

appディレクトリにroot.jsxを作成する。

```sh
mkdir app
touch app/root.jsx
```

下記のファイルを作成する。


```jsx
import {
  Links,
  Meta,
  Outlet,
  Scripts,
} from "@remix-run/react";

export default function App() {
  return (
    <html>
      <head>
        <link
          rel="icon"
          href="data:image/x-icon;base64,AA"
        />
        <Meta />
        <Links />
      </head>
      <body>
        <h1>Hello world!</h1>
        <Outlet />

        <Scripts />
      </body>
    </html>
  );
}

```


## Build and Run

下記のコマンドで、Buildする。
`build/`フォルダーにファイルがビルドされます。

```sh
npx remix build
```

アプリを実行するために、package.jsonに下記を追加します。

```json
{
  "type": "module"
  // ...
}
```

package.jsonを更新後に、次のコマンドを使用して実行します。
実行後に表示されたURLをブラウザで開くと、HelloWorldが表示されたサイトへアクセスできます。

```sh
npx remix-serve build/index.js

[remix-serve] http://localhost:3000 (http://192.168.1.1:3000)
```

![](https://storage.googleapis.com/zenn-user-upload/74fd8c88d175-20231203.png)

## 自分のサーバーを持ち込む


> `build/`のファイルはExpress、Cloudflare Workers、Netlify、Vercel、Fastly、AWS、Deno、Azure、Fastify、Firebase などのサーバー内でどこでも実行できる単なるモジュールです。
> `remix-serve`の使用をやめて、かわりにExpressを使用しましょう。

とのことで、expressでの実装を試す。


### expressのインストールとremix-serveのアンインストール

```sh
npm i express @remix-run/express

# not going to use this anymore
npm uninstall @remix-run/serve
```

### Expressサーバーを作成する。

```sh
touch server.mjs
```

```js:server.mjs
import { createRequestHandler } from "@remix-run/express";
import express from "express";

// notice that the result of `remix build` is "just a module"
import * as build from "./build/index.js";

const app = express();
app.use(express.static("public"));

// and your app is "just a request handler"
app.all("*", createRequestHandler({ build }));

app.listen(3000, () => {
  console.log("App listening on http://localhost:3000");
});

```
### Expressでアプリを実行する
```
node server.mjs
```

## 開発ワークフロー

React RefrechとRemix Hot Data Revalidationを使用して、ファイル変更で更新が入るようにする。

### `package.json` へスクリプトを追加する。

下記の変更で、Remix開発サーバーを起動し、ファイルの変更を監視してアプリをリロードするようになる。
cフラグはアプリケーション・サーバーの起動方法をしている。

ファイルが変更されると、サーバーを再起動しようとするが、Expressを自前で立てているので、ブラウザにホットアップデートを送信できるように、Remixに再起動したことを伝えます。

```json
{
  "scripts": {
    "dev": "remix dev -c \"node server.mjs\""
  }
  // ...
}
```

### broadcastDevReadyをserverに追加する

```diff js:server.mjs
import { createRequestHandler } from "@remix-run/express";
+ import { broadcastDevReady } from "@remix-run/node";
import express from "express";

// notice that the result of `remix build` is "just a module"
import * as build from "./build/index.js";

const app = express();
app.use(express.static("public"));

// and your app is "just a request handler"
app.all("*", createRequestHandler({ build }));

app.listen(3000, () => {
+  if (process.env.NODE_ENV === "development") {
+    broadcastDevReady(build);
+  }
  console.log("App listening on http://localhost:3000");
});
```

```diff app/root.jsx
import {
  Links,
+  LiveReload,
  Meta,
  Outlet,
  Scripts,
} from "@remix-run/react";

export default function App() {
  return (
    <html>
      <head>
        <link
          rel="icon"
          href="data:image/x-icon;base64,AA"
        />
        <Meta />
        <Links />
      </head>
      <body>
        <h1>Hello world!</h1>
        <Outlet />

        <Scripts />
+        <LiveReload />
      </body>
    </html>
  );
}

```


### devサーバーを起動する。

```sh
npm run dev
```

この状態でlocalhostを開き、`app/root.jsx`に変更を加えて保存すると、ファイルの変更がリアルタイムに反映されます。