RemixでつくるWebアプリケーション〜準備編〜

先日リリースされたばかりのReactベースのフレームワークRemixでWebアプリケーションをつくるための下準備について。今回はTailwindを利用したスターターキットを用意していきます。
2021.12.01

はじめに

こんにちはCX事業本部MAD事業部の森茂です。
社内はre:Invent一色ですが、フロントエンドエンジニアとしてもReact Conf 2021を前に盛り上がりたい!ということであえて先日リリースされたReactベースのフレームワークRemixについての記事を投下していきたいと思います:)

準備編として風呂敷を広げてみたのですが、今回はRemixで開発をはじめる前の下準備の紹介記事となります。次にどんな方向へ行くのかはまだわかりません🤠

Remixについての紹介はこちら

今回はRemixを使ってWebアプリケーションをつくる際のスターターキット的なものを用意してみます。なお、スタイリングにはTailwindを、デプロイ先にはRemixリリースから早々に公式対応したVercelを利用しています。

Remixのインストール

まずはRemixをインストールします。(執筆時のバージョンはv1.0.6)

v1.1から初期構築時に生成されるテンプレートがシンプルなものに変更されているため下記構成とは内容が若干異なっています。

$ npx create-remix@latest

インストール時にデプロイ先にあわせたテンプレートを選択する必要がありますが、今回はVercelを選択。ここで異なるテンプレートを選択しても後で変更することができますがそこそこ手間がかかるため先にデプロイ先を決めてからアプリケーションを作ることをオススメします。まだ確定していない場合はいったん基本的な構成のRemix App Serverを選択しておくのがよさそうです。

あとからデプロイ先を変更する場合

公式の方法では下記のように新規プロジェクトをつくりappディレクトリを移行する手法が案内されています。(追加したパッケージ類など別途手動で入れ直す必要がありますのでこのあたりが手間になるかなと思われます)

cd ..
# 新規にプロジェクトを作成します。新たに利用したいテンプレートを選択し直します。
npx create-remix@latest
cd my-new-remix-app
# 新規に作成したプロジェクトのappディレクトリを削除します。
rm -rf app
# 移行前のプロジェクトからappディレクトリを新規プロジェクトへコピーします。
cp -R ../my-old-remix-app/app app
# その後必要なファイルやパッケージ等を再インストール。

テンプレートから利用しない箇所を削除

インストール時に生成されるテンプレートにはデモ用のコードやサンプルコードが多く含まれているので不要なファイルや記述を削除します。

初期ディレクトリ構成

$ tree remix-todo-app-vercel -a -L 3 -I "node_modules|.git"
remix-todo-app-vercel
├── .gitignore
├── README.md
├── api*1
│   └── index.js
├── app
│   ├── entry.client.tsx
│   ├── entry.server.tsx
│   ├── root.tsx
│   ├── routes
│   │   ├── demos/
│   │   └── index.tsx
│   └── styles
│       ├── dark.css
│       ├── demos/
│       └── global.css
├── package-lock.json
├── package.json
├── public
│   └── favicon.ico
├── remix.config.js*2
├── remix.env.d.ts
├── tsconfig.json
└── vercel.json*1

※ (1)Remix App ServerテンプレートにないVercelテンプレート用のファイル
※ (
2)Remix App Serverテンプレートとは記載内容が異なるファイル

app/routes/demosディレクトリとその中のファイル、app/styles/内のcssファイルを削除。app/root.tsxapp/routes/index.tsxも再利用可能なものをいくつか残して必要最小限に、余分なものは削除してしまいます。Remix開発チームは文字数が少ないという理由でconstを使わずにletを利用しているそうなのですが、、、気になる箇所は書き換えておきます:)

We use let because it is only three letters, you can use const if you want 🙂

root.tsx

Layoutコンポーネント部分を削る以外はほぼそのまま流用していきます。

/app/root.tsx

import {
  Links,
  LiveReload,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
  useCatch,
} from 'remix';

// そのまま利用
export default function App() {
  return (
    <Document>
      <Layout>
        <Outlet />
      </Layout>
    </Document>
  );
}

export function ErrorBoundary({ error }: { error: Error }) {
  // そのまま利用
}

export function CatchBoundary() {
  const caught = useCatch(); // let -> constに変更
  // そのまま利用
}

function Document({
  children,
  title,
}: {
  children: React.ReactNode;
  title?: string;
}) {
  return (
    <html lang="ja">
    {/* langのみjaに変更してあとはそのまま利用 */}
  )
}

// 必要最小限に変更
function Layout({ children }: { children: React.ReactNode }) {
  return <div>{children}</div>;
}

routes/index.tsx

記載はほぼカットして一部のみ流用。

/app/routes/index.tsx

import type { MetaFunction } from 'remix';

export const meta: MetaFunction = () => {
  return {
    title: 'Remix Starter',
    description: 'Welcome to remix!',
  };
};

export default function Index() {
  return <div>Index</div>;
}

ここで問題なく開発サーバーが動作するか一度動作チェックしておきます。

$ npm run dev

> dev
> remix dev

Watching Remix app in development mode...
💿 Built in 246ms
Remix App Server started at http://localhost:3000

ブラウザでhttp://localhost:3000にアクセスして「Index」の文字が表示されればOKです。こちらをベースに進めていきます。

PostCSS/Tailwind CSS

v1.1から公式ドキュメントが更新されTailwind CSSの設定方法が変更(若干シンプル)になっています。詳細は公式ドキュメントを参照ください。

公式ドキュメント

Remixでは通常のCSSでのスタイリングを推しているようですが、今回は開発効率も考えて公式ドキュメントにも記載のあるTailwind CSSを利用する形でセットアップしていきます。ドキュメントにはCSS-in-JSを利用する記載もあるようですが色々と手間がかかりそうなのでキャンセル。。

Tailwind CSSを使うならUIコンポーネントにはTailwind CSSと同じTailwind Labsが開発しているheadless UIを使うとさらに開発が楽になります。(今回はTailwind CSSのベースキットのみをインストール)

公式ドキュメントを参考にPostCSS/Tailwind CSSのインストールとセットアップを行います。

Tailwind CSSに必要なパッケージをインストール

$ npm install -D tailwindcss@latest postcss@latest autoprefixer@latest postcss-cli@latest

Postcss、Tailwind CSSに必要な設定ファイルを新規に作成していきます。

postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {}
  }
};

tailwind.config.js

module.exports = {
  purge: [
    "./app/**/*.tsx",
    "./app/**/*.jsx",
    "./app/**/*.js",
    "./app/**/*.ts"
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {}
  },
  variants: {},
  plugins: []
};

CSSファイルについては公式ドキュメントを参考に配置していきます。編集するCSSファイルはappディレクトリ外に配置してpostcssで変換したものをappディレクトリへ置くという構造です。(.gitignoreへのapp/styles追加を推奨)

.
├── app
│   └── styles (変換されるファイルの配置先)
│       ├── app.css
│       └── routes
│           └── index.css
└── styles (編集するCSSファイルの配置先)
    ├── app.css
    └── routes
        └── index.css

.gitignore

# 追記
app/styles
.env

公式ドキュメントではCSSビルド用タスクを分けて記載、実行していますが、Postcssの変換作業を同時に実行したいので複数のコマンドを同時実行をしてくれるconcurrentlyをインストールしておきます。また、後にSupabaseなど環境変数を利用するライブラリの利用も想定してここでdot-envもあわせてインストールしておきます。

$ npm install -D concurrently dotenv

package.jsonscriptsは下記のように変更します。npm run devnpm run build時にpostcssでの変換も実行するようにしています。

package.json

...
"scripts": {
  "build:remix": "remix build",
  "dev:remix": "node -r dotenv/config node_modules/.bin/remix dev",
  "build:css": "postcss styles --base styles --dir app/styles --env production",
  "dev:css": "postcss styles --base styles --dir app/styles -w",
  "dev": "concurrently \"npm:dev:*\"",
  "build": "npm run build:css && npm run build:remix",
  "postinstall": "remix setup node",
  "start": "remix-serve build"
},
...

TailwindのベースとなるCSSファイルを/styles/app.cssとして新規に作成します。

/styles/app.css

@tailwind base;
@tailwind components;
@tailwind utilities;

root.tsxに書き出したCSSファイルを読み込むよう記載を追記します。

/app/root.tsx

...
import type { LinksFunction } from "remix";
import styles from "~/styles/app.css";

export const links: LinksFunction = () => {
  return [{ rel: "stylesheet", href: styles }];
};
...

ここであらためて$ npm run devを実行して動作を確認します。ブラウザ上でTailwind CSSのリセットCSSが反映されているのが確認できると思います。ここまででTailwind CSSを利用したRemixのスターターキットが完成です。

Vercelへのデプロイ

ここでVercelへのデプロイを確認しておきます。Vercelへのデプロイは非常に簡単でGitHubへ連携することで自動的にCI/CDを走らせデプロイまで自動的に行うことができてしまいます。なお、あらかじめGitHubのリポジトリを作成の上Vercelのアカウントを連携しておく必要があります。

使用するGitHubリポジトリを選択します。

5分程度でデプロイ完了です。これからはGitHubへPushするごとにデプロイが自動的に行われます。

これから

Remixを使ったWebアプリケーションの下準備が完了しました。
さてここから何をつくりましょう。。。Supabaseと🤔