Nuxt プロジェクトのベストディレクトリ設計

Nuxt プロジェクトを開発していて、「どこにファイルを置けばいいの?」と迷った経験はありませんか。適切なディレクトリ構成は、開発効率と保守性を大幅に向上させる重要な要素です。
今回は、Nuxt プロジェクトにおける最適なディレクトリ設計について、初心者の方にもわかりやすく解説していきます。規約に従った構成から、プロジェクト規模に応じた実践的な設計例まで、すぐに使える知識をお届けします。
背景
Nuxt の規約ベースアーキテクチャ
Nuxt は「Convention over Configuration(設定より規約)」の思想に基づいて設計されています。これは、開発者が複雑な設定を行わなくても、決められたディレクトリ構成に従うだけで、自動的に最適化された機能を利用できることを意味します。
例えば、pages
ディレクトリに Vue ファイルを配置するだけで、自動的にルーティングが生成されます。この規約ベースのアプローチにより、チーム開発での統一性が保たれ、新しいメンバーも素早くプロジェクトに参加できるのです。
以下の図は、Nuxt の規約ベースアーキテクチャの基本的な仕組みを示しています。
mermaidflowchart TD
developer[開発者] -->|ファイル配置| directories[規約ディレクトリ]
directories --> pages[pages/]
directories --> components[components/]
directories --> layouts[layouts/]
directories --> middleware[middleware/]
pages -->|自動生成| routing[ルーティング]
components -->|自動インポート| autoImport[コンポーネント自動インポート]
layouts -->|自動適用| layoutSystem[レイアウトシステム]
middleware -->|自動実行| middlewareExec[ミドルウェア実行]
routing --> app[Nuxtアプリケーション]
autoImport --> app
layoutSystem --> app
middlewareExec --> app
図で理解できる要点:
- 開発者は決められたディレクトリにファイルを配置するだけ
- Nuxt が自動的に機能を生成・適用
- 設定ファイルの記述量を大幅に削減
ディレクトリ構成がもたらす恩恵
適切なディレクトリ構成を採用することで、以下のような恩恵を得られます。
恩恵 | 説明 | 具体例 |
---|---|---|
開発効率の向上 | ファイルの所在が明確になり、開発スピードが向上 | コンポーネントを探す時間が短縮 |
保守性の向上 | 機能ごとに整理され、バグ修正や機能追加が容易 | 特定の画面の修正箇所がすぐに特定可能 |
チーム開発の円滑化 | 統一されたルールにより、誰が見ても理解しやすい | 新メンバーのオンボーディング時間を短縮 |
スケーラビリティ | プロジェクトの成長に合わせて構成を拡張可能 | 機能追加時の影響範囲を限定 |
特に、Nuxt の自動インポート機能により、components
、composables
、utils
ディレクトリ内のファイルは、明示的にインポート文を書かなくても使用できます。これにより、コードの記述量が削減され、開発効率が大幅に向上するのです。
課題
一般的なディレクトリ設計の問題点
多くのプロジェクトで見られる問題点を整理してみましょう。
ファイルの配置場所が不明確
初心者の方がよく遭遇する問題として、「このファイルはどこに置けばいいの?」という迷いがあります。特に以下のようなケースで混乱が生じやすいです。
typescript// ❌ 問題のある配置例
src/
├── components/
│ ├── Header.vue // グローバルコンポーネント?
│ ├── ProductCard.vue // 商品専用?共通?
│ └── AdminButton.vue // 管理画面専用?
├── utils/
│ ├── api.js // API関連のユーティリティ
│ ├── format.js // フォーマット関数
│ └── validation.js // バリデーション
└── pages/
├── product.vue // 商品一覧?詳細?
└── admin.vue // 管理画面のトップ?
この例では、各ファイルの用途や適用範囲が名前から判断しにくく、開発者が迷いやすい構成になっています。
機能ごとの境界が曖昧
もう一つの大きな問題は、機能の境界が不明確なことです。以下の図は、よくある問題のある構成を示しています。
mermaidflowchart LR
subgraph "問題のある構成"
comp[components/]
util[utils/]
page[pages/]
comp -.->|依存関係が複雑| util
page -.->|どこにあるか不明| comp
util -.->|機能境界が曖昧| page
end
subgraph "結果"
confusion[混乱]
maintenance[保守困難]
slowDev[開発速度低下]
end
comp --> confusion
util --> maintenance
page --> slowDev
図で理解できる要点:
- 機能間の依存関係が複雑化
- ファイルの所在が特定しにくい
- 結果として開発効率が低下
スケーラビリティの課題
プロジェクトが成長するにつれて、初期の簡単な構成では対応しきれなくなります。
小規模から中規模への移行時の問題
プロジェクトの成長段階で発生する典型的な問題を見てみましょう。
成長段階 | ファイル数 | 主な問題 | 影響 |
---|---|---|---|
小規模 | 10-30 ファイル | 構成が単純すぎる | 将来の拡張性を考慮していない |
中規模 | 50-100 ファイル | ディレクトリが肥大化 | ファイル検索に時間がかかる |
大規模 | 100 ファイル以上 | 責務分離が不十分 | 機能追加時の影響範囲が広がる |
技術的負債の蓄積
適切な設計を行わないと、以下のような技術的負債が蓄積されます。
typescript// ❌ 技術的負債の例
// components/index.vue - 巨大なコンポーネント
export default {
name: 'ProductPage',
data() {
return {
products: [],
categories: [],
filters: {},
sorting: {},
pagination: {},
// ... 100行以上のデータプロパティ
};
},
methods: {
// ... 50個以上のメソッド
},
};
このような巨大なファイルは、保守性を著しく低下させ、バグの温床となります。
解決策
Nuxt 公式推奨ディレクトリ構成
Nuxt では、効率的な開発を行うための標準的なディレクトリ構成が定義されています。以下が基本的な構成です。
csharpnuxt-project/
├── .nuxt/ # ビルド時に自動生成(触らない)
├── assets/ # コンパイルが必要なアセット
├── components/ # Vueコンポーネント(自動インポート)
├── composables/ # コンポーザブル関数(自動インポート)
├── content/ # Nuxt Content用のファイル
├── layouts/ # レイアウトコンポーネント
├── middleware/ # ルートミドルウェア
├── pages/ # ページコンポーネント(自動ルーティング)
├── plugins/ # プラグイン
├── public/ # 静的ファイル(そのまま配信)
├── server/ # サーバーサイドコード
├── utils/ # ユーティリティ関数(自動インポート)
├── app.vue # メインアプリコンポーネント
├── error.vue # エラーページ
├── nuxt.config.ts # Nuxt設定ファイル
└── package.json # 依存関係とスクリプト
各ディレクトリの役割と配置ルール
それぞれのディレクトリには明確な役割があります。適切に使い分けることで、効率的な開発が可能になります。
pages ディレクトリ - 自動ルーティングの核心
pages
ディレクトリは、Nuxt の最も重要な機能の一つである自動ルーティングを担当します。
typescript// pages/index.vue - トップページ(/ にマッピング)
<template>
<div>
<h1>ホームページ</h1>
<p>Nuxtアプリケーションのトップページです</p>
</div>
</template>
<script setup lang="ts">
// ページ固有のロジック
const title = 'ホームページ'
useSeoMeta({
title,
description: 'Nuxtアプリケーションのトップページです'
})
</script>
typescript// pages/products/[id].vue - 動的ルート(/products/123 にマッピング)
<template>
<div>
<h1>{{ product.name }}</h1>
<p>{{ product.description }}</p>
</div>
</template>
<script setup lang="ts">
// ルートパラメータの取得
const route = useRoute()
const productId = route.params.id
// 商品データの取得
const { data: product } = await $fetch(`/api/products/${productId}`)
</script>
components ディレクトリ - 再利用可能な UI 部品
コンポーネントは機能や用途に応じて整理します。
typescript// components/UI/Button.vue - 基本的なUIコンポーネント
<template>
<button
:class="buttonClasses"
:disabled="disabled"
@click="$emit('click')"
>
<slot />
</button>
</template>
<script setup lang="ts">
interface Props {
variant?: 'primary' | 'secondary' | 'danger'
size?: 'small' | 'medium' | 'large'
disabled?: boolean
}
const props = withDefaults(defineProps<Props>(), {
variant: 'primary',
size: 'medium',
disabled: false
})
// スタイルクラスの算出
const buttonClasses = computed(() => [
'btn',
`btn--${props.variant}`,
`btn--${props.size}`,
{ 'btn--disabled': props.disabled }
])
</script>
以下の図は、適切なコンポーネント設計の階層構造を示しています。
mermaidflowchart TD
subgraph "コンポーネント階層"
ui[UI/ - 基本部品]
layout[Layout/ - レイアウト部品]
feature[Feature/ - 機能別部品]
ui --> button[Button.vue]
ui --> input[Input.vue]
ui --> modal[Modal.vue]
layout --> header[Header.vue]
layout --> footer[Footer.vue]
layout --> sidebar[Sidebar.vue]
feature --> productCard[ProductCard.vue]
feature --> userProfile[UserProfile.vue]
feature --> shoppingCart[ShoppingCart.vue]
end
subgraph "使用関係"
layout -.->|使用| ui
feature -.->|使用| ui
pages[pages/] -.->|使用| layout
pages -.->|使用| feature
end
図で理解できる要点:
- UI 部品が最下層で最も汎用的
- 機能別部品が UI 部品を組み合わせて構築
- ページが各レイヤーのコンポーネントを使用
composables ディレクトリ - ロジックの再利用
Vue 3 の Composition API を活用したロジックの共有を行います。
typescript// composables/useApi.ts - API呼び出し用のコンポーザブル
export const useApi = () => {
const loading = ref(false);
const error = ref<string | null>(null);
const fetchData = async <T>(
url: string
): Promise<T | null> => {
loading.value = true;
error.value = null;
try {
const data = await $fetch<T>(url);
return data;
} catch (err) {
error.value =
err instanceof Error
? err.message
: 'エラーが発生しました';
return null;
} finally {
loading.value = false;
}
};
return {
loading: readonly(loading),
error: readonly(error),
fetchData,
};
};
typescript// composables/useLocalStorage.ts - ローカルストレージ管理
export const useLocalStorage = <T>(
key: string,
defaultValue: T
) => {
const storedValue = process.client
? localStorage.getItem(key)
: null;
const state = ref<T>(
storedValue ? JSON.parse(storedValue) : defaultValue
);
// 値の変更を監視してローカルストレージに保存
watch(
state,
(newValue) => {
if (process.client) {
localStorage.setItem(key, JSON.stringify(newValue));
}
},
{ deep: true }
);
return state;
};
utils ディレクトリ - 純粋関数とヘルパー
ビジネスロジックに依存しない、純粋な関数を配置します。
typescript// utils/format.ts - フォーマット関数
/**
* 数値を通貨形式でフォーマット
*/
export const formatCurrency = (
amount: number,
currency = 'JPY'
): string => {
return new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency,
}).format(amount);
};
/**
* 日付を指定形式でフォーマット
*/
export const formatDate = (
date: Date | string,
format = 'YYYY-MM-DD'
): string => {
const dateObj =
typeof date === 'string' ? new Date(date) : date;
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(
2,
'0'
);
const day = String(dateObj.getDate()).padStart(2, '0');
return format
.replace('YYYY', String(year))
.replace('MM', month)
.replace('DD', day);
};
具体例
小規模プロジェクトの構成例
個人開発や小さなチームでのプロジェクトに適した構成を見てみましょう。
csharpsimple-blog/
├── components/
│ ├── Header.vue # グローバルヘッダー
│ ├── Footer.vue # グローバルフッター
│ ├── ArticleCard.vue # 記事カード
│ └── CommentForm.vue # コメントフォーム
├── composables/
│ ├── useAuth.ts # 認証関連
│ └── useApi.ts # API呼び出し
├── layouts/
│ └── default.vue # デフォルトレイアウト
├── pages/
│ ├── index.vue # トップページ
│ ├── articles/
│ │ ├── index.vue # 記事一覧
│ │ └── [slug].vue # 記事詳細
│ └── auth/
│ ├── login.vue # ログイン
│ └── register.vue # 新規登録
├── utils/
│ ├── format.ts # フォーマット関数
│ └── validation.ts # バリデーション
└── nuxt.config.ts
小規模プロジェクトでは、シンプルで分かりやすい構成を心がけます。
typescript// components/ArticleCard.vue - 記事カードコンポーネント
<template>
<article class="article-card">
<h2 class="article-card__title">
<NuxtLink :to="`/articles/${article.slug}`">
{{ article.title }}
</NuxtLink>
</h2>
<p class="article-card__excerpt">
{{ article.excerpt }}
</p>
<div class="article-card__meta">
<time :datetime="article.publishedAt">
{{ formatDate(article.publishedAt) }}
</time>
<span class="article-card__author">
{{ article.author.name }}
</span>
</div>
</article>
</template>
<script setup lang="ts">
interface Article {
slug: string
title: string
excerpt: string
publishedAt: string
author: {
name: string
}
}
interface Props {
article: Article
}
defineProps<Props>()
</script>
中規模プロジェクトの構成例
複数の機能を持つ Web アプリケーションの構成例です。
csharpecommerce-app/
├── components/
│ ├── UI/ # 基本的なUIコンポーネント
│ │ ├── Button.vue
│ │ ├── Input.vue
│ │ ├── Modal.vue
│ │ └── Loading.vue
│ ├── Layout/ # レイアウト関連
│ │ ├── Header.vue
│ │ ├── Navigation.vue
│ │ ├── Footer.vue
│ │ └── Sidebar.vue
│ ├── Product/ # 商品関連
│ │ ├── ProductCard.vue
│ │ ├── ProductList.vue
│ │ ├── ProductFilter.vue
│ │ └── ProductDetails.vue
│ ├── Cart/ # カート関連
│ │ ├── CartItem.vue
│ │ ├── CartSummary.vue
│ │ └── CartButton.vue
│ └── User/ # ユーザー関連
│ ├── UserProfile.vue
│ ├── LoginForm.vue
│ └── RegisterForm.vue
├── composables/
│ ├── useAuth.ts # 認証管理
│ ├── useCart.ts # カート管理
│ ├── useProducts.ts # 商品データ管理
│ ├── useLocalStorage.ts # ローカルストレージ
│ └── useApi.ts # API呼び出し
├── layouts/
│ ├── default.vue # 通常のレイアウト
│ ├── auth.vue # 認証ページ用
│ └── admin.vue # 管理画面用
├── middleware/
│ ├── auth.ts # 認証チェック
│ └── admin.ts # 管理者権限チェック
├── pages/
│ ├── index.vue # トップページ
│ ├── products/
│ │ ├── index.vue # 商品一覧
│ │ ├── [id].vue # 商品詳細
│ │ └── category/
│ │ └── [slug].vue # カテゴリ別商品一覧
│ ├── cart/
│ │ ├── index.vue # カート内容
│ │ └── checkout.vue # チェックアウト
│ ├── user/
│ │ ├── profile.vue # プロフィール
│ │ ├── orders.vue # 注文履歴
│ │ └── settings.vue # 設定
│ └── auth/
│ ├── login.vue # ログイン
│ └── register.vue # 新規登録
├── server/
│ └── api/ # サーバーサイドAPI
│ ├── products.get.ts
│ ├── cart.post.ts
│ └── auth/
│ ├── login.post.ts
│ └── register.post.ts
├── types/
│ ├── product.ts # 商品関連の型定義
│ ├── user.ts # ユーザー関連の型定義
│ └── api.ts # API関連の型定義
└── utils/
├── format.ts # フォーマット関数
├── validation.ts # バリデーション
└── constants.ts # 定数定義
中規模プロジェクトでは、機能ごとにディレクトリを分けて整理します。
以下の図は、中規模プロジェクトの機能間の関係性を示しています。
mermaidflowchart TD
subgraph "ページ層"
products[products/]
cart[cart/]
user[user/]
end
subgraph "コンポーネント層"
productComp[Product/]
cartComp[Cart/]
userComp[User/]
ui[UI/]
end
subgraph "ロジック層"
productLogic[useProducts]
cartLogic[useCart]
authLogic[useAuth]
apiLogic[useApi]
end
subgraph "サーバー層"
serverApi[server/api/]
end
products --> productComp
cart --> cartComp
user --> userComp
productComp --> ui
cartComp --> ui
userComp --> ui
productComp --> productLogic
cartComp --> cartLogic
userComp --> authLogic
productLogic --> apiLogic
cartLogic --> apiLogic
authLogic --> apiLogic
apiLogic --> serverApi
図で理解できる要点:
- 各層が明確に分離されている
- UI コンポーネントは全機能で共有
- API 層が統一的にサーバーとやり取り
実装サンプルコード
実際のコードを通じて、適切な構成の利点を確認してみましょう。
カート機能の実装例
typescript// composables/useCart.ts - カート管理のコンポーザブル
interface CartItem {
id: string;
name: string;
price: number;
quantity: number;
image: string;
}
export const useCart = () => {
// ローカルストレージでカート状態を永続化
const items = useLocalStorage<CartItem[]>(
'cart-items',
[]
);
// 合計金額の算出
const totalAmount = computed(() => {
return items.value.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
});
// アイテム数の算出
const totalItems = computed(() => {
return items.value.reduce(
(total, item) => total + item.quantity,
0
);
});
// カートにアイテムを追加
const addItem = (product: Omit<CartItem, 'quantity'>) => {
const existingItem = items.value.find(
(item) => item.id === product.id
);
if (existingItem) {
existingItem.quantity++;
} else {
items.value.push({ ...product, quantity: 1 });
}
};
// アイテムの数量を更新
const updateQuantity = (id: string, quantity: number) => {
const item = items.value.find((item) => item.id === id);
if (item) {
item.quantity = Math.max(0, quantity);
if (item.quantity === 0) {
removeItem(id);
}
}
};
// アイテムを削除
const removeItem = (id: string) => {
const index = items.value.findIndex(
(item) => item.id === id
);
if (index > -1) {
items.value.splice(index, 1);
}
};
// カートをクリア
const clearCart = () => {
items.value = [];
};
return {
items: readonly(items),
totalAmount,
totalItems,
addItem,
updateQuantity,
removeItem,
clearCart,
};
};
typescript// components/Cart/CartButton.vue - カートボタンコンポーネント
<template>
<button
class="cart-button"
@click="toggleCart"
>
<Icon name="shopping-cart" />
<span class="cart-button__count" v-if="totalItems > 0">
{{ totalItems }}
</span>
</button>
</template>
<script setup lang="ts">
// カート状態を取得
const { totalItems } = useCart()
// カート表示の切り替え
const isCartOpen = ref(false)
const toggleCart = () => {
isCartOpen.value = !isCartOpen.value
}
</script>
typescript// pages/products/[id].vue - 商品詳細ページ
<template>
<div class="product-detail">
<div class="product-detail__image">
<img :src="product.image" :alt="product.name" />
</div>
<div class="product-detail__info">
<h1 class="product-detail__title">{{ product.name }}</h1>
<p class="product-detail__price">
{{ formatCurrency(product.price) }}
</p>
<p class="product-detail__description">
{{ product.description }}
</p>
<UIButton
@click="handleAddToCart"
:disabled="loading"
>
{{ loading ? 'カートに追加中...' : 'カートに追加' }}
</UIButton>
</div>
</div>
</template>
<script setup lang="ts">
// ルートパラメータから商品IDを取得
const route = useRoute()
const productId = route.params.id as string
// 商品データの取得
const { data: product, pending } = await useFetch(`/api/products/${productId}`)
// カート機能の利用
const { addItem } = useCart()
// カートに追加する処理
const loading = ref(false)
const handleAddToCart = async () => {
if (!product.value) return
loading.value = true
try {
addItem({
id: product.value.id,
name: product.value.name,
price: product.value.price,
image: product.value.image
})
// 成功通知
await navigateTo('/cart')
} catch (error) {
console.error('カートへの追加に失敗しました:', error)
} finally {
loading.value = false
}
}
// SEO設定
if (product.value) {
useSeoMeta({
title: product.value.name,
description: product.value.description
})
}
</script>
このサンプルコードでは、以下の点で適切な設計を実現しています。
設計原則 | 実装方法 | 利点 |
---|---|---|
関心の分離 | カートロジックをコンポーザブルに分離 | テストしやすく、再利用可能 |
単一責任 | 各コンポーネントが明確な役割を持つ | 保守性が高い |
データの流れ | 状態管理が一元化されている | データの整合性を保てる |
型安全性 | TypeScript で型定義を徹底 | バグを早期発見できる |
まとめ
ベストプラクティスの要点
Nuxt プロジェクトにおけるディレクトリ設計のベストプラクティスをまとめます。
原則 | 具体的な実践方法 | 効果 |
---|---|---|
規約に従う | Nuxt の標準ディレクトリ構成を基本とする | 学習コストの削減、チーム開発の効率化 |
機能で分ける | 関連するファイルを同じディレクトリにまとめる | 変更時の影響範囲を限定 |
層で分離 | UI、ロジック、データアクセスを分離 | テストしやすく、保守性が向上 |
命名を統一 | 一貫したファイル・ディレクトリ命名規則 | 可読性とメンテナンス性が向上 |
段階的拡張 | プロジェクトの成長に合わせて構成を発展 | 技術的負債の蓄積を防止 |
初心者向けのチェックリスト
以下のチェックリストを参考に、プロジェクトの構成を見直してみてください。
-
pages
ディレクトリでルーティングを整理できているか -
components
が適切な粒度で分割されているか - 共通ロジックが
composables
に抽出されているか - ユーティリティ関数が
utils
に分類されているか - 型定義が
types
ディレクトリで管理されているか - ファイル名が機能を表現しているか
- ディレクトリの階層が深すぎないか(3 階層まで推奨)
継続的な改善のポイント
良いディレクトリ設計は一度作って終わりではありません。継続的な改善が重要です。
定期的な見直し
プロジェクトの成長に合わせて、定期的にディレクトリ構成を見直しましょう。
typescript// 改善例:巨大なコンポーネントの分割
// ❌ 改善前:1つの巨大なコンポーネント
// components/ProductPage.vue (300行)
// ✅ 改善後:機能ごとに分割
// components/Product/ProductDetails.vue
// components/Product/ProductImages.vue
// components/Product/ProductReviews.vue
// components/Product/ProductRecommendations.vue
チーム内でのルール共有
チーム開発では、ディレクトリ設計のルールを文書化し、共有することが重要です。
markdown# プロジェクト構成ルール
# ファイル命名規則
- コンポーネント: PascalCase (例: UserProfile.vue)
- コンポーザブル: camelCase (例: useAuth.ts)
- ユーティリティ: camelCase (例: formatDate.ts)
# ディレクトリ分割基準
- components: 20 ファイル以上で機能別サブディレクトリを作成
- pages: 機能ごとにサブディレクトリを作成
- composables: 機能別に分類(例: auth/, api/, ui/)
適切なディレクトリ設計は、開発効率の向上だけでなく、プロジェクトの長期的な成功にも大きく貢献します。今回紹介したパターンを参考に、皆さんのプロジェクトに最適な構成を見つけてください。
継続的な改善を心がけることで、より良いコードベースを構築していけるでしょう。
関連リンク
- article
Nuxt プロジェクトのベストディレクトリ設計
- article
Nuxt での画像最適化戦略:nuxt/image と外部 CDN 徹底比較.md
- article
Nuxt のトランジション&アニメーションでリッチな UX を実現
- article
Nuxt で使うカスタムディレクティブの作り方
- article
Nuxt と Tailwind CSS で美しい UI を量産しよう
- article
Nuxt の i18n で多言語サイトを簡単構築
- article
React 開発を加速する GitHub Copilot 活用レシピ 20 選
- article
Prisma の公式ドキュメントを使い倒すためのコツ
- article
GitHub Actions × Node.js:テストとデプロイを自動化する
- article
Pinia × TypeScript:型安全なストア設計入門
- article
Obsidian デイリーノート活用術:毎日の思考ログを資産に変える方法
- article
Git で特定のコミットを打ち消す!git revert の正しい使い方
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来