parcel ~ はじめの一歩 ~

## **はじめに**
*明日の有馬記念が気になってしかたないなか、この記事をかいています。この記事は[グロービス Advent Calendar 2017](https://qiita.com/advent-calendar/2017/globis) 23日目の記事です。*

*グロービスでは競馬と日本酒を愛するエンジニアを募集しております。*

## **parcelとは**
近年、フロントエンド開発において、多くの新しい技術が登場してきています。 あまりにも色々でてきて、何をチョイスすればいいのか迷うことも多いと思います。

今回はそんな多くの技術のなかから、新しいタスクランナーとして急速にgithub starを獲得し、注目をあびてきている **parcel**  について書きたいと思います。

ちなみに、タスクランナーとは何かを簡単にいうと、以下のようなものかと思います。

* ファイルの種類ごとにタスクを分けることができる
* タスクの中で色々できる
* ファイルの変更監視ができる

代表的なものとしては、以下のようなものが挙げられます。

* Grunt
* gulp
* webpack

SPAなどフロントエンド開発の比重が大きくなるようなサービス開発では、高機能なwebpack などを使って、設定ファイルをゴリゴリ書いて、いい感じの環境を作成してもいいと思いますが、静的ページや簡単なモックを作りたいといった場合、サクッと用意できる軽量なものを選択したいところです。

そんな時、私は大概タスクランナーとかは使わず、**npm scripts** で済ませています。

ところが、ゼロコンフィギュレーションのタスクランナーで、parcel(パーセル)なるもの (小包という意味) が出てきて、最近話をちょくちょく聞くようになったので、どんなものなのかを知るために使ってみました。

[parcel-bundler/parcel · GitHub](https://github.com/parcel-bundler/parcel)


## **parcelを使ってみる**
parcel本体は、以下のコマンドでインストールすることができます。
`yarn` か `npm`  どちらかのパッケージマネージャーを使用してインストールしてください。

```
$ yarn global add parcel-bundler
$ npm install -g parcel-bundler
```

今回は、以下のような環境を構築します。

* ES6 (Babel)でJavaScriptが書ける
* PostCSS (いくつかプラグイン入れてみる)でスタイルが書ける

Nodeのバージョンは 9.2.0 以上にしておいてください
これしないと、***`Uncaught ReferenceError: require is not defined`*** みたいなエラーがでるかも

あと補足で、parcelはIE11もサポートするようになったようです
[Parcel does not support IE · Issue #230 · parcel-bundler/parcel · GitHub](https://github.com/parcel-bundler/parcel/issues/230)

構成はこんな感じです

```
├── .babelrc
├── .postcssrc
├── package.json
├── yarn.lock
├── node_modules
├── dist
└── src
    ├── styles
    │   └── index.js
    │   └── main.js
    │   └── main.css
    │   └── variables.css
    ├── index.html
    └── scripts
        ├── index.js
        └── main.js
```

parcelの場合、`babel-loader` は必要なく、`.babelrc`を検出すると、自動でES6をビルドしてくれるみたいです。

```
$ yarn init
$ yarn add babel-preset-env
```

`babel-preset-env` は、ES 6 compatibility tableを用いて、サポートされている環境に基づき、必要なBabelプラグインを自動で決定してくれます。
`babel-preset-es2015`  とか、もう入れなくていんですね。

```html:.babelrc
{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["last 2 versions", "safari >= 7"]
      }
    }]
  ]
}
```

Postcssの設定ファイルとして、今回は `.postcssrc` を用意しました。
プラグインとして、以下の４つを入れてみます。

* postcss-modules
* postcss-import
* postcss-nested
* postcss-simple-vars

プラグインの追加は、 `$ yarn add postcss-modules` のようなコマンドで入れるだけです。 追加したら、以下のように `.postcssrc`  に追加しておきます。(オプションからにしちゃってますが、よしなにしてください)

```json:.postcssrc
{
  "modules": false,
  "plugins": {
    "autoprefixer": {
      "grid": true
    },
    "postcss-simple-vars": {},
    "postcss-nested": {},
    "postcss-import": {}
  }
}
``` 

今回は `modules` を `false` にします。

これで環境の構築は完了となります。
次に、簡単に動画が表示されるサンプルを作成します。

まずはエントリポイントとなる HTMLファイルを以下のように準備します。

```html:index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>parcel env</title>
</head>
<body>
  <script src="./styles/index.js"></script>
  <main>
    <h1 id="js-title"></h1>
    <video controls autoplay width="1024" height="640" id="js-video">
      <source src="movies/sample.mp4">
      <p>動画を再生するには、videoタグをサポートしたブラウザが必要です。</p>
    </video>
    <p id="js-time" class="time"></p>
  </main>
  <script src="./scripts/index.js"></script>
</body>
</html>
```

`./styles/index.js`  `./scripts/index.js`   は、其々CSSとJavaScriptのエントリポイントになります。 
h1タグを空にしてますが、今回はサンプルということでこうしてますが、普通はやらないほうがいいです。

```javascript:styles/index.js
import main from './main';

main();
```

``` javascript:styles/main.js
import classes from './main.css';

export default () => {
  console.log(classes.main);
};
```

```css:styles/main.css
body {
  background: var(--background-color);
  width: 100%;
  h1 {
    color: var(--font-color);
    text-align: center;
    margin: 0;
  }
  video {
    width: 960px;
    display: block;
    margin: 0 auto;
  }
  .time {
    text-align: center;
    color: #000;
  }
}
```

```css:styles/variables.css
$white: #fff;
$grey: #333;

:root{
  --background-color: $white;
  --font-color: $grey;
}
```


```javascript:scripts/index.js
import { getVideoTime } from './main';

const TITLE = 'parcel env';

let t = document.getElementById('js-title');
t.innerText = TITLE;

let v = document.getElementById('js-video');
v.onloadedmetadata = function() {
  getVideoTime(this);
}
```

```javascript:scripts/main.js
export function getVideoTime(v) {
  document.getElementById('js-time').innerHTML = v.duration + 'seconds';
}
```


あとは、 `$ parcel src/index.html`  とエントリファイルとなるhtmlを指定してコマンドを実行するだけです。

`package.json` にスクリプトを追加しておきましょう

```json:package.json
"scripts": {
  "start": "parcel src/index.html"
}
```

`localhost:{ポート番号}`   のように、空いているポートを自動で割り当ててローカルサーバーをたち上げてくれます。

もちろん監視もされるので、各種ファイル (HTML, CSS JavaScript)の変更を検知し画面を更新してくれます。

実際に作成したサンプルを、 こちらにアップしておきます。

[GitHub - seikeido/parcel-env](https://github.com/seikeido/parcel-env)



## **まとめ**
すごい簡単にフロントエンドの開発環境を作れるので、 簡易的なモックやLPを作成する際などには、使っていってもいいかもしれない。 (2017年12月時点)。 
サービス開発への導入は、まだはやいと思うので、しばらくは webpackを使う感じになりそう。
シンプルに見えて、本当は複雑なことをやっているきがする。色々やれるようにしていく過程で、結局複雑でイマイチな感じにならないことを祈ります。とりあえず、issueやpullreqは追っていこうと思います。

明日は、さぶちゃんの祭りを聞いて、2017年を締めくくりたい、キタサンブラック軸で馬単ながし