【マジで】カレーの作り方 🍛

今回の記事ですが、
中々いいネタが思い出せないので

**カレーの作り方**（を見つける[アプリ](https://random-curry.netlify.com)）
を作りました。

_釣りタイトルで申し訳ない、Qiita 様 BANしないでくれ..._

## 技術スタック

フレームワークやライブラリーは、カレーに使われている材料の幅広さと同じようで、
近年が話題になっている技術をいくつ採用したいと思います。

- サーバーレス
- SPA
- CSS フレームワーク

せっかくなので、普段使わないライブラリーやサービスの組み合わせでアプリを作りました。

| 技術 | サービス・ライブラリー |
| --- | --- |
| サーバーレス | [Netlify Functions](https://www.netlify.com/products/functions/) |
| SPA | [Svelte](https://svelte.dev/) |
| CSS フレームワーク | [Tailwind CSS](https://tailwindcss.com/) |

## 操作流れ

クックパッドからレシピを取得しようと思ったんですが、残念ながら API というものがなかったそうです。そこで、[axios](https://github.com/axios/axios) で HTML ページを取得し、[cheerio](https://github.com/cheeriojs/cheerio) で HTML をパースしてデータをきれいにして JSON で返しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285534/d2e64587-d047-45d4-569a-c2132221e66d.png)

（[mermaid.js](https://qiita.com/caesar_cat/items/e8a116a585863633d15a) でさくっと作りました、すごい！）

## 実装

### 環境構築

こういう組み合わせが結構珍しくて、一番苦労しました。
いろいろ試した結果、このやり方でうまく行きました。

#### Svelte プロジェクトを新規生成

```bash
$ npx degit sveltejs/template random-curry
$ cd random-curry
$ npm install
```

#### Netlify Functions を初期化
```bash
# まず、パッケージを導入
$ npm install --dev netlify-cli netlify-lambda
```

で、`package.json` に npm コマンドを追加：

```js
// package.json
// "build:lambda" と "netlify" と "deploy" を追加
  "scripts": {
    "build": "rollup -c",
    "build:lambda": "netlify-lambda build src/functions",
    "dev": "rollup -c -w",
    "netlify": "netlify dev",
    "deploy": "netlify deploy",
    "start": "sirv public"
  },
```

そしてプロジェクトルートに `netlify.toml` というファイルを新規追加：

```toml
# netlify.toml
[build]
  publish = "public/"
  command = "npm run build && npm run build:lambda"
  functions = "lambda"
```

#### Tailwind CSS を導入

Tailwind CSS を Svelte に導入するはかなり複雑で、[こちら](https://dev.to/jerriclynsjohn/svelte-tailwind-storybook-starter-template-2nih) の記事を参考しながら導入しました。簡単に説明すると、

1. Tailwind と PostCSS と関連するパッケージを導入
2. `rollup.config.js` に PostCSS 処理を追加
3. `postcss.config.js` を新規作成して処理を追加
4. `npx tailwind init` を実行し、`tailwind.config.js` を追加
5. `src/utils.css` を新規作成し、Tailwind CSS のルールを定義
5. `main.js` に `import 'utils.css'` 行を追加

詳しくは[ソースコード](https://github.com/adwinying/random-curry)をご参照ください。

### 開発環境を起動

```bash
$ npm run netlify
```

これで実行すれば、http://localhost:8888 からサイトが見れます。

### ファイル構成

ファイル構成としては、Svelte のプロジェクトとほぼ同じですが、ただ `src/functions` にサーバーレス関数を定義することを追加しました。

```
random-curry/
├── lambda/   # lambda 関数のコンパイル先
├── public/   # svelte のコンパイル先
├── src/      # アプリソースコード
│   ├── functions/   # lambda 関数
│   │   └── curry.js # カレーレシピを取得 API はここに書く
│   ├── components/  # svelte コンポーネント
│   ├── App.svelte   # svelte ルートコンポーネント
│   └── main.js
├── node_modules/
├── package.json
├── netlify.toml
├── postcss.config.js
├── rollup.config.js
└── tailwind.config.js
```

### ソースコード

ソースコードはそんなに面白くないので、省略します。興味があれば [Github リポ](https://github.com/adwinying/random-curry)をご参照ください。

## 感想（DX など）

### Netlify Functions

正直、今回作ったサーバーレス関数は、ブラウザでも実現できますが、、、

AWS Lambda の簡略版を感じ、簡単にサーバーレス関数を作ることできました。尚、メモリが 1GB、実行時間が 10 秒という制限があり、巨大のアプリを作るとしたら少し気になりますね。でもサーバー側での処理が少しであればわざわざサーバーを立ち上げしなく、lambda 関数でいいんじゃないかと思っていました。

### Svelte

前に少し触った経験があり、やっぱり他の SPA を比べると「**SPA の軽量版**」を感じました。簡単なアプリを実装するとき、jQuery か素 JS でやりたくない場合はこれでいいと思いますが、「コンパイルが必要」ことでそんなに気軽に導入できないですね。

### Tailwind CSS

Bootstrap とコンセプトが違い、ボタンやカードコンポーネントを用意するこたが一切なく、全部 CSS のクラス（ユーティリティクラス）でコンポーネントを建築することが必要でした。少し面倒な一方、デザインが自分で決めるので「**Bootstrap で作られたサイトに見える**」ことが避けられますね。また、コンポーネントのデザインする際は `class` 属性が 2-3 行を使ったことが気になりました。しかし、これで本来コンポーネント化すべき**重複している HTML 要素**が簡単に見つけ出すのはいいですね。

## まとめ

この組み合わせで開発するのはアリと思いますが、特に Svelte と Tailwind CSS の連携は少しでも簡略したいですね。

そして、いいレシピをいくつ見つけ出しましたので、今夜カレーにしようかな。。

最後に、Netlify にデプロイしたので、是非試してみてください！

https://random-curry.netlify.com