たった数分で環境構築が完了!TypeScriptでWebアプリケーション開発ができるフレームワーク「frourio」が本当に手軽だった。

たった数分で環境構築が完了!TypeScriptでWebアプリケーション開発ができるフレームワーク「frourio」が本当に手軽だった。

Kazuya Takato

Kazuya Takato

こんにちは、エンジニアのづやです。

突然ですがエンジニアのみなさん、TypeScriptに触れた経験はありますか? TypeScriptはGitHubが毎年発表しているランキングで今年4位に急上昇したくらい、もっともアツいプログラム言語の1つです。

エンジニアの言語の使用頻度がグラフになっている出典:https://octoverse.github.com/

しかし、いざ試してみようと思っても、

 

  • フレームワークは何を使えば良い?
  • どうやって導入したら良い?

など、意外とハードルって高くないですか?

そこで「frourio(フルーリオ)」という画期的なフレームワークを見つけました。こういうのってある程度経験を積んだエンジニアでないと使いこなせない……というケースも多いですよね。

でもfrourioはそんなことはなく、TypeScriptに触れたことがないエンジニアでも、サクッと使えるフレームワークなんです!

どんな感じなのか実際に触っていこうと思いますが、その前にfrourioについて少し説明します。

 

「frourio」とは?

frourioのサイトのファーストビューhttps://frourio.io/

端的にいうとTypeScriptのフルスタックフレームワークです。

フルスタックフレームワークとは?
フロントエンドからバックエンド、DBの操作(O/Rマッパー)までWebサービス開発に必要な機能のほぼ全てを含んだプログラムの集合です。代表的な例としては、Ruby on RailsやPHPのLaravelなどがあります。

frourioはフロントエンドからバックエンドまで全てTypeScriptで開発できます。RailsやLaravelを使うとフロントエンドではJavaScriptを書く必要があり、2つの言語を習得する必要があります。

一方、frourioはTypeScriptだけでWebサービス全体を開発することが可能で、開発速度と品質の両方を向上できることが大きな特徴。プログラム全体を通してタイプミスやエラーの原因になる操作が行われていないかどうかをTypeScriptが自動検知してくれるので安心です。

ちなみにfrourioを開発したのは松田さん(@m_mitsuhide)という方で、Qiitaで執筆した記事がわかりやすいので参考にしてみてください!

憧れのTypeScriptフルスタック環境がコマンド1発で作れる超軽量フレームワーク「frourio」

コマンド1発でフロントSPA + RESTサーバー + O/Rマッパーの環境構築ができるとのことなので、早速試してみましょう!

 

環境構築について

では実際に触っていきます。TypeScriptはNode.jsの環境で動作するプログラム言語なので、あらかじめNode.jsのインストールが必要です。

また、RDBMSも必要に応じてインストールしておきましょう。今回はこちらの内容で環境構築をしてみます(npmはNode.jsと一緒にインストールされます)。

 

Node.js: v14.15.0
npm: v6.14.8
RDBMS: MySQL v8.0.22

まずは以下のコマンドを実行してみます。

$ npx create-frourio-app

しばらくするとブラウザでhttp://localhost:3000が開き、以下の画面が表示されました。

中央上段にfrourioと書かれたスクリーンショット
この画面でfrourioの構成を選択します。今回フロントエンドフレームワークはNuxt.jsにしました。

そのほか下の画像のように、SSRorSPA、HTTPクライアントなどの項目をぽちぽち選びます。開発者の好みのものがカスタムできるのは素直にいいなと思いました。

選択項目がわかるスクリーンショット
O/Rマッパー以降では、データベースの設定をしていきます。ユーザー名やパスワード、データベース名も画面から入力します。

中央下段にCreateボタンがあるスクリーンショット

最後にCreateボタンを押すと、インストールが始まります。完了すると自動で以下のページが開きました。この時点でデータベースも含めて環境の作成が完了しています!

ただし、Createする際に対象のDBサーバが起動しており、かつログインユーザーを作成しておく必要があります。Create時に、入力した情報でDBにログインできない場合はエラーが発生します。

 
frourio-todo-appと書かれたスクリーンショット
これでフロントSPA + RESTサーバー + O/Rマッパーの環境構築は完了です。本当にコマンド1発でした、早いですね!

デフォルトでTODOリストのサンプルが実装されているので、フロント→バックエンドまでの動作を一通り確認することができます。

 

処理の流れを確認してみよう!

フロント→バックエンドまでの処理の流れを把握するべく、TOP画面中央でフォームに値を入力し、ADDボタンをクリックした時の挙動を追ってみましょう。

おおまかな処理順序は以下の通りです。

処理順序
①pages/index.vueのcreateTask
②server/api/tasks/controller.tsのpost
③server/service/task.tsのcreateTask

ADDボタンをクリックすると、pages/index.vueのcreateTask()メソッドが呼び出されます。

createTask()の中ではthis.$api.tasks.post()でエンドポイントを指定してAPIの呼び出しを行なっています。

メソッドが呼び出されたスクショ

ここには松田さんが開発したaspida(アスピーダ)というライブラリが利用されており、型安全なAPIの呼び出しを可能にしてくれます。

aspidaは、エンドポイントをディレクトリの階層から自動生成してくれるライブラリです。詳細が気になる人はこちらをご覧ください。

「aspida」について知りたい!

 

frourioについての記事なので、aspidaの説明は割愛しますが、

this.$api.tasks.post()

と記載することで、server/api/tasks/controller.tsのpostが呼び出されます。

コードのスクショ

続いてpostの中ですが、createTask()でserver/service/task.tsのcreateTaskの処理が実行されます。

初期設定の際にO/RマッパーとしてPrisma(https://www.prisma.io/)を選択したため、ここではprisma.task.create()でデータベースに値を生成しています。

コードのスクショ02

ちなみに、DBのスキーマはserver/prisma内でバージョン管理しており、デフォルトでTaskテーブルの定義があります。

schema.prismaに記載がありますので、テーブルを追加する場合はこちらを更新することになりますね。

コードのスクショ03

createTask()でタスクを作成した後は、fetchTask()メソッドでgetのAPIを呼び出し、TODOリストを取得する流れになります。以上がTODOをADDした時の挙動です。

API側の実装は全てTypeScriptで提供されており、エンドポイント指定やO/Rマッパーの仕組みがわかれば効率良く開発ができそうですね。

一連の流れがわかったところで、簡単な機能追加をしてみましょう。

 

背景画像をPOSTするAPIを実装してみる!

frourio-todo-appと書かれたスクリーンショット
こちらにあるTOPページの背景が味気ないので、背景画像を変更できるボタンを実装してみましょう!

server/apiの下にbackgroundディレクトリを作成すると自動的にtsファイルが生成されます。

tsファイルのスクショ

次に画像投稿用のPOST APIを追加するべく、以下のように実装してみます。

自動生成されたserver/api/background/index.tsにPOST APIのパラメータ型を定義します。

元々書かれているgetをpostに書き換えます。

export type Methods = {
  post: {
    reqFormat: FormData
    reqBody: { img: Blob }
    resBody: {
      imageUrl: string
    }
  }
}

次にserver/api/background/controller.tsでPOST時の動作を記述します。

先ほど、server/api/background/index.tsの型定義を書き換えた影響でエディタ上にエラーが出ているはずです。ここもgetをpostに書き換えていきます。

import { defineController } from './$relay'
import { changeImage } from '$/service/background'
 
export default defineController(() => ({
  post: async ({ body }) => ({
    status: 201,
    body: await changeImage(body.img)
  })
}))

この時点ではchangeImage関数が未定義なのでエラーが残ります。server/api/service/background.tsを作成して画像を保存し、URLを返してくれるchangeImage関数を定義します。

import fs from 'fs'
import path from 'path'
import { Multipart } from 'fastify-multipart'
import { API_ORIGIN, BASE_PATH } from './envValues'
 
export const changeImage = async (imgFile: Multipart) => {
  const imgName = `${Date.now()}${path.extname(imgFile.filename)}`
 
  await fs.promises.writeFile(
    path.resolve('public', imgName),
    await imgFile.toBuffer()
  )
 
  return { imageUrl: `${API_ORIGIN}${BASE_PATH}/${imgName}` }
}

server/api/publicディレクトリに保存したファイルは静的にホスティングされます。ここまで書くと、先ほどのserver/api/background/controller.tsのエラーがなくなるはずです。

これで画像を投稿するAPIが完成しました。残りはフロントエンドで投稿ボタンを実装するだけです。

pages/index.vueに以下のコードを追加します。

<template>
+<div class="container" :style="pageStyle">
    <user-banner />
    <div>
      <logo />
      <h1 class="title">frourio-todo-app</h1>
+     <input type="file" accept="image/*" @change="editImage" />
      ...
    </div>
  </div>
</template>
 
<script lang="ts">
import Vue from 'vue'
import { Task } from '$prisma/client'
 
export default Vue.extend({
  data() {
    return {
+     pageStyle: {
+       background: ''
+     },
      tasks: [] as Task[],
      newLabel: ''
    }
  },
  ...
  methods: {
    ...
+   async editImage(e: { target: HTMLInputElement }) {
+     if (!e.target.files?.length) return
 
+     const res = await this.$api.background.$post({
+       body: { img: e.target.files[0] }
+     })
+     this.pageStyle = { background: `center/cover url(${res.imageUrl})` }
+   }
  }
})
</script>

これにて完了。ブラウザ中央に出現したボタンから画像ファイルを選択すると、背景が変更されました!

 
frourioを使って完成した画面

冬らしい背景に設定完了。編集したのは4ファイルだけで、ここまでかかった時間は1時間程度でした。

TypeScriptが初めてでも、フロントエンドとデータベースの知識があればfrourioを短時間で使えるようになると思います!

ちなみに全て英語で書かれていますが、frourio公式のドキュメントはこちらから読めます。

日本語の解説記事はfrourioのコミッターがQiitaに不定期で連載しているとのことなので、ぜひこちらもチェックしてみてはいかがでしょうか?

Qiitaの記事をチェックしてみる!

 

開発者の松田さんに話を聞きました

せっかくなので、frourioを開発した松田さんにお話を聞いていきたいと思います!

松田さんのお写真 松田さん(@m_mitsuhide大企業の社内ツールをNuxt.js+TypeScriptで作りながら個人でfrourioとaspidaを開発。7年前にWebGLライブラリjThreeを公開して以来オープンソースを作り続けている。

ーー「frourio」を開発しようと思ったきっかけは何ですか?

松田さん:フロントエンドからのAPIリクエストを型安全にするaspidaを公開したあとに、バックエンドも型安全にしたくなったのがきっかけでした。両方を統合してTypeScriptで書けるようになれば、早く高品質なWebサービスを開発できるようになると考えたのです。

ーーなるほど。frourioを使ってみて、TypeScriptが初めてでも書きやすいと感じました。開発者としてはどこが魅力だと考えていますか?

松田さん:そうですね、1つ目はTypeScriptの複雑な型を使わずに書けることです。TypeScriptは従来のJavaScriptに型を追加した言語ですが、複雑な部分をfrourioで極力隠蔽しているのでほとんどJavaScriptに近い見た目で書くことができます。

2つ目は、画面上で構成を決めるだけで環境構築ができることです。新しい言語・フレームワークを習得する際に最も面倒で難しいのは環境構築です。経験年数に関係なくつまずきますし、エラーコードは役に立たずググっても答えが出ないことがありませんか?

ーーそういう経験をしたエンジニアは多いと思います!

松田さん:3つ目は、テストコードを書けないような状況でも、高い品質のサービスを開発しやすいことです。今までのフルスタックフレームワークは言語を二つ使う必要があったり、TypeScriptを導入してもフロントエンドとバックエンドが統合されていなかったりするため「APIが正しく繋がること」を型でチェックすることが困難でした。

そのため本体のコードと同じくらいのコストをかけてテストコードを書くか、ブラウザ上で手動確認する必要があります。frourioならAPIのリクエスト含め、フロントエンド・バックエンド・O/Rマッパーまで統合してTypeScriptでの型チェックが可能です。

どうしてもテストを書くリソースを確保できない状況でも、従来より早く安全にサービス開発ができるようになりますね。

ーー確かに素早くテストも書ける優秀なエンジニアを確保するのはどの会社でも苦労しているし、案件やチーム編成によってテストを書けないことはよくあると思います。frourioを導入するとテストを書かなくても良くなるのですか?

松田さん:「書かなくてもいい」とは言いづらいですが、「書けない現状がある」ことを認識しています。

frourioを使ってもTypeScriptでカバーできない部分があるので、テストを書くことが理想です。今回の記事では触れていませんが、frourioには関数に依存性を注入できる画期的なテスト機能があります。

一方で納期や予算、文化によって必ずしも理想通りにいかない現場をたくさん見てきました。そんな課題に少しでも貢献したい思いで、TypeScriptの恩恵を最大限享受できるフレームワークとしてfrourioを開発しました。世界中のエンジニアに、この安心感を体験して欲しいです。

ーー理想を追求しつつ、現実的な課題も解決できるように設計されたフレームワークということですね。frourioがより多くのエンジニアに広まっていき、素晴らしいWebサービスが産まれることを願っています!

 

「frourio」を触ってみたリアルな感想

コマンド1つで環境構築からAPI実装まで、TypeScriptを使って簡単に実現できました! 環境構築に時間をかけずにTypeScriptを触ってWebアプリケーションが作成できるので、これからTypeScriptを始めたい方にとってはうってつけのフレームワークではないかと思います。

またaspidaを使って、ディレクトリ/ファイルによってオートルーティングができる点や、型の安全も保証されている点において、「手軽さ」「保守性」の両面を兼ね備えているのが大きな強みだと感じました。

今回はローカル環境での動作確認のみでしたが、今後Dockerで本番環境デプロイなども試してみたいと思います。

 

難しい知識が必要ないフレームワーク「frourio」

frourioのサイトのファーストビュー

「frourio」の特徴
  • TypeScriptだけで扱えるフルスタックフレームワーク。
  • コマンド一発で環境構築からAPI実装までできる。
  • TypeScriptが初めてでも読みやすくて書きやすい。

いくら手軽でも、仕事として使えるレベルまで習得するにはある程度の時間が必要です。この機に誰より早くfrourioに入門して「TypeScriptフルスタックエンジニア」を目指してみませんか?

「frourio」を触ってみる!

この記事のシェア数

1983年生まれ。SIerとしてのキャリアをスタートし、JavaやC#を中心に多岐にわたる開発プロジェクトにエンジニアとして参加。その経験を活かし、LIGを創業。バックエンドおよびフロントエンドエンジニアとしての深い知識と経験をもとに、多様なプロジェクトに従事。2023年7月には社長室室長に就任にし、社内の体制やルールの最適化、AI技術の推進など、経営戦略の一翼を担っています。

このメンバーの記事をもっと読む