Vue-cli(webpack)解剖 ーディレクトリ構成ー

この記事は [株式会社Y's アドベントカレンダー](https://qiita.com/advent-calendar/2017/ysinc) 19日目の記事です。(大遅刻...)

今月自社で行われたビアバッシュでVue関連の質問受付を丸投げされたので(発表者は私ではない)、初心にかえり、Vue-cliを前提とした、私が実際に構築しているディレクトリ構造についてお話しようかなと思います。

# Vue-cliの種類

インストールの方法はたくさんの方がわかりやすく記事にしてくれているので割愛します。
↓おすすめ参考記事
[Vue.js を vue-cli を使ってシンプルにはじめてみる](https://qiita.com/567000/items/dde495d6a8ad1c25fa43)

Vue-cliには６つのテンプレートが用意されています。(2017年12月現在)

＊ **webpack**　[github](https://github.com/vuejs-templates/webpack)
 - A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction.
(ホットリロード、linting、テスト＆CSS抽出を備えたフル機能のWebpack + vue-loader設定)
```$ vue init webpack my-project```
 
 
＊ **webpack-simple**　[github](https://github.com/vuejs-templates/webpack-simple)
 - A simple Webpack + vue-loader setup for quick prototyping.
(クイックプロトタイピングのためのシンプルなWebpack + vue-loaderセットアップ。)
```$ vue init webpack-simple my-project```
 
 
＊ **browserify**　[github](https://github.com/vuejs-templates/browserify)
 - A full-featured Browserify + vueify setup with hot-reload, linting & unit testing.
(ホットリロード、linting＆ユニットテストを備えたフル機能のBrowserify + vueify設定。)
```$ vue init browserify my-project```
 
 
＊ **browserify-simple**　[github](https://github.com/vuejs-templates/browserify-simple)
 - A simple Browserify + vueify setup for quick prototyping.
(クイックプロトタイピングのための簡単なBrowserify + vueify設定。)
```$ vue init browserify-simple my-project```
 
 
＊ **pwa**(プログレッシブウェブアプリ)　[github](https://github.com/vuejs-templates/pwa)
 - PWA template for vue-cli based on the webpack template
(webpackテンプレートに基づくvue-cli用のPWAテンプレート)
```$ vue init pwa my-project```
 
 
＊ **simple**　[github](https://github.com/vuejs-templates/simple)
 - The simplest possible Vue setup in a single HTML file
(単一のHTMLファイルで可能な最も簡単なVue設定)
```$ vue init simple my-project```
 
 
私はwebpackかwebpack-simpleを使用しています。
webpack-simpleが一番拡張しやすく、導入もしやすいかなと思います。

が、今回はwebpackテンプレートでの構造について。

# webpackテンプレートをインストール！
たくさんの機能が一括でインストール&設定されているので、一から構築する時に最適です。
ですが、公式githubを覗いてみると
>The develop branch is not considered stable and can contain bugs or not build at all, so use at your own risk.
訳：開発ブランチは安定しているとはみなされず、バグを含んでいるか、まったくビルドされていない可能性があります。したがって、自己責任で使用してください。

となっておりますので、開発ブランチを使用する際は注意をしないといけません。
※コメントで頂いた通り、明示的に開発ブランチを指定しない限りはインストールされません。

```$ vue init webpack my-project```を唱えるといくつか質問をされます。

```console
? Project name
? Project description (A Vue.js project) 
? Author (umeda-haruka <>)
? Vue build (Use arrow keys)
  > Runtime + Compiler: recommended for most users 
  > Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-
specific HTML) are ONLY allowed in .vue files - render functions are r
equired elsewhere
? Install vue-router? (Y/n) 
? Use ESLint to lint your code? (Y/n) 
? Pick an ESLint preset (Use arrow keys)
  > Standard (https://github.com/standard/standard) 
  > Airbnb (https://github.com/airbnb/javascript) 
  > none (configure it yourself) 
? Set up unit tests (Y/n) 
  > Jest 
  > Karma and Mocha 
  > none (configure it yourself) 
? Setup e2e tests with Nightwatch? (Y/n) 
? Should we run `npm install` for you after the project has been creat
ed? (recommended) (Use arrow keys)
  > Yes, use NPM 
  > Yes, use Yarn 
  > No, I will handle that myself 
```

まぁひとまずEnterを押しておきましょう。
なお、
Use ESLint to lint your code?でnを選択すると下記のディレクトリから(※１)
.eslintignore
.eslintrc.js

Set up unit tests?でnを選択すると下記のディレクトリから(※２)
.test/
.build/webpack.test.conf.js

が除外されて構築されます。
　

作成されたディレクトリ↓↓

```console
./
├─build/
│　　　　├─build.js
│　　　　├─check-versions.js
│　　　　├─logo.png
│　　　　├─utils.js
│　　　　├─vue-loader.conf.js
│　　　　├─webpack.base.conf.js
│　　　　├─webpack.dev.conf.js
│　　　　├─webpack.prod.conf.js
│　　　　└─webpack.test.conf.js //※2
│
├─config/
│　　　　├─dev.env.js
│　　　　├─index.js
│　　　　├─prod.env.js
│　　　　└─test.env.js
│
├─src/
│　　　　├─assets/
│　　　　├─components/
│　　　　├─router/
│　　　　├─App.vue
│　　　　└─main.js
│
├─static/
│　　　　└─.gitkeep
│
├─test/ //※2
│　　　　├─e2e/
│　　　　└─unit/
│
├─index.html
├─package.json
├─README.md
├─.editorconfig
├─.eslintignore //※1
├─.eslintrc.js //※1
├─.gitignore
└─.postcssrc.js
```
盛りだくさん^^

ざっくりとディレクトリの紹介をすると
・build/
→webpackの設定やビルド用の設定ディレクトリ

・config/
→ポートの指定等を含めた各設定ファイルを格納したディレクトリ

・src/
→開発用ディレクトリ

・static/
→コンポーネントに依存しない静的ファイルを格納するディレクトリ

・test/
→テスト用設定ディレクトリ



# パターンに合わせて構築する！
追加ディレクトリに関してはあくまでも私個人が構築しやすい構造のため参考にどうぞ。

## 画像
画像をvueコンポーネントで読み込むには２通りのパターンがあります。

#### **src/asset/**
コンポーネントで呼び出す画像など、モジュールに依存した素材を格納します。
基本画像はこちらに格納します。

```console
src/
　　　└─assets/
     └─images/

```

呼び出しはビルド前のソースを記載します。↓

```html:html
<img src="../assets/images/logo.png" alt="Vue.jsのロゴ">
```
```js:script
export default {
  name: 'HelloWorld',
  data () {
    return {
      img: require('../assets/images/logo.png')
    }
  }
}
```
```css:style
div {
 background: url('../assets/images/logo.png') no-repeat;
}
```
vueのコンポーネントのデータとしてurlを持つときはrequire必須です。
記載がないとエラーを吐き出されます。

詳しく詳細を載っている参考記事↓
[Vue.jsでimgタグのsrcをバインドさせる際の注意点](http://tk2000ex.blogspot.jp/2017/11/vue.html)


#### **static/**
staticディレクトリに格納されているデータはwebpackによるビルドの影響を受けません。
```npm run build```で作成されたdistディレクトリの中にそのまま格納されます。
そのため、ソースコード内では

```html:html
<img src="./static/logo.png" alt="Vue.jsのロゴ">
```
```css:style
div {
 background: url('./static/logo.png') no-repeat;
}
```
といった形になります。

## スタイル
src直下にstylesディレクトリを追加で作成しています。
その中にレイアウト系やベースとなるスタイルを定義したファイルを格納しています。(scss使ってます)

```console
src/
　　　└─styles/
     ├─base/
     ├─layout/
     ├─project(or page/function)/
     └─common.scss
```
そして親コンポーネントでまとめて呼び出し。

```css:App.vue
@import "./styles/common.scss";
```

コンポーネント毎のスタイルはcomponentsディレクトリ内の.vueファイルで別途記述しています。

vueファイル内で呼び出さなくてもstaticディレクトリにstylesディレクトリ作成してgulpとかでビルドしてhtml部分で

```html:index.html
<link href="/css/common.min.css" rel="stylesheet">
```
で呼び出してもいいと思います。
別途タスク作るのが面倒だったので私はあまりやりません...。

## ページ
src直下にpagesディレクトリを追加で作成しています。
nuxt.jsのcliを落とすと存在するpagesディレクトリというのがありまして、わかりやすいためvueの時も使っています。

```console
src/
　　　└─pages/
     ├─top.vue  //トップページ
     ├─login.vue　　　//ログインページ
     └─details.vue　　　//詳細ページ

```

機能毎にページを作成し、router部分で切り替えて作成。
それぞれのvueファイルでcomponentsディレクトリのコンポーネントを呼び出しています。


# 最後に
まだまだ書こうかなと思った部分が多いのですが、長くなってしまったのでひとまずこれにて...。
いつかハンズオンやりたいですね。
　
　
　

次は 20日目 @T_igarashi さんの記事です。お楽しみに！!