第3章: プロジェクト構成の理解

第3章: プロジェクト構成の理解

概要

本章では、前章で作成したVue.jsプロジェクトの構成を詳しく理解します。Viteで生成されたプロジェクトの各ファイルとディレクトリの役割、Vueの単一ファイルコンポーネント(SFC)の構造、そしてプロジェクト設定ファイルについて学びます。

1. プロジェクトディレクトリ構造

Viteで生成したVueプロジェクトの基本的なディレクトリ構造を再確認し、各部分の役割を詳しく見ていきましょう:

my-vue-app/
├── node_modules/     # インストールされた依存関係パッケージ
├── public/           # 静的アセット(処理なしでそのままコピーされる)
├── src/              # ソースコード
│   ├── assets/       # コンパイル/処理されるアセット
│   ├── components/   # 再利用可能なVueコンポーネント
│   ├── App.vue       # アプリケーションのルートコンポーネント
│   └── main.js       # アプリケーションのエントリーポイント
├── .gitignore        # Gitで無視するファイルの設定
├── index.html        # HTMLエントリーポイント
├── package.json      # プロジェクトの依存関係と設定
├── package-lock.json # 依存関係のバージョン固定用
├── vite.config.js    # Viteの設定ファイル
└── README.md         # プロジェクトの説明

2. 主要ディレクトリとファイルの役割

node_modules/

このディレクトリには、npm installコマンドでインストールした全ての依存関係が格納されています。このディレクトリは.gitignoreに登録されており、通常はGitリポジトリにコミットされません。

public/

ビルド時に処理されず、そのままコピーされる静的ファイルを置くディレクトリです。例えば、ファビコン(favicon.ico)、robots.txt、静的画像などを配置します。このディレクトリに配置したファイルは、コードからは「/」をルートとして参照できます。

<!-- 例:public/logo.png にあるファイルを参照 -->
<img src="/logo.png" alt="Logo">

src/

アプリケーションのソースコードを配置するメインディレクトリです。開発のほとんどはここで行います。

src/assets/

ビルド時に処理される画像、スタイルシート、フォントなどのアセットファイルを格納します。例えば、Sassファイル、モジュールCSSファイル、SVGなどです。このディレクトリ内のファイルは、importを使用して参照されます。

// 例:CSSをインポート
import './assets/main.css'

// 例:画像をインポート
import logo from './assets/logo.png'
src/components/

再利用可能なVueコンポーネント(.vueファイル)を格納するディレクトリです。ボタン、フォーム、カードなどのUIコンポーネントを作成し、他のコンポーネントやページから再利用できます。

src/App.vue

アプリケーションのルートコンポーネントです。すべてのページとコンポーネントは、最終的にこのコンポーネント内でレンダリングされます。

src/main.js

アプリケーションのエントリーポイントです。Vueインスタンスを作成し、グローバルなプラグインやコンポーネントを登録し、アプリケーションをDOMにマウントします。

index.html

プロジェクトのルートにあるHTMLファイルです。Viteは、このファイルをビルドプロセスのエントリーポイントとして使用します。このファイルには、Vueアプリケーションがマウントされるdiv要素と、main.jsへのスクリプト参照が含まれています。

package.json

プロジェクトの依存関係、スクリプト、およびメタデータを管理するファイルです。このファイルには、アプリケーションの構築、テスト、起動に必要なスクリプトとパッケージが記述されています。

{
  "name": "my-vue-app",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.3.4"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^4.2.3",
    "vite": "^4.4.5"
  }
}

主なスクリプトの説明:

vite.config.js

Viteの設定ファイルです。プラグインの追加、ビルドオプションのカスタマイズ、エイリアスの設定などを行うことができます。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
})

3. 単一ファイルコンポーネント(SFC)の構造

Vueの単一ファイルコンポーネント(.vueファイル)は、HTML、JavaScript、CSSを1つのファイルにカプセル化したものです。これにより、コンポーネントベースの開発が容易になり、関連するコードを1箇所にまとめることができます。

.vueファイルの基本構造を見てみましょう:

<script setup>
// JavaScriptコード(Composition API)
import { ref, computed } from 'vue'

// リアクティブな状態
const count = ref(0)

// 算出プロパティ
const doubleCount = computed(() => count.value * 2)

// メソッド
function increment() {
  count.value++
}
</script>

<template>
  <!-- HTMLテンプレート -->
  <div class="container">
    <h1>カウンター: {{ count }}</h1>
    <p>2倍の値: {{ doubleCount }}</p>
    <button @click="increment">増やす</button>
  </div>
</template>

<style scoped>
/* スコープ付きCSS */
.container {
  max-width: 400px;
  margin: 0 auto;
  padding: 20px;
  text-align: center;
}

h1 {
  color: #42b983;
}

button {
  background-color: #42b983;
  color: white;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
</style>

<script setup>

Vue 3のComposition APIを使用するための構文です。setup属性を追加することで、スクリプト内のコードが自動的にVueコンポーネントのsetup()関数内で実行されます。これにより、コードがより簡潔になります。

この部分では、以下のような処理を行います:

<template>

コンポーネントのHTMLテンプレートを定義する部分です。ここでは、以下のような機能を使用できます:

<style>

コンポーネントのスタイルを定義する部分です。scoped属性を追加すると、そのスタイルはこのコンポーネントのみに適用され、他のコンポーネントには影響しません。

また、CSSプリプロセッサを使用することもできます:

<style lang="scss" scoped>
// SCSSを使用
$primary-color: #42b983;

.container {
  h1 {
    color: $primary-color;
  }
}
</style>

4. main.jsファイルの詳細

main.jsファイルは、Vueアプリケーションのエントリーポイントです。ここで、Vueアプリケーションを初期化し、必要なプラグインやグローバルコンポーネントを登録します。

import { createApp } from 'vue'
import App from './App.vue'

// スタイルのインポート
import './assets/main.css'

// Vueアプリケーションの作成
const app = createApp(App)

// プラグインの登録(例)
// import router from './router'
// app.use(router)

// グローバルコンポーネントの登録(例)
// import BaseButton from './components/BaseButton.vue'
// app.component('BaseButton', BaseButton)

// グローバルプロパティの設定(例)
// app.config.globalProperties.$http = axios

// アプリケーションのマウント
app.mount('#app')

createApp関数を使用してVueアプリケーションを作成し、mountメソッドを使用してDOMにマウントします。その間に、プラグインやグローバルコンポーネントを登録することができます。

5. Vueコンポーネントの命名規則

Vueコンポーネントの命名には、いくつかの規則があります:

6. プロジェクト構造のベストプラクティス

大規模なVueプロジェクトでは、以下のようなディレクトリ構造が推奨されています:

src/
├── assets/          # 静的アセット
├── components/      # 共通コンポーネント
│   ├── base/        # 基本UI要素(BaseButton、BaseInput等)
│   ├── layout/      # レイアウト関連(TheHeader、TheSidebar等)
│   └── ui/          # 特定のUI要素(DataTable、UserCard等)
├── composables/     # 再利用可能なComposition関数
├── views/           # ページコンポーネント
├── router/          # ルーティング設定
├── stores/          # Pinia/Vuexストア
├── services/        # APIサービス
├── utils/           # ユーティリティ関数
├── App.vue          # ルートコンポーネント
└── main.js          # エントリーポイント

このようなディレクトリ構造によって、コードの整理と保守が容易になります。プロジェクトの規模に応じて、必要なディレクトリを追加していくことが重要です。

7. Vueコンポーネントのインポートとエクスポート

Vueコンポーネントを別のコンポーネントで使用するには、インポートして登録する必要があります。Composition API(<script setup>)での例を見てみましょう:

<script setup>
// 子コンポーネントのインポート
import HelloWorld from './components/HelloWorld.vue'
import BaseButton from './components/base/BaseButton.vue'

// propsの定義
defineProps({
  title: String,
  message: {
    type: String,
    required: true,
    default: 'デフォルトメッセージ'
  }
})

// イベントの定義
const emit = defineEmits(['update', 'submit'])

// イベントの発火
function handleSubmit() {
  emit('submit', { success: true })
}
</script>

<template>
  <div>
    <h1>{{ title }}</h1>
    <HelloWorld :msg="message" />
    <BaseButton @click="handleSubmit">送信</BaseButton>
  </div>
</template>

<script setup>を使用すると、インポートしたコンポーネントは自動的に登録され、テンプレート内で直接使用できます。また、definePropsdefineEmitsを使用して、propsとイベントを定義します。

まとめ

本章では、Vueプロジェクトの構成について詳しく学びました。プロジェクトのディレクトリ構造、各ファイルの役割、単一ファイルコンポーネントの構造、コンポーネントの命名規則、そしてプロジェクト構造のベストプラクティスについて理解を深めました。

次の章では、Vue.jsの基本的な機能である「Hello World」とリアクティブシステムについて学びます。

目次に戻る