🍋

Freshハンズオン 初級編

2024/03/02に公開

ハンズオン用の記事です。随時修正・アップデートされます。
対象レベルは「少々JavaScriptが書ける」初心者向けです。中級編はこちら
色々端折るために拡張機能をインストールします。Next.jsなどに親しんでフロントエンドをバリバリやっている方には冗長な説明が多いと思います。上級者は公式ドキュメントを全部読み込むことをおすすめします。

Freshの特徴

Freshはシンプルさと速度、信頼性に重点を置いたDeno用のWebフレームワークです。

特徴としては「サーバサイドレンダリング」を基礎に下記の特徴を備えています。

  • 必要がない限りゼロJavaScript
  • 基本的にすべてTypeScript
  • ビルドステップなし(条件あり)

この結果、型の恩恵を受けながら、極力軽量な構成でWebアプリケーションを作ることができます。

ゼロJavaScript

FreshはIsland architectureという動的Webアプリケーションのための仕組みを持っていますが、使わなくても構いません。フレームワークを使う場合なんやかんやでJSコードが足されることがありますが、FreshでJSを使わなければ最低限のHTMLコードだけが出力されます。

// index.tsx
export default function Home() {
  return (
    <h1>
      Hello, world
    </h1>
  );
}

手書きでHTMLを書くノリでJSXを書けばそれがWebページになります。簡単ですね。

TypeScriptサポート

Freshでデフォルトで生成される雛形はTypeScript(TSX)です。

JavaScriptを使ってWebページを作っていると、なんかページが動かなくなってコンソールを見ると大量のエラーを吐いていた、みたいなことがあると思います。

TypeScriptでページを作っていれば、変数名の変更によるエラーやundefinedエラーのような基礎的なコーディングミスは書いている最中に気づくことができます。

例えばこんな著書リストを持っていたとき、

export const books = [
  {
    id: 1,
    title: '吾輩は猫である',
    image: "neko.jpg",
  },
  {
    id: 2,
    title: "坊っちゃん",
    image: "bocchan.jpg",
  },
  {
    id: 3,
    title: '三四郎',
    image: "sanshiro.jpg",
  }
]

書名を title と間違えて name にしてもこのようにすぐ気づくことができます。

やっぱり title じゃなくて name にしたいなーと思ったとき、VSCodeのリネーム機能で整合性を保ったまま変更することができます。

deno fmtなどのフォーマッタがデフォルトで使えることも利点の一つです。

Freshは小さめのフレームワーク

ここまでなら、他のフレームワークでも似たようなのあるな、みたいに思われたかもしれません。

Freshはこういった機能を実現していながら、最小構成のファイル数は少なめです。

webpack.config.jstsconfig.jsonも見当たらないことがわかります。

フレームワーク自体も大きくなく src 下は 60ファイル / 6311行くらいらしいです。全部読みきれないこともないですね。FreshはDenoそのものの機能をうまく活かしながら小さくシンプルに作られています。

Freshにできないこと

Freshは概ねなんでも作ることができますが、静的サイトジェネレータとして使うことはできません。また、ReactではなくPreactを採用していることに留意する必要があります。

静的サイトジェネレータが必要な場合はLumeを検討してください。

準備

下記のツールをインストールしてください。

VSCode拡張のインストール

テンプレートは公式ドキュメントから取ってきてもいいのですが、簡易化のためにVSCode拡張機能を作りました。

https://marketplace.visualstudio.com/items?itemName=hashrock.fresh-framework-helper

Freshで簡単なWebサイトを作ってみよう

まず、任意のディレクトリでターミナルを開き、下記のコマンドでinitします。

deno run -A -r https://fresh.deno.dev my-fresh-app

すると初期化する設定を聞かれるので、styling libraryはN, VSCodeはyで回答します。

その後に下記のコマンドでVSCodeで開き、そのままサーバを起動します。

cd my-fresh-app
code .
deno task start

http://localhost:8000/ を開くと下記のようなページが開きます。

最小構成にしよう

まずは下記の赤点をつけたファイルをすべて削除してしまってください(フォルダは残しておいてください)。

その後、routesフォルダを右クリックし、 New Route Componentを選択します。

ファイル名はindex.tsxのまま、そのままEnterを連打してデフォルト(Async route=No, Simple JSX Page)で作成します。

するとこのようなページが作成されます。

ブラウザをリロードすると、下記のシンプルなページができます。

好きに書き換えて、オートリロードが走ることを確認してください。

複数のページを作ってみよう

同じ手順で foo.tsxを作成してください。

VSCodeのエクスプローラの下にある「FRESH ROUTES」というペインを開いてください。

Freshはファイルベースルーティングを採用しており、「foo.tsx」というファイルを配置すると
http://localhost:8000/foo でアクセス可能になります。

なお下記アイコンをクリックするとブラウザで開きます。

動的なルートを作ってみよう

今度は New Route Componentの最初の項目に users/[name] と入力します。

今度は3つ目の設問で「Dynamic Handler」を選択します。

拡張機能の不備で、エラーになってしまうので、生成したページの関数名を「Users/[name]」から「Page」という名前に変更します(実は名前は何でも良いです)。

これはNext.js同様の動的マッチするルートコンポーネントです。http://localhost:8000/users/hoge にアクセスすると「Greetings to you, hoge!」というメッセージが表示されます。

ガワを作ってみよう

FreshにはLayoutという機能があり、特定のルート以下を包むようなページを作成できます。routesフォルダを右クリックして New Layout を選択します。

外側のdivにstyleを追加すると、すべてのページに赤い枠線が付加されます。

export default function Layout({ Component, state }: PageProps) {
  return (
    <div class="layout" style="border: 1px solid red;">
      <Component />
    </div>
  );
}

部品を作ってみよう

componentsフォルダを右クリックして"New Component"を選択してください。

コンポーネント名はMyComponentにしてみます。すると下記のようなコンポーネントが生成されます。

import { JSX } from "preact";

export function MyComponent(props: JSX.HTMLAttributes<HTMLDivElement>) {
  return (
    <div {...props}>
      <h1>MyComponent</h1>
    </div>
  );
}

このコンポーネントを使うには、好きなルートで <MyCo... のように入力すると補完候補に出てくると思いますので、そのままEnterで確定します。

すると自動的に import { MyComponent } from "../components/MyComponent.tsx"; という行が追加され、コンポーネントがimportされます。

タグを閉じて確定すると、MyComponentがimportされるはずです。

ここまででFreshのルーティング機能とレイアウト機能を紹介しました。

※なお、Freshのドキュメントに上記の「Component」に相当する機能の説明はありません。今作ったコンポーネントはJSXの機能の範疇であり、Fresh側の機能ではないということを意味します。Freshのinitしたプロジェクトにはcomponentsディレクトリが存在しますが、別にその名前である必要はなく、どこに置いてもよかったりします。
※Freshに特別扱いされるコンポーネントとしてはislandsが挙げられます。こちらは自動的にハイドレーションが行われるため、 islands フォルダ内に置かれ、default exportを公開するなどの規約が存在します。

Deno Deployで公開してみよう

FreshはDeno Deployで使うのが最もスムーズです。まずはDeno Deployへのサインアップを済ませてください。無料です。

下記コマンドでdeployctlをインストールします。

deno install -Arf jsr:@deno/deployctl

そして、プロジェクト内で下記を実行します。

deployctl deploy

なんとこれだけでデプロイされ、URLが発行されます。

好きにコードを更新して、何度でもデプロイしてみてください。2回目以降はプレビューURLが発行されるのみとなり、本番環境を更新するには--prodオプションが必要になります。

以上でシンプルなWebページを作るチュートリアルは終了です。

Discussion