9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

カスタムテンプレートを作ってvue-cliでinstallする

Last updated at Posted at 2019-01-08

始めに

Vue.jsを始めるに当たって、簡単に始めるためにvue-cliを作って環境を取ってくることがあると思います。

vue-cliで環境を取ってくる
$ vue init webpack <project-name>

実はこのテンプレートは自作することができて、そのテンプレートを使うことができます。

こちらにテンプレートを作ってみたので、これを取ってくる場合は以下のようにします。
https://github.com/TakanoriOnuma/vue-template

カスタムテンプレートを取ってくる
$ vue init TakanoriOnuma/vue-template <project-name>

このカスタムテンプレートですが、結構作り方が見つからなかったのでまとめてみました。

テンプレートの基本構成

カスタムテンプレートを作る場合はざっくり言うと以下のような構成になります。
vue initすると、templateディレクトリの中身がごっそりコピーされるので、設定がいらない場合は環境をそのままtemplateディレクトリに入れるだけでテンプレートができてしまいます。
ただ他のテンプレートを使っている人はわかると思いますが、lintを入れてみたり、vuexを入れてみたり、色々オプションを聞かれて必要なものだけ取り込まれていると思います。その辺の設定はmeta.jsで書き、ここで得られたフラグを元にコードの出し分けをします。

ディレクトリ構成
- template/  # template以下のものが全てコピーされます(設定で取り除いたりできます)
- meta.js    # テンプレートを取り込む際に色々設定するところです
- README.md  # なくても大丈夫ですが、一応

meta.jsの設定

meta.jsは以下のような設定をします。jsonでも設定は出来ますが、JSの方が細かい設定もできるのでこっちにしています(コメントもかけますし)。

meta.js
module.exports = {
  prompts: {
    name: {
      type: 'string',
      message: 'Project Name'
    },
    description: {
      type: 'string',
      message: 'Description',
      default: 'A Vue.js project'
    },
    author: {
      type: 'string',
      message: 'Author'
    },
    licence: {
      type: 'string',
      message: 'licence',
      default: 'MIT'
    },
    devServerPort: {
      type: 'string',
      message: 'dev server port',
      default: '4000'
    },
    // confirmがフラグになる
    isUseStore: {
      type: 'confirm',
      message: 'is use Vuex Store?'
    }
  },
  // 条件にマッチする時だけコピーする
  filters: {
    'src/javascripts/store/**/*': 'isUseStore'
  },
  // vue initで展開させないファイルを指定する
  skipInterpolation: ['node_modules/**'],
  complete: (data) => {
    console.log('\nTo get started:');
    // 別ディレクトリに生成する場合は出力先のディレクトリに移動するメッセージを出す
    if (!data.inPlace) {
      console.log(`  cd ${data.destDirName}`);
    }
    console.log('  yarn install');
    console.log('  yarn start');
  }
};

promptsのところで各項目の質問を書きます。
文字列を受け取りたいときはtypeをstringにして、true/falseのフラグはconfirmにします。
ちなみにnameやauthorは勝手にデフォルトの値が設定されます。おそらくnameはディレクトリ名、authorはgitのauthorから取ってきていると思います。
filtersやskipInterpolationは後ほど説明します。
completeではテンプレートの読みこみが終了した時の処理を書きます。vue initでは第2引数にディレクトリ名を指定するのが通例ですが、ない場合はカレントディレクトリに読み込まれるのでその条件分岐も書かれています。

実際に実行するとこんな感じになります。
スクリーンショット 2019-01-08 17.07.18.png

meta.jsで設定したパラメータを展開する

単純な展開

meta.jsのpromptに書かれたkey名が変数として使えるので、これを使ってテンプレートをカスタマイズしていきます。
変数の展開はmustash記法が使え、例えばREADME.mdだと以下のようになります。
namedescriptiondevServerPortがプロンプトで設定した値が入る感じです。

README.md
# {{ name }}
{{ description }}

## 環境
+ node: 10.15.0
+ npm: 6.2.0

## インストール
`$ npm install`

## タスク一覧
### 開発サーバーの立ち上げ
`$ npm start`  
[http://localhost:{{ devServerPort }}](http://localhost:{{ devServerPort }})にアクセスしてフロントエンドの開発をする。  

### フロントエンドのコードのビルド
`$ npm run build`  
dist以下に生成物を配置する。

フラグに応じた出し分け

今回はisUseStoreと言う変数を使ってVuexを使うかのフラグを持っています。これに応じてvuexをpackage.jsonに書くか否かを設定するので、package.jsonは以下のようになります。
以下のように{{#フラグ変数}} コンテンツ {{/フラグ変数}}でフラグ変数がtrueの時だけコンテンツを出力します。

package.json
{
  // dependenciesだけ記載
  "dependencies": {
    "reset-css": "^4.0.1",
    "vue": "^2.5.21",
    "vue-types": "^1.3.4"{{#isUseStore}},
    "vuex": "^3.0.1"{{/isUseStore}}
  }
}

storeの設定はstoreディレクトリに配置しており、ファイルごと取り除きたい場合はmeta.jsの方に記述します。

meta.js(一部のみ)
module.exports = {
  // isUseStoreがtrueの時だけstore以下のファイルを出力する
  filters: {
    'src/javascripts/store/**/*': 'isUseStore'
  }
};

Vue.jsにもmustash記法で展開したい場合

同じ要領でVue.jsにも書いていきたいですが、Vue.jsでもmustash記法が使われており、vue initで展開すると困る場合は\でエスケープして設定します。

<template lang="pug">
div
  img(src='../images/home.svg')
  p Hello World!
  TestComponent
  {{#isUseStore}}
  p counter
  button(@click="onDecrementButtonClick") -
  //- \{{ $store.state.count }}と書くことで展開後は普通の{{ $store.state.count }}になる
  span(style="padding: 0 10px;") \{{ $store.state.count }}
  button(@click="onIncrementButtonClick") +
  {{/isUseStore}}
</template>

これで対応は出来ますが、テンプレートに書く場合は一々\でエスケープしないといけません。もしVueファイルは展開しないのでしたらmata.jsのskipInterpolationに書くといいです。(interpolationは「内挿」と言う意味らしいです)
ちなみにnode_modulesも書いているのは、ローカルで動作確認するときにnode_modulesも展開の対象になってしまったためです。(普通は必要ないです)

meta.js(一部のみ)
module.exports = {
  // vueファイルやnode_modules以下のものは展開しない
  skipInterpolation: ['src/**/*.vue', 'node_modules/**']
};

余談

mustash記法は別な表記方法で認識させることもできるらしいので、そっちでやると言う方法もありそうです。

mustache記法について簡単にまとめてみた

ローカルで動作確認する

一々githubにあげて試していくのは面倒なのでローカルでインストールする方法を紹介します。
やり方は単純で、テンプレートの場所は相対パスで書くだけでいいです。

ローカルのテンプレートを使用する
$ vue init ./vue-template vue-template-test

作ってみての所感

テンプレートを作ると以降の環境構築は非常に楽になりますが、テンプレートの開発はかなりめんどくさいです。
一々テンプレートを取り込んでみて動くかを確認しないといけないので、結構時間がかかります。
更に条件分岐が入るとエディタもエラーになってかなりコードが書きにくいです。
スクリーンショット 2019-01-08 16.25.00.png

vue initではブランチ名を指定できるので、それぞれ分けて使っていく運用が割と楽なんじゃないかなぁって思っています。

$ vue init TakanoriOnuma/vue-template#vuex vue-template-test

まぁこの場合vuex+vue-routerとか複数のオプションがある場合は対応は厳しいですけど。基本的にカスタムテンプレートではそんなにパターンを用意しないほうがいいんじゃないかなと思っています。

参考資料

既にあるテンプレートを見ると結構参考になると思います。僕もよく分からないことが多かったので参考にしました。(completeの処理とか)

あとは公式ドキュメントですね。

終わりに

vue initと言うコマンドですが、別にVue.jsじゃなくてもReactとかpugをビルドするだけの静的サイトとか、そう言うのでもテンプレートとして作れます。一度作ると使い回すのが凄く楽になるので、似たような環境をよく作る人は試してみてはいかがでしょうか。

9
5
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
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?