---
layout: "@/layouts/MarkdownLayout.astro"
---
import Toc from "../../components/Toc.astro";
import ExampleWrapper from "@/components/ExampleWrapper.astro";
import TailwindExample from "@/components/example/TailwindExample";
import ReactExample from "@/components/example/ReactExample";
import DayjsExample from "@/components/example/DayjsExample";
import CombinedExample from "@/components/example/CombinedExample";
export const title = "有名なライブラリ";
# {title}
## TOC
npmには世界中の開発者が作ったライブラリが公開されており、その数は100万を超えています。
ここでは特によく使われる代表的なライブラリを紹介します。
## UIを作る
### React
**React**はMeta(旧Facebook)が開発したUIライブラリです。
ウェブページの画面を「コンポーネント」という部品に分けて管理できるようにしたもので、
現在最もよく使われているフロントエンドライブラリのひとつです。
ボタンやフォームなどのUI部品を再利用しやすい形で作れるため、大規模なウェブアプリケーションの開発に特に力を発揮します。
また、`useState`のような仕組みを使うことで、クリックや入力といった操作に応じて画面を自動で更新できます。
Reactのコードをよく見ると、JavaScriptの中にHTMLのような記述が混ざっていることに気づくと思います。
これは**JSX**と呼ばれる、Reactのための独自の書き方です。
```tsx
// これはJavaScriptではなく、JSXという書き方
return (
<div>
<p>クリック数: {count}</p>
</div>
);
```
JSXはブラウザがそのまま解釈することはできません。
Node.jsのツール(ViteやTypeScriptなど)が、ブラウザが読めるJavaScriptに変換して初めて動きます。
つまり、Reactは前のページで紹介した「別の書き方をJavaScriptに変換する」用途のひとつでもあります。
```tsx
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>クリック数: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(0)}>リセット</button>
</div>
);
}
```
<ExampleWrapper><ReactExample client:load /></ExampleWrapper>
### Tailwind CSS
**Tailwind CSS**はCSSを効率よく書くためのライブラリです。
通常のCSSはクラス名を自分で決めてスタイルを記述しますが、Tailwind CSSでは`text-lg`や`bg-blue-500`のような
あらかじめ用意されたクラスを組み合わせることで、CSSファイルをほとんど書かずにスタイルを整えられます。
Tailwind CSSを土台にして、ボタンやカードなどよく使うUIパーツをあらかじめ用意したライブラリもあります。
このドキュメントサイトでは **daisyUI** というライブラリを使っており、`btn`や`card`といったクラスを使うだけで整ったUIが作れます。
```html
<button class="btn btn-primary">プライマリ</button>
<button class="btn btn-secondary">セカンダリ</button>
<div class="card bg-base-200 shadow-sm">
<div class="card-body">
<h3 class="card-title">カードコンポーネント</h3>
<p>Tailwind CSSのクラスを組み合わせるだけで作れます。</p>
</div>
</div>
```
<ExampleWrapper><TailwindExample /></ExampleWrapper>
## サーバーを作る
### Express
**Express**はNode.jsでWebサーバーを作るためのフレームワークです。
Node.js単体でもWebサーバーは作れますが、Expressを使うことでURLごとの処理を簡潔に書けるようになります。
Node.jsでサーバーを作る場合、現在でも最もよく使われている定番のライブラリです。
```js
import express from "express";
const app = express();
// /hello にアクセスされたときの処理
app.get("/hello", (req, res) => {
res.send("Hello, World!");
});
app.listen(3000);
```
## 便利ツール
### Day.js
**Day.js**は日付や時刻を扱うためのライブラリです。
JavaScriptには標準で日付を扱う機能がありますが、「3日後の日付を求める」「日付を〇年〇月〇日の形式で表示する」
といった処理を書くのが複雑です。Day.jsを使うとこういった処理をシンプルに書けます。
```js
import dayjs from "dayjs";
import "dayjs/locale/ja";
dayjs.locale("ja");
const now = dayjs();
now.format("YYYY年MM月DD日(ddd)HH時mm分"); // 今日の日時
now.add(7, "day").format("YYYY年MM月DD日"); // 7日後
now.subtract(1, "month").startOf("month"); // 先月の初日
```
<ExampleWrapper><DayjsExample /></ExampleWrapper>
---
これらはほんの一例です。npmには他にも無数のライブラリがあり、
「やりたいことがあればまず探してみる」というのがNode.js開発の基本的なスタイルです。
いまモダンと言われるWeb開発の多くは、こういったライブラリを組み合わせて作られています。
## 組み合わせる
これらのライブラリは、それぞれ単独で使うだけでなく組み合わせることで力を発揮します。
以下は **React**・**Tailwind CSS**・**Day.js** を組み合わせた例です。
今日の日付(Day.js)を表示しながら、チェックボックスで状態が変わる(React)、見た目の整ったタスクリスト(Tailwind CSS)を作っています。
```tsx
import dayjs from "dayjs";
import "dayjs/locale/ja";
import { useState } from "react";
dayjs.locale("ja");
const initialTasks = [
{ id: 1, text: "朝のミーティング", done: false },
{ id: 2, text: "仕様書を読む", done: false },
{ id: 3, text: "コードレビュー", done: false },
];
export default function TaskList() {
const [tasks, setTasks] = useState(initialTasks);
const toggle = (id) => {
setTasks(tasks.map((t) => (t.id === id ? { ...t, done: !t.done } : t)));
};
const done = tasks.filter((t) => t.done).length;
return (
<div className="card border border-base-300 max-w-sm">
<div className="card-body gap-4">
<div>
<p className="text-xs text-base-content/50">
{dayjs().format("YYYY年MM月DD日(ddd)")}
</p>
<h3 className="card-title">今日のタスク</h3>
<p className="text-sm text-base-content/60">{done} / {tasks.length} 完了</p>
</div>
<ul className="space-y-2">
{tasks.map((task) => (
<li key={task.id}>
<label className="flex items-center gap-3 cursor-pointer">
<input
type="checkbox"
className="checkbox checkbox-primary"
checked={task.done}
onChange={() => toggle(task.id)}
/>
<span className={task.done ? "line-through text-base-content/40" : ""}>
{task.text}
</span>
</label>
</li>
))}
</ul>
</div>
</div>
);
}
```
<ExampleWrapper><CombinedExample client:load /></ExampleWrapper>