いろいろ試そう Parcel 2@beta

# はじめに

去る 2020年6月19日、Parcel v2のベータバージョンがリリースされました。

> [📦 Parcel 2 beta 1: improved stability, tree shaking, source map performance, and more! 🚀](https://medium.com/@devongovett/parcel-2-beta-1-improved-stability-tree-shaking-source-map-performance-and-more-78179779e8b7)

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">🚀 Parcel 2 beta 1 has been released!<br><br>🌳 Improved tree shaking<br>🗺 20x faster source map builds<br>#️⃣ Improved content hashing<br>🚨 Resolver diagnostics<br>📊 More accurate bundle reports<br>🐞 Tons of bugfixes!<br><br>📝 Read more: <a href="https://t.co/hMGtOKEOs3">https://t.co/hMGtOKEOs3</a><br>🌎 New website! <a href="https://t.co/SWaS5OvWIA">https://t.co/SWaS5OvWIA</a></p>&mdash; Devon Govett (@devongovett) <a href="https://twitter.com/devongovett/status/1273685386020024320?ref_src=twsrc%5Etfw">June 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

この記事では、Parcel v2の基本的な使い方から、いくつかのAltJS・ライブラリをParcelでコンパイルするテンプレートについて説明します。

なお、この記事の内容は[`v2.0.0-beta.1`](https://github.com/parcel-bundler/parcel/tree/v2.0.0-beta.1)時点でのドキュメント、ソースコードをベースにしています。
また、無印のParcelを **Parcel v1**、新しいv2を **Parcel v2**と表記します。

# オフィシャルドキュメント

Parcel v1のドキュメントは https://parceljs.org/ でしたが、v2ではURLが代わり https://v2.parceljs.org/ （未完成）がドキュメントとして提供されています。

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/1325d873-e558-d97c-11f4-d246d1740b7b.png)](https://v2.parceljs.org/)
▲ Parcel v2のドキュメント

# インストール

Parcel v1のパッケージは`parcel-bundler`という名前で公開されていましたが、Parcel v2からパッケージ名が`parcel`となりました。

また、現在のParcel v2はベータ版のため、バージョンを`@next`と指定してインストールします。

```shell
$ yarn add -D parcel@next
```

# 設定ファイル

Parcel v2では、`.parcelrc`という設定ファイルを使用できるようになりました。
`.parcelrc`を指定しなかった場合は、デフォルトの設定（[`@parcel/config-default`](https://github.com/parcel-bundler/parcel/tree/v2.0.0-beta.1/packages/configs/default)）でバンドルされます。

`.parcelrc`はParcelのプラグインを種類ごとに設定します。

設定できるプラグインの種類は次のとおりです。

* [Resolvers](https://github.com/parcel-bundler/parcel#resolvers)
  * ファイルやパッケージ、アセットを解決するプラグイン
* [Transformers](https://github.com/parcel-bundler/parcel#transformers)
  * ソースコードを変換（トランスパイル）するプラグイン
  * 公式でBabelやTypeScript、Vue、Yamlなどのトランスフォーマが提供されている
* [Bundlers](https://github.com/parcel-bundler/parcel#bundlers)
  * アセットをバンドルするプラグイン
* [Namers](https://github.com/parcel-bundler/parcel#namers)
  * ファイルの命名やコンテントハッシュなどを付与するプラグイン
* [Runtimes](https://github.com/parcel-bundler/parcel#runtimes)
  * バンドラーフェーズのあとに最終的にバンドルに含まれるアセット（HMRのコードなど）を生成するプラグイン
* [Packagers](https://github.com/parcel-bundler/parcel#packagers)
  * 異なるアセットタイプを単一のバンドルにマージするプラグイン
* [Optimizers](https://github.com/parcel-bundler/parcel#optimizers)
  * バンドルを最適化するプラグイン
* [Reporters](https://github.com/parcel-bundler/parcel#reporters)
  * Parcelでのイベントを受け取ってロガーに出力したり、ログファイルを生成するプラグイン
* [Validators](https://github.com/parcel-bundler/parcel#validators)
  * ビルド後にソースコードの検証を行いエラーを表示するプラグイン

いずれのプラグインも自作が可能ですが、基本的な機能は公式パッケージとして公開されているものを使用すれば問題ないでしょう。

もし、個別の`.parcelrc`を設定する場合はデフォルトの設定に追加する形で定義するとよいでしょう。

```.parcelrc
{
  // デフォルトの設定を継承する
  "extends": "@parcel/config-default",
  "optimizers": {
    "*.{png,jpg}": ["@parcel/optimizer-awesome-images"]
  }
}
```

また、ある拡張子にプラグインを追加する際は、デフォルトの設定を引き継ぐよう`...`を最後に記載するようにしましょう。

```.parcelrc
{
  "extends": "@parcel/config-default",
  "transforers": {
    // デフォルト設定が引き継がれないためコンパイルできない
    "*.{ts,tsx}": [],
    // ... で extends で継承された設定を引き継ぐ
    "*.{ts,tsx}": ["..."],
  }
}
```

# いろいろ試してみよう

ここからは、Parcel v2でいろいろなAltJS、ライブラリをバンドルする設定を見ていきましょう。
それぞれ、GitHubでソースコードを公開しています。

また、公式のリポジトリにも[いくつかのサンプルプロジェクト](https://github.com/parcel-bundler/parcel/tree/v2.0.0-beta.1/packages/examples)が用意されています。

## Pug + Sass

テンプレートエンジンのPugとCSSプリプロセッサのSassを使用したサンプルです。

> [サンプルリポジトリ](https://github.com/lollipop-onl/parcel-v2-playground)

### 開発環境構築

サンプルリポジトリの開発環境構築の手順を紹介します。

ここでは、次の構成でファイルを配置しています。
それぞれのファイルの内容はサンプルリポジトリでご確認ください。

```
.
├── src/
│   ├── index.pug
│   └── styles.sass
└── package.json
```

PugとSassの設定はデフォルトで定義されているため、`.parcelrc`ファイルでの設定は必要ありません。
（[Pugの設定](https://github.com/parcel-bundler/parcel/blob/d24e09a9797af41a9d2c6c733b1c6cf6671d60c7/packages/configs/default/index.json#L21)・[Sassの設定](https://github.com/parcel-bundler/parcel/blob/d24e09a9797af41a9d2c6c733b1c6cf6671d60c7/packages/configs/default/index.json#L13)）

インストールした依存関係は`parcel@next`と次のパッケージです。

```shell
$ yarn add -D pug sass

# reset.css
$ yarn add reset-css
```

ここまでできたら、Parcelで開発サーバーを起動します。
`serve`コマンドは省略できます。

```shell
$ yarn parcel serve src/index.pug
```

ポートを指定していない場合、`http://localhost:1234`で開発サーバーが起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/a3f0eb75-05ae-bbea-13e3-ed95b93b1e55.png)

あとは、Pugファイル、Sassファイルへ変更を加えるとHMRで表示中の内容が入れ替わります。

以上でPugとSassの開発環境ができました！かんたんですね。

### まとめ

* `yarn add -D parcel@next pug sass`
* PugとSassを記述
* `yarn parcel serve src/index.pug`
* http://localhost:1234 を開く

### 余談

Parcelでは、Sassから`node_modules`へインストールされたパッケージをインポートする際、パッケージ名のプレフィックスとして`~`を**必要としません**。

`~package-name`の指定は本来、Webpackでのシンタックスのようで、ParcelのCLI上では次のようにレポートされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/ef44e083-7d92-eca3-d314-cf5739b66912.png)

具体的な理由まで書かれていて、とても親切なエラーメッセージですね！

## React + CSS Modules

React（JSX）とCSS Modulesによるサンプルです。

> [サンプルリポジトリ](https://github.com/lollipop-onl/parcel-v2-playground/tree/examples/react-cssmodules)

### 開発環境構築

サンプルリポジトリの開発環境構築の手順を紹介します。

ここでは、次の構成でファイルを配置しています。
それぞれのファイルの内容はサンプルリポジトリでご確認ください。

```
.
├── src/
│   ├── Hello/
│   │   ├── index.jsx
│   │   └── index.modules.css
│   ├── entry.jsx
│   ├── index.html
│   └── styles.css
├── .postcssrc
└── package.json
```

JSXやCSSのバンドルに関する設定はデフォルトで定義されているため、`.parcelrc`ファイルでの設定は必要ありません。
（[JSXの設定](https://github.com/parcel-bundler/parcel/blob/d24e09a9797af41a9d2c6c733b1c6cf6671d60c7/packages/configs/default/index.json#L5-L8)）

ただし、CSS Modulesを使用するためのPostCSSの設定が必要です。
ここでは、`postcss-modules`パッケージを使用してCSS Modulesを実現しています。

```.postcssrc
{
  "modules": true,
  "plugins": []
}
```

インストールした依存関係は`parcel@next`と次のパッケージです。

```shell
$ yarn add react react-dom prop-types
$ yarn add -D postcss-modules

# reset.css
$ yarn add reset-css
```

ここまでできたら、Parcelで開発サーバーを起動します。
serveコマンドは省略できます。

```shell
$ yarn parcel serve src/index.html
```

ポートを指定していない場合、`http://localhost:1234`で開発サーバーが起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/21e5c1ec-9af4-3df0-21b6-1be0e53b1b89.png)

あとは、JSXファイルやCSSファイルへ変更を加えるとHMRで表示中の内容が入れ替わります。

以上でReactとCSS Modulesの開発環境が構築できました。こちらもかんたんでしたね！

### まとめ

* `yarn add -D parcel@next postcss-modules`
* `yarn add react react-dom prop-types`
* `.postcssrc`に設定を記述
* Reactを記述
* `yarn parcel serve src/index.html`
* http://localhost:1234 を開く

### 余談

今回はプレーンなCSSを使用したCSS Modulesでしたが、JSXファイルから参照するファイルを`.sass`や`.styl`へ変更し、必要なパッケージ（`sass`や`stylus`）をインストールすれば、設定を変更することなくほかのCSSプリプロセッサを使用したCSS Modulesで開発ができます。

## Vue

残念ながら、Parcel v2 beta.1時点ではVueのトランスフォーマプラグインが開発されていません。

開発については次のIssue内で議論が行われています。

[Parcel 2: Vue transformer · Issue #3364 · parcel-bundler/parcel](https://github.com/parcel-bundler/parcel/issues/3364)

状況として、Parcel v2のコアチームにVueを使用するメンバーが少なくSFCの取り扱いについて議論しているようです。

開発が終了し、公開されれば次のように`.parcelrc`に記載すればVueもバンドルできるようになるのではないかなと思います。

```.parcelrc
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.vue": ["@parcel/transformer-vue"]
  }
}
```

## TypeScript + ESLint

TypeScriptとESLintを使用したサンプルです。

> [サンプルリポジトリ](https://github.com/lollipop-onl/parcel-v2-playground/tree/examples/typescript-eslint)

### 開発環境構築

サンプルリポジトリの開発環境構築の手順を紹介します。

ここでは、次の構成でファイルを配置しています。
それぞれのファイルの内容はサンプルリポジトリでご確認ください。

```
.
├── src/
│   └── index.ts
├── .eslintrc
└── package.json
└── tsconfig.json
```

インストールした依存関係は`parcel@next`と次のパッケージです。

```shell
yarn add -D typescript @parcel/validator-typescript @parcel/validator-eslint

# ESLint
yarn add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

TypeScriptの設定はデフォルトで定義されているため、`.parcelrc`ファイルでの必要はありませんが、型をチェックするには別途、バリデータプラグイン`@parcel/validator-typescript`を追加する必要があります。
また、ESLintチェックもTypeScriptの型チェックと同様、バリデータプラグイン`@parcel/validator-eslint`が必要です。

バリデータプラグインを設定した`.parcelrc`ファイルは次のとおりです。

```.parcelrc
{
  "extends": "@parcel/config-default",
  "validators": {
    "*.{js,jsx,ts,tsx}": ["@parcel/validator-eslint", "@parcel/validator-typescript"]
  }
}
```

ここまでできたら、Parcelで`.ts`ファイルをビルドします。

```shell
$ yarn parcel build src/index.ts
```

ソースコードに問題がなければビルドに成功しますが、エラーがあった場合は次のようにCLI上にエラーが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/9804f15b-ea84-5b4a-18b0-5b97d0d71394.png)
▲ 型エラー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127934/4407d9a9-63df-3c8d-8567-bbb34a6bf586.png)
▲ ESLintエラー

なお、ESLintエラーのAuto Fixには対応していないようです。

### まとめ

* `yarn add -D parcel@next typescript eslint @parcel/validator-typescript @parcel/validator-eslint`
* `.eslintrc`にESLint設定を記述
* `yarn parcel build src/index.ts`
* エラーがあればCLI上に表示される

# おわりに

Parcel v2でv1時代より柔軟にオプションを設定できるようになりましたが、設定不要でバンドルできる手軽さも健在です。

まだベータ版ですが、一般的な使い方をする分には申し分ない機能が提供されているなという印象でした。
ただ、新しいツールのため、調べられる情報や公開されているプラグインが少なく真に柔軟に使えるようになるにはまだまだ時間がかかるかなと思います。

2019/8/14にα版が公開されてから10ヶ月、ついにParcel v2も正式リリースの日が近づいてきました。
これからのParcelの発展が楽しみです！