Vue CLIの各オプションを検討してみた

Contents

はじめに

Vue.jsの勉強をするにあたって、最初に当たる壁は『環境構築』だと思います。

今回はVue CLIを用いたインストール、環境構築について、各オプションを比較ながら検討しようと思います。

また、今回はAlpineのDockerコンテナ上で検証を行ったため、一部機能が使えなかったり、インストールできなかったりしています。ご了承ください!

Vueのインストール

Vueの公式ページによると、Vueのインストール方法はいくつかあるそうです。

直接埋め込み

scriptタグを直接headタグ内に書き込むCDN (Content Delivery Network) 形式です。今回は割愛します。

NPM

NPMを用いてVueをインストールできます。

ただWebpackなどのバンドラと組み合わせて使うものなので、学習コストは高くなってしまいます。

ということで、今回は割愛します。

(いずれは扱えるようになりたいなぁ…)

CLI

Vueからは公式のCLI (Command Line Interface) が提供されています。

他ツールを使うことなく環境構築ができるので、非常に便利です!

今回はこれを題材にしていきます。

Vue CLIインストール

NPMやYarnにてインストールできます。

# NPM
$ npm install -g @vue/cli

# Yarn
$ yarn global add @vue/cli

プロジェクトの作成

プロジェクトの作成方法は主に2種類あります。

CLI

下記コマンドを実行すると、プロジェクト作成のオプションがCLI上で設定できます。

$ vue create <project-name>

詳細なオプションについては後述します。

GUI

下記コマンドを実行すると、8000ポートのlocalhostでブラウザが立ち上がります。

$ vue ui

上記CLIで作成するのと同じ要領で、GUI上でプロジェクトを作成することができます。

コマンドラインでの操作に慣れていない・抵抗がある人も扱いやすいようになっています。親切ですね!

注意点

CLI、GUIともに共通する注意点ですが、プロジェクトはカレントディレクトリ (今自分が操作している階層) に作成されます。

VSCodeのRemote Containerなどを使用していると作業しているディレクトリが操作したいディレクトリになっていることが多いので、プロジェクトを作成する前に1階層上へ行く必要があったりします。

作成してから後悔しないよう、どこにプロジェクトを作成するか見極めてから実行することをオススメします。

username:/app$ vue create app
↓
/app
└ app
   ├ node_modules/
   ├ public/
   ├ src/
   ├ ...

プロジェクト作成時のオプション

プロジェクト作成時に様々なオプションが聞かれます。

各オプションの関係図は下記のイメージです。

├ プリセット
│  ├ プリセット(Vue2)
│  ├ プリセット(Vue3)
│  └ 手動
│     ├ Vueバージョン選択
│     │  ├ 2.x
│     │  └ 3.x
│     ├ Babel
│     ├ TypeScript
│     │  ├ class-style component syntax
│     │  └ Babel alongside TypeScript
│     ├ PWA
│     ├ Router
│     │  └ history mode for router
│     ├ Vuex
│     ├ CSSプリプロセッサ
│     │  ├ Sass/SCSS (with dart-sass)
│     │  ├ Sass/SCSS (with node-sass)
│     │  ├ Less
│     │  └ Stylus
│     ├ 成形ツール
│     │  │  ├ ESLint with error prevention only
│     │  │  ├ ESLint + Airbnb config
│     │  │  ├ ESLint + Standard config
│     │  │  └ ESLint + Prettier
│     │  └─┬ Lint on save
│     │      └ Lint and fix on commit
│     ├ Unitテスト
│     │  ├ Mocha + Chai
│     │  └ Jest
│     └ E2Eテスト
│         ├ Cypress
│         ├ Nightwatch
│         │  ├ Chrome
│         │  └ Firefox
│         └ WebdriverIO
│             ├ Chrome
│             └ Firefox
├ 設定ファイルの置き場所
│  ├ 専用の設定ファイル
│  └ package.json
└ パッケージマネージャ
   ├ NPM
   └ Yarn

プリセットの使用

まずプリセットの使用を聞かれます。

『Manually select features』を選択することで、各オプションをカスタムで設定できます。

? Please pick a preset: (Use arrow keys)
  Default ([Vue 2] babel, eslint) 
  Default (Vue 3) ([Vue 3] babel, eslint) 
❯ Manually select features 

各オプション

プロジェクトを作成する上で、どのオプションが必要なのか聞かれます。

全て選択しない状態でプロジェクトを作成すると、Vueのバージョンは2になるようです。

? Check the features needed for your project: 
❯◯ Choose Vue version
 ◯ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◯ Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◯ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

Vueバージョン選択

Vueのバージョンを聞かれます。

Vue2系とVue3系では書式が大きく異なるので、要注意です。

? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
❯ 2.x 
  3.x 

バージョンが異なるので、もちろん package.json は異なります。

# Vue2

"dependencies": {
  "vue": "^2.6.11"
},
"devDependencies": {
  ...
  "vue-template-compiler": "^2.6.11"
}
# Vue3

"dependencies": {
  "vue": "^3.0.0"
},
"devDependencies": {
  ...
  "@vue/compiler-sfc": "^3.0.0"
}

各Vueファイル、main.js も異なりますが、バージョンによる形式の違いなので割愛します。

Babel

Babelについては、各オプションの選択時に設定していれば組み込まれます。

Babelのインストールが必要になるので、package.json は異なります。

# default

"dependencies": {

  "vue": "^2.6.11"
},
"devDependencies": {

  "@vue/cli-service": "~4.5.0",
  "vue-template-compiler": "^2.6.11"
}
# Babel

"dependencies": {
  "core-js": "^3.6.5",
  "vue": "^2.6.11"
},
"devDependencies": {
  "@vue/cli-plugin-babel": "~4.5.0",
  "@vue/cli-service": "~4.5.0",
  "vue-template-compiler": "^2.6.11"
}

また、Babel の設定ファイルと思われる babel.config.js が追加されていました。

main.js も少し異なりましたが、Babelが要因なのかはわかりませんでした。

# default

new Vue({
  render: function (h) { return h(App) },
}).$mount('#app')
# Babel

new Vue({
  render: h => h(App),
}).$mount('#app')

TypeScript

TypeScriptはさらに追加のオプションが聞かれます。

まずは何もオプションを設定しない場合を見てみます。

TypeScriptのインストールが必要になるので、package.json は異なります。

# default

"devDependencies": {

  "@vue/cli-service": "~4.5.0",

  "vue-template-compiler": "^2.6.11"
}
# TypeScript

"devDependencies": {
  "@vue/cli-plugin-typescript": "~4.5.0",
  "@vue/cli-service": "~4.5.0",
  "typescript": "~4.1.5",
  "vue-template-compiler": "^2.6.11"
}

各Vueファイルでは、TypeScriptを使用した形式に変更されます。

// default

<script>
export default {
  name: 'HelloWorld'
}
</script>
// TypeScript

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'HelloWorld',
});
</script>

main.js と main.ts も異なります。

// main.js

new Vue({
  render: function (h) { return h(App) },
}).$mount('#app')
// main.ts

new Vue({
  render: h => h(App),
}).$mount('#app')

さらにTypeScriptの方は tsconfig.json が作成されます。

Class形式

TypeScriptをクラス形式にするか聞かれます。

? Use class-style component syntax? (Y/n) 

設定すると、一部パッケージが追加されます。

# TypeScript

"dependencies": {
  ...


},
# TypeScript + class-style component syntax

"dependencies": {
  ...
  "vue-class-component": "^7.2.3",
  "vue-property-decorator": "^9.1.2"
},

また、tsconfig.json にも1行追加されます。

# TypeScript

{
  "compilerOptions": {
    ...

  },
  ...
}
# TypeScript + class-style component syntax

{
  "compilerOptions": {
    ...
    "experimentalDecorators": true,
  },
  ...
}

各Vueファイルは vue-property-decorator を用いた書式に変更されます。

# TypeScript

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'HelloWorld',
});
</script>
# TypeScript + class-style component syntax

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {}
</script>
Babel

TypeScriptのコンパイルとBabelの設定になるのですが、よくわかりませんでした…勉強中です。

? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (y/N) 

なお『Babel + TypeScript (上記オプション無し)』と『TypeScript (上記オプション有り)』を比較したところ、『Babel + TypeScript (上記オプション無し)』側にはBabelをインストールせず、設定ファイル (babel.config.js) もありませんでした。

また、tsconfig.json だけ異なっていました。

ここもまだ理解できていません。精進します…。

# Babel + TypeScript (上記オプション無し)

{
  "compilerOptions": {
    "target": "es5",
    ...
  },
  ...
}
# TypeScript (上記オプション有り)

{
  "compilerOptions": {
    "target": "esnext",
    ...
  },
  ...
}

PWA

PWAは Progressive Web App の略で、『WebページやWebアプリをスマートフォン向けのアプリのように利用できる技術のこと』とのことです。

スマホのホーム画面にアイコンを追加したり、プッシュ通知をしたりできるようです。

PWAについても、各オプションの選択時に設定していれば組み込まれます。

PWAを可能にするパッケージをインストールするので、package.json は異なります。

# default

"dependencies": {

  ...
},
"devDependencies": {

  ...
}
# PWA

"dependencies": {
  "register-service-worker": "^1.7.1",
  ...
},
"devDependencies": {
  "@vue/cli-plugin-pwa": "~4.5.0",
  ...
}

またPWAを追加したプロジェクトには main.js が一部変更されており、さらに registerServiceWorker.js が追加されていました。

PWAを実現するための設定などになると思いますが、今回は割愛します。

いずれ勉強したい!

Router

追加パッケージとしてVue Routerが追加されるので、package.json は異なります。

# default

"dependencies": {
  ...

},
"devDependencies": {

  ...
}
# Router

"dependencies": {
  ...
  "vue-router": "^3.2.0"
},
"devDependencies": {
  "@vue/cli-plugin-router": "~4.5.0",
  ...
}

他にも main.js にRouterの設定が追加されたり、router/index.js が追加されたり、views ディレクトリができたりと、Vue Routerに沿って大きく変化があります。

ほぼVue Routerの機能になるので割愛します。別の機会に改めて紹介できたらと思います!

またRouterでも追加のオプションとして、Historyモードの有無を聞かれます。

Vue Routerの機能になるので詳細は割愛しますが、サーバ側の設定が不要になるようURLにハッシュ (#) が入るものになります。

? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) 

なお、差分としては router/index.js が変更されるだけなので、後からの変更も容易だと思います。

# Router

const router = new VueRouter({


  routes
})
# Router + History Mode

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

Vuex

Vuexは『Vue.js アプリケーションのための 状態管理パターン + ライブラリ』とのことです。

詳細は割愛しますが、異なるコンポーネント間でデータを保持し、やり取りを行えるようになります。

Vuexについても、各オプションの選択時に設定していれば組み込まれます。

Vuexをインストールするので、package.json は異なります。

# default

"dependencies": {
  ...

},
"devDependencies": {

  ...
}
# Vuex

"dependencies": {
  ...
  "vuex": "^3.4.0"
},
"devDependencies": {
  "@vue/cli-plugin-vuex": "~4.5.0",
  ...
}

他にも main.js にVuexの設定が追加されたり、store/index.js が追加されたり、views ディレクトリができたりしますが、ほぼVuexの機能になるので割愛します。

CSSプリプロセッサ

CSSプリプロセッサも追加のオプションが聞かれます。

? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys)
❯ Sass/SCSS (with dart-sass) 
  Sass/SCSS (with node-sass) 
  Less 
  Stylus 
dart-sass

Dart SassはSassのプリプロセッサの1種で、package.json に追記されます。

# default

"devDependencies": {
  ...
 
 
  ...
}
# Dart Sass

"devDependencies": {
  ...
  "sass": "^1.26.5",
  "sass-loader": "^8.0.2",
  ...
}

各Vueファイルはstyleタグに lang="scss" が追記されます。他は特に変更はありませんでした。

node-sass

Node SassもSassのプリプロセッサの1種ですが、推奨されていないため割愛します。

(僕の環境ではパッケージのインストール時にエラーが出てしまいました)

Less

LessもCSSの拡張言語の1種で、package.json に追記されます。

# default

"devDependencies": {
  ...


  ...
}
# Less

"devDependencies": {
  ...
  "less": "^3.0.4",
  "less-loader": "^5.0.0",
  ...
}

各Vueファイルはstyleタグに lang="less" が追記されます。他は特に変更はありませんでした。

Stylus

StylusもCSSの拡張言語の1種で、package.json に追記されます。

# default

"devDependencies": {
  ...


  ...
}
# Stylus

"devDependencies": {
  ...
  "stylus": "^0.54.7",
  "stylus-loader": "^3.0.2",
  ...
}

各Vueファイルはstyleタグに lang="stylus" が追記され、書式もStylusに変更されていました。

整形ツール

? Pick a linter / formatter config: 
❯ ESLint with error prevention only 
  ESLint + Airbnb config 
  ESLint + Standard config 
  ESLint + Prettier 
ESLint with error prevention only
# default

"scripts": {
  ...

},
...
"devDependencies": {

  ...


  ...
}
# ESLint

"scripts": {
  ...
  "lint": "vue-cli-service lint"
},
...
"devDependencies": {
  "@vue/cli-plugin-eslint": "~4.5.0",
  ...
  "eslint": "^6.7.2",
  "eslint-plugin-vue": "^6.2.2",
  ...
}

また、.eslint.js と vue.config.js が追加されていました。

.eslint.js はESLintの設定ファイルなので詳細は割愛します。

vue.config.js については後述します。

以降オプションについては、上記オプションと比較してみます。

ESLint + Airbnb config
# ESLint

"devDependencies": {
  ...

  ...

  ...
}
# ESLint + Airbnb

"devDependencies": {
  ...
  "@vue/eslint-config-airbnb": "^5.0.2",
  ...
  "eslint-plugin-import": "^2.20.2",
  ...
}

各Vueファイル、config.js などが整形ツールに従って、末尾にカンマが付くなどの変更がありました。

また、.eslintrc.js も一部変更されていました。

# ESLint

module.exports = {
  ...
  extends: [
    ...
    'eslint:recommended'
  ],
  ...
}
# ESLint + Airbnb

module.exports = {
  ...
  extends: [
    ...
    '@vue/airbnb',
  ],
  ...
},

さらに、ESLint + Airbnb側では .editorconfig も追加されます。

ESLint + Standard config
# ESLint

"devDependencies": {
  ...

  ...




  ...
}
# ESLint + Standard config

"devDependencies": {
  ...
  "@vue/eslint-config-standard": "^5.1.2",
  ...
  "eslint-plugin-import": "^2.20.2",
  "eslint-plugin-node": "^11.1.0",
  "eslint-plugin-promise": "^4.2.1",
  "eslint-plugin-standard": "^4.0.0",
  ...
}

また、.eslintrc.js も一部変更されていました。

# ESLint

module.exports = {
  ...
  'extends': [
    ...
    'eslint:recommended'
  ],
  ...
}
# ESLint + Standard config

module.exports = {
  ...
  extends: [
    ...
    '@vue/standard'
  ],
  ...
}

さらに、ESLint + Standard config側では .editorconfig も追加されます。

※Airbnb側とは一部異なります。

ESLint + Prettier
# ESLint

"devDependencies": {
  ...

  ...

  ...

  ...
}
# ESLint + Prettier

"devDependencies": {
  ...
  "@vue/eslint-config-prettier": "^6.0.0",
  ...
  "eslint-plugin-prettier": "^3.3.1",
  ...
  "prettier": "^2.2.1",
  ...
}

各Vueファイル、config.js などが整形ツールに従って、末尾にカンマが付くなどの変更がありました。

また、.eslintrc.js も一部変更されていました。

# Title

module.exports = {
  ...
  'extends': [
    'plugin:vue/essential',
    'eslint:recommended'

  ],
  ...
}
# Title

module.exports = {
  ...
  extends: [
    "plugin:vue/essential",
    "eslint:recommended",
    "@vue/prettier",
  ],
  ...
}
共通オプション

また、いずれの整形ツールでも下記オプションを追加で設定できます。

? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◯ Lint on save
 ◯ Lint and fix on commit

Lint on saveを選択がデフォルトなので、選択しない場合 vue.config.js が追加されます。

module.exports = {
  lintOnSave: false
}

Lint and fix on commitを選択した場合、パッケージが追加されるため package.json が更新されます。

# Lint default

"devDependencies": {
  ...

  ...
}









# Lint and fix on commit

"devDependencies": {
  ...
  "lint-staged": "^9.5.0",
  ...
},
"gitHooks": {
  "pre-commit": "lint-staged"
},
"lint-staged": {
  "*.{js,jsx,vue}": [
    "vue-cli-service lint",
    "git add"
  ]
}

Unitテスト

? Pick a unit testing solution: (Use arrow keys)
❯ Mocha + Chai 
  Jest 
Mocha + Chai
# Title

"scripts": {
  ...

},
...
"devDependencies": {

  ...


  ...
}
# Title

"scripts": {
  ...
  "test:unit": "vue-cli-service test:unit"
},
...
"devDependencies": {
  "@vue/cli-plugin-unit-mocha": "~4.5.0",
  ...
  "@vue/test-utils": "^1.0.3",
  "chai": "^4.1.2",
  ...
}

また tests/unit ディレクトリが作成され、中に example.spec.js が作成されていました (内容はJestのものと同じ)。

Jest
# Title

"scripts": {
  ...

},
...
"devDependencies": {

  ...

  ...
}
# Title

"scripts": {
  ...
  "test:unit": "vue-cli-service test:unit"
},
...
"devDependencies": {
  "@vue/cli-plugin-unit-jest": "~4.5.0",
  ...
  "@vue/test-utils": "^1.0.3",
  ...
}

また tests/unit ディレクトリが作成され、中に example.spec.js が作成されていました (内容はMocha + Chaiのものと同じ)。

さらに直下には jest.config.js が追加されていました。

E2Eテスト

? Pick an E2E testing solution: 
❯ Cypress (Chrome only) 
  Nightwatch (WebDriver-based) 
  WebdriverIO (WebDriver/DevTools based) 
Cypress
# Title

"scripts": {
  ...

},
...
"devDependencies": {

  ...
}
# Title

"scripts": {
  ...
  "test:e2e": "vue-cli-service test:e2e"
},
...
"devDependencies": {
  "@vue/cli-plugin-e2e-cypress": "~4.5.0",
  ...
}

また tests/e2e ディレクトリが作成され、中にテスト用の項目が追加されていました。詳細は割愛します。

さらに直下には cypress.json が作成され、.gitignore にも若干追加分がありました。

Nightwatch
# Title

"scripts": {
  ...

},
...
"devDependencies": {

  ...
}
# Title

"scripts": {
  ...
  "test:e2e": "vue-cli-service test:e2e"
},
...
"devDependencies": {
  "@vue/cli-plugin-e2e-nightwatch": "~4.5.0",
  ...
}

また tests/e2e ディレクトリが作成され、中にテスト用の項目が追加されていました。詳細は割愛します。

WebdriverIO

私が検証している環境 (Alpine) ではインストールできなかったので、今回は割愛します。

いずれ何かの環境で検証したい!

共通オプション

Nightwatch と WebdriverIO ではブラウザのドライバを選択できます。

? Pick browsers to run end-to-end test on 
❯◯ Chrome
 ◯ Firefox

選択に応じて各ドライバをインストールするため、package.json に追記されます。

# Chrome

"devDependencies": {
  ...
  "chromedriver": "^84.0.1",
  ...
}
# Firefox

"devDependencies": {
  ...
  "geckodriver": "^1.20.0",
  ...
}

設定ファイル

BabelやESLintの設定ファイルをどうするか聞かれます。

『In dedicated config files』だと専用の設定ファイルが作成され、『In package.json』だとpackage.jsonに集約されます。

? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
❯ In dedicated config files 
  In package.json 

パッケージマネージャ

NPMかYarnのどちらで作成を進めるか聞かれます。任意のものを選択します。

※Yarnがインストールされていない場合、この選択はスキップされます。

? Pick the package manager to use when installing dependencies: 
❯ Use Yarn 
  Use NPM 

おわりに

まだ知らない項目が多いせいか、全然まとまりませんでした…

Vue CLIを用いることで、様々なオプション、パッケージを含んだプロジェクトを簡単に作れることがわかりました。

初学者の勉強や簡単なプロジェクトには最適だと思います。

これからVue CLIを使う人の役に立てればと思います!

最後まで読んでいただきありがとうございます。

指摘や意見があればコメントにてお願いします!

参考

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です