前回記事の続きです。
【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には各種設定に加え、ローカルサーバ起動の処理も記述されています。
"scripts": {
// ローカルサーバ起動
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
// ビルド
"build": "node build/build.js"
},
build.js
から設定ファイルが読み込まれ、必要な値がセットされます。
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
エントリポイントの場所やbundleファイルの出力先などを指定するwebpack.base.conf.js
は、共通で読み込まれます。
// webpack.dev.conf.jsも同じ記述あり
const baseWebpackConfig = require('./webpack.base.conf')
抜粋して確認してみます。
const config = require('../config')
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ファイルの中にそれぞれの設定が記述がされています。
module.exports = {
dev: {
// ローカルサーバ起動の設定
},
build: {
// ビルドの設定
}
}
そのほかにpackage-lock.json
も読み込まれているようです。(name
やprocess
の設定が記述されています。)
webpackConfig
がセットされたら、ビルドが実行されます。
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.vue
とHelloWorld.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>
の部分に注目です。
コメントの通り、ここにビルドされたファイルが挿入されます。
<!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がそのまま反映されるようです。
// 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コンポーネント
が呼び出されています。
<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プロパティを設定しているので、その値も反映されます。
<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)