LoginSignup
62
72

More than 3 years have passed since last update.

【Vue.js】Vue CLIでVue.jsを動かす〜ビルドまでの流れ、生成されたファイルの構造について

Posted at

前回記事の続きです。
【Vue.js】Vue CLIでVue.jsを動かす〜プロジェクト作成まで

今回は、vue initで生成されたプロジェクトの中を確認してみます。

以下の項目を中心に、順番にたどりながら進めたいと思います。
作成したファイルがどういう流れでビルドされて、そのためにはどういった設定が必要か、概要を確認します。

  • 生成されたディレクトリ・ファイルの概要
  • エントリポイントとbundleファイルの出力先
  • ビルドとローカルサーバ(開発用サーバ)の起動について
  • 描画されるファイルのつながり

ディレクトリ構造

$ cd my-app
$ tree -L 1
.
├── README.md 
├── build             // ビルド用スクリプトを格納
├── config            // ビルド用設定ファイルを格納
├── index.html        // インデックス、最終的にこのファイルに描画される
├── node_modules      // パッケージを格納
├── package-lock.json // パッケージのバージョン情報
├── package.json      // スクリプトやインストールされたパッケージの情報
├── src               // ビルド対象のファイルを格納
└── static            // 静的ファイルを格納

実際に描画されるファイル(ビルド対象のファイル)はsrcディレクトリに格納されています。

$ cd src
$ tree -L 2
.
├── App.vue            // 単一ファイルコンポーネント
├── assets             // 画像やフォントなどを格納
│   └── logo.png       // 画像ファイル
├── components         // コンポーネントを格納
│   └── HelloWorld.vue // 単一ファイルコンポーネント
└── main.js            // エントリーポイントとなるファイル

さらにnpm run buildを行うと、distディレクトリが生成されます。
ビルド後アプリケーションを公開した時、実際に表示されるファイル(bundleファイル)が格納されています。

$ cd dist
$ tree -L 2
.
├── index.html
└── static
    ├── css
    └── js

ただし、ビルド後に以下のメッセージが表示されます。
HTTP serverで公開されることを前提としているため、file://でindex.htmlにアクセスしても表示確認ができないようです。

Tip: built files are meant to be served over an HTTP server.
Opening index.html over file:// won't work.

参考記事

vue-cliでVue.jsをインストールしたときのファイルについて
vue-cliでwebアプリケーションを作って、GitHubPagesで無料で爆速でリリースした話

webpackの設定

devとbuildの違い

両方ともmy-app/package.jsonで定義されています。

dev

webpackのプラグインwebpack-dev-serverにより、ローカルサーバが起動します。
編集したファイルはブラウザをリロードすれば即反映されるので、動作確認に便利です。

ビルドではありません。

build

ビルドです。

エントリーポイントを起点として読み込まれたファイル群が、公開用のbundleファイルにまとめられます。

ビルド/ローカルサーバ起動までの道のり

npm run buildを実行するとbuild/build.jsが実行されます。

webpack-dev-serverでローカルサーバを起動する場合は、build.jsは呼ばれません。(ビルドではありません。)
設定ファイルもwebpack.prod.conf.jsではなくwebpack.dev.conf.jsが呼ばれます。webpack.dev.conf.jsには各種設定に加え、ローカルサーバ起動の処理も記述されています。

package.json
"scripts": {
  // ローカルサーバ起動
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start": "npm run dev",
  // ビルド
  "build": "node build/build.js"
},

build.jsから設定ファイルが読み込まれ、必要な値がセットされます。

build/build.js
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')

エントリポイントの場所やbundleファイルの出力先などを指定するwebpack.base.conf.jsは、共通で読み込まれます。

build/webpack.prod.conf.js
// webpack.dev.conf.jsも同じ記述あり
const baseWebpackConfig = require('./webpack.base.conf')

抜粋して確認してみます。

build/webpack.base.conf.js
const config = require('../config')
build/webpack.base.conf.js
module.exports = {
  // ファイルパスの起点を指定
  // my-appプロジェクトの場合はmy-appディレクトリが指定される
  context: path.resolve(__dirname, '../'),
  // エントリーポイント
  entry: {
    app: './src/main.js'
  },
  // bundleファイルの出力先
  output: {
    path: config.build.assetsRoot,
    // nameやprocessはpackage-lock.jsonより
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      // ビルド用
      ? config.build.assetsPublicPath
      // ローカルサーバ起動用
      : config.dev.assetsPublicPath
  },

webpack.base.conf.jsではconfig/index.jsを読み込んでいます。つまり、index.jsはビルド/ローカルサーバ起動を問わず呼び出されるファイルということです。
こちらは、1ファイルの中にそれぞれの設定が記述がされています。

config/index.js
module.exports = {
  dev: {
    // ローカルサーバ起動の設定
  },

  build: {
    // ビルドの設定
  }
}

そのほかにpackage-lock.jsonも読み込まれているようです。(nameprocessの設定が記述されています。)

webpackConfigがセットされたら、ビルドが実行されます。

build/build.js
webpack(webpackConfig, (err, stats) => {
  // ビルド処理
})

これらの設定は、webpackのwebpack.config.jsファイルに該当する部分です。
以前に記事の中で紹介しました。
【JavaScript】ビルドとは何か〜webpackを使ってビルドする

開発用にビルドを行う(本番用とは別のサーバにビルドする)場合は、別途設定が必要です。
vue-cliのwebpackテンプレートで環境別にnpm run buildが出来るようにする

参考記事

webpackのメモ
webpack.config.jsで思ったpath.resolveって何のためにあるの?

ファイルの構造

デモ画面は以下のファイルから構成されています。
どこから何が読み込まれて何が表示されているのか、順番に確認していきます。

  • index.html
  • src/main.js
  • src/App.vue
  • src/components/HelloWorld.vue

コンポーネントとは

先にコンポーネントについて簡単に説明します。

コンポーネントとは再利用可能な名前付きの部品(Vueインスタンス)のことです。
複数の画面で、共通して利用したい機能がある時に使います。

他の部品とは切り離されているため、メンテナンスも簡単になります。

コンポーネントの設定については、公式サイトに詳しく説明されています。
公式サイト>コンポーネントオプション

単一ファイルコンポーネント

これから紹介するApp.vueHelloWorld.vueは、単一ファイルコンポーネントと呼ばれています。

1つのコンポーネント内でHTML, JavaScript, CSSがセットになっており、ファイルの拡張子が.vueになります。

中規模以上の開発でよく使われるそうです。

公式サイト>単一ファイルコンポーネント

index.html

npm run dev実行時メッセージの通り、http://localhost:8080にアクセスすると表示されるインデックスです。

Your application is running here: http://localhost:8080

普通のhtmlファイルですが、<div id="app"></div>の部分に注目です。
コメントの通り、ここにビルドされたファイルが挿入されます。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>my-app</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

main.js

エントリーポイントとなるjsファイルです。

index.htmlのid="app"要素に結びついています(マウント)。main.jsの内容がid="app"要素の中に挿入されます。

template: '<App/>'により、main.jsのtemplateとして、Appコンポーネントのtemplateがそのまま反映されるようです。

src/main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
// 具体的に何をしているのかわかりません・・・おまじない?
import Vue from 'vue'
// Appコンポーネントをインポート
import App from './App'

// Vue.js起動時に、コンソールにヒントが表示されなくなる
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  // elオプション
  // アプリケーション(この場合はindex.html)に紐づける要素を指定する
  // #appにマウントする、と言うらしい
  el: '#app',
  // componentsオプション
  // Appコンポーネントを利用する
  components: { App },
  // templateオプション
  // Appコンポーネントのタグ名を設定する
  // <App/>としてAppコンポーネントのtemplateを呼び出せる
  template: '<App/>'
})

App.vue

main.jsから呼び出されている単一ファイルコンポーネントです。

templateタグで囲われている部分が、実際に表示されます。
templateタグ内では、さらにHelloWorldコンポーネントが呼び出されています。

src/App.vue
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <!-- ここにHelloWorldコンポーネントが挿入される -->
    <HelloWorld/>
  </div>
</template>

<script>
// HelloWorldコンポーネントをインポート
import HelloWorld from './components/HelloWorld'

export default {
  // nameオプション
  // コンポーネントコンストラクタ名をAppに設定する
  name: 'App',
  // componentsオプション
  // HelloWorldコンポーネントを利用する
  components: {
    HelloWorld
  }
}
</script>

<style>
  /* CSSを記述 */
</style>

HelloWorld.vue

App.vueから呼び出されている単一ファイルコンポーネントです。

templateタグで囲われている部分が、実際に表示されます。
dataオプションのmsgプロパティを設定しているので、その値も反映されます。

src/components/HelloWorld.vue
<template>
  <div class="hello">
 <!-- 設定したmsgプロパティの値が入る -->
  <h1>{{ msg }}</h1>
  <!-- 省略 -->
  </div>
</template>

<script>
export default {
  // nameオプション
  // コンポーネントコンストラクタ名をHelloWorldに設定する
  name: 'HelloWorld',
  // dataオプション
  data () {
    return {
      // msgプロパティの値を設定する
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<!-- HelloWorldコンポーネント限定のCSSを設定 -->
<style scoped>
  /* CSSを記述 */
</style>

参考記事

VueCLIからVue.js入門①【VueCLIで出てくるファイルを概要図で理解】
vue-cliで始めるVue.jsチュートリアル (1)

62
72
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
72