Parcelを利用して簡単Vue-Element-UI実装

# 注意！
この記事古いのでインストール方法が変わってます！
本記事ではnpmインストールするパッケージをごちゃごちゃ書いていますが、以下だけで動くようになった模様。([公式参照](https://parceljs.org/recipes.html#vue))

```
npm install --save vue
npm install --save-dev parcel-bundler
```

以下から執筆当時の記事。環境構築は古いけど実装は今でも問題ないです。

# はじめに

最近名前を聞くようになったparcel。
（詳しくは 「[webpack時代の終わりとparcel時代のはじまり](https://qiita.com/bitrinjani/items/b08876e0a2618745f54a)」「[Parcel 入門 ～Parcelはwebpackの代わりになるのか～](https://qiita.com/soarflat/items/3e43368b2d767c730781)」 など参考）

こちらを利用してVueで最も(?)人気のあるElement-UIを使ったWebページを実装してみよう思い立ったのでやってみました。
（本当は設定ファイルが不要なParcelでVue + typescript の記事にしようと思ってたけど時間がなくて断念したのは内緒です。今度本格的に挑戦します。ちょっとだけ文末に触れています。）

あと、私自身node周りのことやvue.js初心者なのでツッコミがあったらお願いします。
ちなみに今回の環境はWindows10となります。

# 成果物

公開しています。
https://github.com/mastar3104/parcel-vue-element

# 作業手順

すでにParcelの実行方法は記載されているページが多く出てきていますが改めて1から。

### **parcelのインストール**
```
npm i -D parcel-bundler
```  

ちなみにparcelでは `async function` を利用しているのでnodeのバージョンが古いとコケると思います。私は最初node6の仮想環境で試したらこけました。現在は8.9.3でやってます。


### **vue.js その他もろもろのインストール**
```
# jsコンパイルのお供 babel。インストールするだけでparcelが良しなに設定してくれる
npm i -D babel-preset-env babel-preset-vue

# Vue本体とElement-UI
npm i -D vue element-ui

# parcelコンパイルプラグインとそのお供
npm i -D parcel-plugin-vue  vue-template-compiler
```

parcel は設定ファイルが不要！というのがウリっぽいので、plugin系もインストールするだけでよしなにビルドしてくれます。
上記でインストールしている[`parcel-plugin-vue`](https://github.com/lc60005457/parcel-plugin-vue)は、単一ファイルコンポーネントをビルドできるようにするpluginらしいです。

現状では複雑なことができないparcelですが、これからplugin系が増えていき、どんどん発展していくのではないかと思います。（複雑なことができすぎて結局parcel疲れにならないことも祈ります。。）

### **ファイルの実装**

今回は簡単にデートピッカーがでるサンプルを実装してみました。
私自身Element-UIの実装が初めてだったので、[こちらのサイト](https://s8a.jp/vue-js-library-element)を参考にさせていただきました。

```src/index.html
<html>
<head>
  <meta charset="utf-8">
  <title>Parcel Vue-Element Tutorial</title>
</head>
<body>
  <h1>Parcel Vue-Element</h1>
  <div id="app">
  </div>
  <script src="js/app.js"></script>
</body>
</html>
```

```src/js/app.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/ja'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App.vue'

Vue.use(ElementUI, {locale})

new Vue(App).$mount('#app')
```  

```html:src/js/App.vue
<template>
  <div id="app">
    <el-date-picker v-model="datetime" type="datetime" placeholder="日時を選択してください"></el-date-picker>
  </div>
</template>

<script>
  module.exports = {
    name: 'app',
    data () {
      return {datetime: ''}
    }
  }
</script>
```

### **parcelの実行**

```
npx parcel src\index.html
```

実装はこれだけ！簡単！とおもったら

```
src\js\App.vue: Unknown plugin "transform-runtime" specified in "base" at 0, attempted to resolve relative to ....
```

はい。`.bablerc`にvueの記述をしていませんね。。
いくら設定ファイルなし！といってもそれはバンドラであるparcelの話であって、利用するコンパイラの設定は普通に必要です。（当たり前）

というわけで

```json:.bablerc
{
  "presets": [
    "vue"
  ]
}
```

これで再実行。  

```  
npx parcel src\index.html

⏳  Building...
Server running at http://localhost:1234
✨  Built in 19.40s.
```

これで`http://localhost:1234`へアクセスすると

![vue-element.png](https://qiita-image-store.s3.amazonaws.com/0/185345/ded90aa5-6a9c-ffa2-3d0e-5cd3996e1eb7.png)

こんな感じです。

ちなみに参考サイトと実装が多々変わっている部分があるかと思いますが、それは
```
Failed to mount component: template or render function not defined.
```
とか
```
found in anonymous component - use the "name" option for better debugging messages.
```
に悩まされた結果です。。

こちらの情報に助けていただきました。[Vue.js 2 アップデートメモ](https://qiita.com/tmiame/items/34823b22cd3829321120)


### **Parcelについての感想**

本当に新しいツールで、まだまだこれからという感じがします。私がglupを知ったころにはwebpackがあり、webpackを使い始めた頃にはwebpack疲れエンジニアが続出していたりだったので、parcelとは始まりから向き合っていけそうな時期に知れてよかったです。
設定ファイルなしという分、制約に癖があるのでどこまで受け入れられていくのか、有志によってどこまで進歩していくかがポイントだと思います。



### おまけ（parcel + typescript + vue について）

冒頭で書いた、本当はこっちにしたかったというお題ですが、ほんの少しは一応触ってみました。
vue2.5からtypescriptとの親和性が厚くなり、型宣言狂信者には朗報だと思います。
従来の(?)webpack + vue + typescript だと、tsconfig.jsonのほかにwebpack.config.jsの設定等もいろいろ必要でしたが、parcelであればbabelのように勝手にtsconfig.jsonを呼んでくれますし、もちろんparcel自体の設定も不要です。

#### 触ってみた内容

##### typescriptのインストール
```
npm i -D typescript
```

##### ファイルの実装

```src/indexts.html
<html>
<head>
  <meta charset="utf-8">
  <title>Parcel Vue Typescript Tutorial</title>
</head>
<body>
  <h1>Parcel Vue Typescript</h1>
  <div id="app">
    <a href="#" v-on:click="log">クリック</a>
  </div>
  <script src="js/test.ts"></script>
</body>
</html>
```

```src/js/test.ts
import Vue from 'vue/dist/vue.esm.js'

let vue = new Vue({
  methods : {
    getMsg() : string {
      return 'msg';
    },
    log() : void {
      let msg = this.getMsg();
      console.log(msg);
    }
  }
}).$mount('#app')

```

で`indexts.html`をエントリポイントにすると問題なくビルドされ、開発サーバが動きました。
とっても簡単。

ただ、単一コンポーネントにした際は、いろいろ試したのですがまだうまくいかず、苦戦中です。。。

ちなみにts(jsでも同様)の1行目が`import Vue from 'vue'`だと、`You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.`というエラーに悩まされます。
詳しくは勉強中ですごめんなさい。この辺が参考になると思います。（[【公式】さまざまなビルドについて](https://jp.vuejs.org/v2/guide/installation.html#%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%93%E3%83%AB%E3%83%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)）


かなりタイトルから脱線しました。。。。



### まとめ

これからもparcelとvue.jsの進化に期待しています。