Parcelの導入方法 & Docker Alpineで開発環境の立ち上げる手順


2020/08/22

商品ベースにならない社内向けのSPA(シングルページアプリケーション)などのクオリティーを問わないアプリであっても、
webpackを使ってプロジェクトを書き始めるのが前々から気が重く感じ始めている...

なんて症状が出始めている方は私だけではないと思います。

そんなとき、
Parcelを使えば、簡単かつ少ない手順でSPA(シングルページアプリケーション)を起動できることができます。

Parcelで完全にwebpackに置き換わるようなものでもありません。

しかしアプリケーション開発でプロジェクトの中身を事細かくカスタマイズする必要が無い場合には、Parcelを使ったほうが圧倒的に楽ですし、生産性も高まります。

本稿は、簡単なParcelの導入方法と、Alpine Dockerで開発環境を立ち上げる際の注意点に関して解説していきます。


Parcelをとりあえず使ってみる

まずは、公式のチュートリアルに沿って、もっとも簡単なParcelプロジェクトの使い方をやってみます。

Parcelの使い方より、alpine-dockerでのparcelの導入方法を知りたい方は、この節はスキップして後半の内容から読んでみてください。

node環境

Parcelがnpmパッケージで提供されているので、nodeが使えることが大前提です。

とりあえず手元のnode周りでの確認ですが、node/npm/yarnがグローバルインストールされていることを確認してください。

            
            $ node --version
v12.16.1
$ npm --version
6.13.4
$ yarn --version
1.22.0
        

Parcelのインストール

今回はとりあえずプロジェクトが何もないところから初めてみます。

適当な作業フォルダ
my-parcelを作成し、そこに入って作業したとします。

まずはその場所に、
package.jsonを作成しましょう。

            
            $ npm init -y
$ ls
package.json
        
生成されたpackage.jsonの中身は以下のようになっていると思います。

            
            {
    "name": "my-parcel",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT"
}
        
後ほどこれを修正しますが、いまのところはこのままにしておきます。

次は
parcelを導入します。

後半でalpine-dockerにはグローバルインストールすることもあり、公式でもグローバルインストールされているため、

            
            $ npm install -g parcel-bundler
#もしくは
$ yarn global add parcel-bundler
        
とするのをメインに話を進めますが、ローカルでパッケージを利用したい場合には、

            
            $ yarn add parcel-bundler -D
        
としても利用できます。

好ましい方をお使いください。

インストール作業はこれだけです。

インストールされたバーションを確認すると、以下のようになりました。

            
            $ parcel --version
1.12.4
$ parcel --help
Usage: parcel <command> [options]

Options:
  -V, --version               output the version number
  -h, --help                  output usage information

Commands:
  serve [options] [input...]  starts a development server
  watch [options] [input...]  starts the bundler in watch mode
  build [options] [input...]  bundles for production
  info                        Prints debugging information about the local environment
  help [command]              display help information for a command

  Run `parcel help <command>` for more information on specific commands
        

Parcelの基本的な使い方

それではHello world的なプログラムを作成してみます。

以下のように2つのリソースを追加します。

            
            $ touch index.js index.html
$ ls
package.json index.js index.html
        
まずindex.htmlのほうに以下の内容を追加します。

            
            <html>
    <body>
        <script src="./index.js"></script>
    </body>
</html>
        
もうひとつ、index.jsは以下の内容にします。

            
            console.log('hello world');
        
...この程度のプロジェクトではバンドルしなくてもいい気がします。

早速、Parcelでこのアプリをビルドしてみます。

            
            $ parcel index.html
Server running at http://localhost:1234
✨  Built in 359ms.
        
ビルド後に、http://localhost:1234にダイレクトされているのでこのアドレスをブラウザで叩くと、

合同会社タコスキングダム|蛸壺の技術ブログ

となっています。

...もう既にこれだけで最低限のSPAの開発環境が整ってしまいました!

Parcelの最大の特徴のひとつである、自動で必要なリソースを解析してバンドルしてくれる機能は、
webpack.config.jsの呪縛から開放された気分になります。

ともかく、これだけでアプリの開発が進められるわけです。

Parcelでは常時リソースの変更を監視してくれているので、例えばブラウザにサーブ中にも、以下のようにリソースを修正したら、

            
            console.log('hello Parcel!!!!!!!!!!!');
        
この変更が即時反映される仕組みですので、わざわざビルドしなおす手間もありません。

合同会社タコスキングダム|蛸壺の技術ブログ

ちなみに
parcelコマンドはparcel serveコマンドの略記です。

デフォルトでは
distフォルダ以下に生成物が出力されます。

parcel serveした時点で、プロジェクトのファイル構造は以下のようになっていると思います。

            
            $ tree
.
├── dist
│   ├── app.e31bb0bc.js
│   ├── app.e31bb0bc.js.map
│   └── index.html
├── index.html
├── index.js
└── package.json
        

Productionモード

Productionでアプリを出したい場合には、例えば以下のようにビルドします。

            
            $ parcel build index.html --no-source-maps --no-content-hash index.js
✨  Built in 508ms.

dist/index.js      1.11 KB    247ms
dist/index.html       61 B    232ms
Done in 1.13s.
        
ここで、parcel buildが最終的にプロダクションビルドするコマンドになります。

--no-source-mapsオプションはソースマップを出力しない、--no-content-hash <バンドル後のjsファイル>でハッシュ値無しのjsファイルを指定する、というコマンドでなっています。

詳細なコマンドオプションに関しては、
公式のリファレンスを参照してください。


Docker Alpineで開発環境の立ち上げ

parcelの使い方が分かったところで、開発環境ごと持ち出せるようにalpine-dockerで利用できるようにしましょう。

ベースとなるDockerイメージは
node-alpineです。

どのタグバーションを選ぶかはお任せですが、今回は
12.18-alpine3.12を利用してみます。

Dockerfile

まずはDockerイメージを作成します。プロジェクトにDockerfileを追加し、以下の内容に編集します。

            
            FROM node:12.18-alpine3.12
ENV NODE_ENV development
WORKDIR /usr/src/app

#Install dependent packages
RUN apk update && apk upgrade && apk add --no-cache \
    bash git openssh curl

#Installing npm packages
RUN npm i -g parcel-bundler
RUN npm i -g http-server
        

docker-compose.yml

Dockerの操作には、docker-composeを利用していただくと、Docker特有の長めのコマンドを打たなくて済むため、より生産的かと思います。

この記事では既にdocker-composeをインストールされているものとして扱わせていただくと、以下の
docker-compose.ymlをプロジェクトに追加してみます。

            
            version: '3'

services:
  app:
    image: my-parcel:12.18-alpine3.12
    build: .
    user: 'node:node'
    environment:
      NODE_ENV: development
      PARCEL_WORKERS: 1
    ports:
      - 1234:1234
      - 8080:8080
      - 35607:35607
    volumes:
        - ./:/usr/src/app
    tty: true
        
簡単に解説すると、まずdocker-compose上のサービス名は今回appとして定義しています。

ビルド後のDockerイメージは
my-parcelです。

ベースのイメージ名が想起できるようなタグ名(ここでは
12.18-alpine3.12)を付けておくとメンテナンスの時に便利です。

ポートの設定は1234/8080/35607としています。

それぞれ
parcel serve用・http-server用・HMRホスト用です。

HMRポートは任意の番号で構いません。

alpine-dockerでは
lscpuコマンドが標準では利用できないので、環境変数PARCEL_WORKERSを1に設定しておくことで無用なエラーを避けることができます。

次に以下のようにpackage.jsonのスクリプトを追記しておきましょう。

            
            {
    "name": "my-parcel",
    "version": "0.0.1",
    "main": "dist/index.js",
    "scripts": {
        "start": "rm -rf ./dist && parcel serve index.html --hmr-port 35607 --no-cache",
        "build": "rm -rf ./dist && parcel build index.html --no-source-maps --no-content-hash index.js --no-cache",
        "serve": "http-server ./dist -a 0.0.0.0 -p 8080 -c-1"
    },
    "license": "MIT"
}
        
スクリプトを定義しておくことで、yarn start/yarn build/yarn serveからそれぞれ、開発モードでビルド・製品ビルド・ローカルでSPAサーバー起動が操作できます。

今回の最終的なプロジェクトの最低限のフォルダ構造は、

            
            $ tree
.
├── Dockerfile
├── dist
│   ├── index.html
│   └── index.js
├── docker-compose.yml
├── index.html
├── index.js
└── package.json
        
という感じにとてもコンパクトにまとまっていると思います。


まとめ

以上、フロントエンド向けのnode.jsアプリ開発者の強い味方・Parcelの導入手順を簡単に解説してみました。

もしwebpack疲れにお困りの際には、
Parcelの導入を検討してみてはいかがでしょうか。
記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。