maesblog

2018年注目のビルドツール「Parcel」について

前回の記事『フロントエンドの2017年の振り返りと2018年の展望』で触れましたが、今年流行るのではと言われているツールのひとつに「Parcel」が挙げられます。いわゆるビルドツール(バンドラー)です。「設定ファイルがいらない」という強烈なコンセプトを打ち出し、フロントエンド界に旋風を巻き起こしつつあります。私も実際に使ってみましたが、とても使い勝手が良く、使えるツールだと思いました。今回は、このParcelについてざっくりですが、使い方などを紹介したいと思います。

はじめに – ビルドツールの現状

まずビルドツールの現状について振り返っておきます。ビルドツールと言えば、様々なものが出回っていると思いますが、やはり元祖と言えるのが魔法の杖と呼ばれたBrowserifyでしょう。require()で読み込むNode.jsのモジュールをブラウザでも読み込めるようにし、さらにモジュールの依存関係を解決し一つのファイルにしてくれるこのBrowserifyはフロントエンドの開発スタイルを大きく変えるきっかけとなったツールのひとつと言っても過言ではありません。

その後登場したのがWebpackで、ほぼほぼBrowserifyと同じような用途で使用するものではありましたが、SCSSに対応していたり、複数のエントリーポイントを指定できたり、HMR(Hot Module Replacement)に対応していたりと機能が充実していて、gulpのようなタスクランナー代わりにもなるということでシェアを拡大し、今では一人勝ち状態となってきています。Browserifyの影はだいぶ薄くなってきているような気がします。

ただWebpackは高機能であるが故、あれもこれもとやり出すと設定ファイル(webpack.config.js)があっという間にカオス状態に陥りやすいです。途中からプロジェクトに参加した人は全てを把握するのに一苦労するし、途中で設定ファイルを弄るとなるとかなり神経質になります。こう言ったところから「Webpack疲れ」という言葉まで出てきているのが現状です。

こうした現状を受けて登場したのが「Parcel」となります。

📦 Parcelとは

ParcelはAdobeのエンジニアDevon Govett氏が中心になって開発が進められています。2017年12月6日にv1.0.1がリリースされています。その最も大きな特徴は「設定ファイルを必要としない」ことです。つまり余計な設定を行ったりやプラグインをインストールしたりすることなく、JSやCSS、HTMLなどのトランスパイルやビルドが行えるようになっています。さらにWebpackでお馴染みのHMRやCode Splitingが自動で行えるようになっています。

上述したように、Webpack疲れの主な原因がカオス化しやすい設定ファイルということですから、そうした反省を踏まえてコンセプトが練られているのでしょう。

parcel
📦 Parcel

また、Parcelはビルドの高速化が図られています。マルチコアプロセッサを利用してコードを並列にコンパイルし、初期ビルドの速度を大幅に向上させているとのことです。また、キャッシュを備えており、ファイルごとにコンパイルされた結果を保存することで、次からの起動を速くしているとのことです。Parcelのサイトに既存のビルドツールと比較したベンチマークの記載がありますが、以下のようにParcelは断トツで速いです。

parcel_benchmarks
ベンチマーク

私も実際に使い始めていますが、やはり使い勝手が良いなという印象です。よく使うであろう機能が、何の設定なしで使えるのは嬉しいですね。わざわざ毎回設定するのは正直面倒ですから。すごくエンジニアのことを考えて作られているなと思います。

こうしたコンセプトが受け入れられて、GitHubのスター数もリリースから約2ヶ月で「19,235」となっています(2018年2月17日現在)。

Parcelの使い方

それでは、Parcelの使い方を紹介していきます(主にParcel v1.5.0の内容となります)。上述したように設定が必要のないツールなので、基本はインストールとコマンドの実行のみとなります。

Parceをインストールする

グローバル(システム)にインストールする場合は以下のコマンドを実行します。

# yarn
$ yarn global add parcel-bundler

# npm
$ npm install -g parcel-bundler

プロジェクトディレクトリにインストールする場合は以下のコマンドを実行します。

# yarn
$ yarn add --dev parcel-bundler

# npm
$ npm install --save-dev parcel-bundler

ファイルを準備する

例えば以下のようにファイルを準備します。

index.html
src/
 ┣━ app.js
 ┗━ app.css

HTMLファイルでは、それぞれjsファイルとcssファイルを読み込むようにします。もちろんjsファイルはいくつかのモジュールをimportしているものとします。

<!doctype html>

<html>
  <head>
    <meta charset="utf-8">
    <title>Parcel</title>
    <link rel="stylesheet" href="./src/app.css">
  </head>
  <body>
    <h1>Hello World</h1>
    <script src="./src/app.js"></script>
  </body>
</html>

Parcelを実行する

エントリーファイルを指定して(ここではindex.html)、parcelコマンドを実行します。

# グローバルから実行する場合
$ parcel index.html

# プロジェクトディレクトリから実行する場合
$ npx parcel index.html

ポイントは、エントリーファイルを指定するだけということです。parcelコマンドを実行すると、依存関係のあるファイルが全てバンドルされた状態で、distディレクトリに出力されます(distディレクトリは初回実行時に自動生成されます)。

さらに、自動的にポート番号が付与されたWebサーバーが起動します。HMR(Hot Module Replacement)にも対応しているので、parcelコマンドを1回実行したら、その後は何もせずにファイルを更新する度に変更を検知し、ビルド結果をブラウザに反映してくれるようになります。

出力結果

parcelコマンド実行後のdistディレクトリの中は以下のようになっています。ソースマップファイルも同時に生成されています。

dist/
 ┣━ 03f20d8b5ab7499921e86c67dfb8af48.js
 ┣━ 03f20d8b5ab7499921e86c67dfb8af48.css
 ┣━ 03f20d8b5ab7499921e86c67dfb8af48.map
 ┣━ 158b1a02bfa5c40b538bea410a823170.js
 ┣━ 158b1a02bfa5c40b538bea410a823170.map
 ┗━ index.html

出力されたhtmlファイルの中身は以下のようになっています。

<!doctype html>

<html>
  <head>
    <meta charset="utf-8">
    <title>Parcel</title>
    <link rel="stylesheet" href="/dist/03f20d8b5ab7499921e86c67dfb8af48.css">
  <script src="/dist/03f20d8b5ab7499921e86c67dfb8af48.js"></script></head>
  <body>
    <h1>Hello World</h1>
    <script src="/dist/158b1a02bfa5c40b538bea410a823170.js"></script>
  </body>
</html>

Parcelの基本的な使い方はこんな感じです。parcelコマンドを叩く以外何もしなくて良いことがわかるでしょう。

Parcelのオプション

上記の通り、Parcelは余計なことは何もせずに利用することができますが、状況により自分の開発スタイルに沿って利用したい場合もあるかと思います。その場合はparcelコマンドのオプションを使います。よく使いそうなオプションをいくつか紹介します(プロジェクトディレクトリにインストールしたParcelを使用する場合は、頭にnpxをつけてください)。

parcelコマンドを実行すると自動的にポート番号が付与されてWebサーバーが起動しますが、-pオプションを使うと、任意のポート番号を指定することができます。

$ parcel index.html -p 8888

parcelコマンド実行時に、自動的にブラウザを起動して内容を表示してくれると便利です。openオプションをつけてparcelコマンドを実行するとそれが可能です。

$ parcel index.html -p 8888 --open

逆にParcelによるWebサーバーは起動せずに、ファイルの更新検知とビルドのみを行いたい場合は、watchをつけてparcelコマンドを実行します。

$ parcel watch index.html

上記ではエントリーファイルとしてhtmlファイルを指定していましたが、JavaScriptのみParcelにビルドしてもらいたい時などにjsファイルをエントリーファイルに指定するなど任意のファイルを指定することも可能です。

$ parcel ./src/app.js

トランスパイル

BrowserifyやWebpackでは、トランスパイルする場合は別途プラグインをインストールする必要がありますが、Parcelでは一般的なトランスパイラについては最初からサポートされています。例えばBabelであれば、.babelrcファイルがプロジェクトディレクトリ内にあれば、自動的にbabelでトランスパイルするようになっています。トランスパイルについては以下のような対応となっています。

Babel

BabelはES2015+のコードを一般的なブラウザで動くJavaScriptに変換するためのトランスパイラです。.babelrcファイルがプロジェクトディレクトリに含まれていた場合、自動的にトランスパイルします。Babelを使用する場合は、以下の準備が必要です。

babel-preset-envをインストールします(以下はyarnでインストールする場合)。

yarn add babel-preset-env

.babelrcファイルを作成し、以下を記述します。

{
  "presets": ["env"]
}
.babelrc
2月15日にリリースされたParcel v1.6.0から.babelrcが必要なくなり、ES2015+をトランスパイルするために何も設定する必要がなくなりました。デフォルトでbabel-preset-envが使われるようになったようです。ただし、package.jsonbrowserslistまたはengines.nodeフィールドを使って任意のものにオーバーライドできるようです。

TypeScript

TypeScriptはJavaScriptに静的型付けやクラスベースのオブジェクト指向を加えたスーパーセットです。Parcelでは特に何も設定する必要がなくTypeScriptのJavaScriptへのトランスパイルが可能です。

HTMLファイルにtsファイルを読み込むだけで、自動的にトランスパイルされます。

<html>
  <body>
    <script src="./src/app.ts"></script>
  </body>
</html>

直接tsファイルをエントリーファイルとしてparcelコマンドを実行してもよいです。

$ parcel ./src/app.ts

SCSS

SCSSはCSSのメタ言語です。CSSをプログラミング的に書くことができます。ParcelはSCSSのコンパイルにも対応しています。

node-scssをインストールしておけば、SCSSのコンパイルを自動で行ってくれます。

$ npm install node-sass

postCSS

postCSSは、autoprefixercssnextCSS Modulesなどのプラグインを使用してCSSを変換するためのツールです。ParcelでPostCSSを使用するには、.postcssrc(JSON)、.postcssrc.js、またはpostcss.config.jsのいずれかのファイル名で設定ファイルをプロジェクトディレクトリ内に作成することで、自動的にpostCSSでのトランスパイルが実行されます。

autoprefixerを使用する場合は、postcss-modulesとautoprefixerをインストールします(yarnでインストールする場合)。

$ yarn add postcss-modules autoprefixer

.postcssrcファイルを作成し、以下を記述します。

{
  "modules": true,
  "plugins": {
    "autoprefixer": {
      "grid": true
    }
  }
}

プラグインは、pluginsオブジェクトのkeyとして指定し、オプションはvalueに定義します。プラグインにオプションがない場合は、trueと指定します。それから、CSS Modulesの場合は指定方法に若干例外があるようです。詳細はParcelの公式ドキュメントでご確認ください。

postHTML

postHTMLは、postCSSと同じようにプラグインを使用してHTMLを変換するためのツールです。ParcelでPostHTMLを使用するには、.posthtmlrc(JSON)、posthtmlrc.js、またはposthtml.config.jsのいずれかのファイル名で設定ファイルをプロジェクトディレクトリ内に作成することで、自動的にpostHTMLでのトランスパイルが実行されます。

post-img-autosizeを使用する場合は、まずpost-img-autosizeをインストールします(yarnでインストールする場合)。

$ yarn add posthtml-img-autosize

.posthtmlrcファイルを作成し、以下を記述します。

{
  "plugins": {
    "posthtml-img-autosize": {
      "root": "./images"
    }
  }
}

プラグインは、pluginsオブジェクトのkeyとして指定し、オプションはvalueに定義します。プラグインにオプションがない場合は、trueと指定します。

プロダクションビルド

プロダクション版をビルドする機能ももちろん備わっています。

プロダクション版をビルドする場合は、buildをつけてparcelコマンドを実行します。

$ parcel build entry.js

HMRは無効となり、全てのファイルがミニファイされた状態で./distディレクトリ内にビルドされます。ミニファイに関しては、JavaScriptはuglify-es、CSSはcssnano、HTMLはhtmlnanoが使われるということです。

プロダクション版の出力先はデフォルトだと./distとなっていますが、以下のオプションで任意の出力先を指定することもできます。

$ parcel build entry.js --out-dir build/output

# または

$ parcel build entry.js -d build/output

public-urlオプションを使うと、任意のPublic URLを指定することもできます。デフォルトはpout-dirで指定したものとなっています。

$parcel build entry.js --public-url ./

ミニファイさせたくない場合はpno-minifyオプションを使用します。

$ parcel build entry.js --no-minify

キャッシュさせたくない場合は、pno-cacheオプションを使用します。

$ parcel build entry.js --no-cache

Reactの開発環境を作ってみる

最後にParcelを使ったReactの開発環境の構築方法を紹介します。

まずは、必要なパッケージをインストールします。

$ yarn add react
$ yarn add react-dom
$ yarn add --dev parcel-bundler
$ yarn add --dev babel-preset-env
$ yarn add --dev babel-preset-react

.bablercファイルを作成し、以下を記述します。

{
  "presets": ["env", "react"]
}
.babelrc

package.jsonファイルのscriptsにコマンドを登録します。

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

package.jsonファイルに登録したコマンドを実行します。

$ npm start

これでReactの開発環境の出来上がりです。簡単ですね。

2月15日にリリースされたParcel v1.6.0からJSXをサポートするようになり、さらに.babelrcも必要なくなったため、デフォルトでReactに対応するようになりました。もちろん何か後で機能を使いしたい場合は、.babelrcを使用することも可能だということです。

まとめ

ざっくりParcelの公式ドキュメントに書かれていることをまとめてみました。設定ファイルが必要ないとは言え、コマンドベースとなっているので、状況によっては多くのコマンドを使うことになりそうです。その場合は、必要に応じてpackage.jsonに登録していくことになるでしょう。

まだリリースされて2ヶ月足らずの新しいツールですが、次から次へと機能が追加されている模様です。かなり進化が早いです(この記事を書いている最中に、大幅に仕様が変わるほどです)。ユニットテストなどにも対応してくれたら、かなり使えるツールになるのではないでしょうか。実際に私も使い始めていますが、特にTypeScriptを書く時などはかなり重宝しています。大型案件でも使えることがわかれば、大流行するのではないでしょうか。今後の動きを注目していきたいですね。ちなみにWebpackもPercelのこうした動きに影響を受けたのかゼロコンフィグ(設定ファイルなし)の道を模索し始めているようです。それぞれのツールの今後の進化が楽しみですね。

この記事を書いている最中に、Parcel v1.6.0がリリースされました。上記で追記したように、ES2015+のトランスパイルに.babelrcが必要なくなったり、Reactがデフォルトでサポートされたり大幅なアップデート内容となっています。詳細は以下をご参照ください。

コメント

  • 必須

コメント