Parcelのv1は現在は古いのでv2を使用したほうが良い

Parcelとは

ParcelとはWebアプリケーションバンドラでマルチコア処理を利用した高速パフォーマンスで開発環境を作成することができる。

現在はv2がリリースされているがv1との互換性はないため、いまから使用する場合は最新バージョンを使用したほうが良いだろう。

ちなみにParcelで検索して表示される日本語の公式サイトはv1の情報なのでv2の情報は英語の公式サイトで確認する必要がある。(2021年11月現在)

Parcel 公式サイト(日本語)

Parcel 公式サイト(英語)

parcel-bundlerをアンインストール

Parcelのparcel-bundlerは現在deprecated(非推奨)となっているため、もし過去にインストールしている場合は以下のコマンドでアンインストールしたほうが良いだろう。

これがインストールされていると間違えてv2ではくv1で実行してしまう事故が発生しやすい。

yarnの場合

yarn global remove parcel-bundler

npmの場合

npm uninstall -g parcel-bundler

Parcelの環境構築手順

使い方はまず適当なディレクトリを作成してcdで移動後、parcelをインストールする。

mkdir my-parcel
cd myparcel
npm init -y
npm i -D parcel

parcelのインストールが完了したらsrcのディレクトリを作成する。

mkdir src

index.htmlを作成して以下のようなHTMLファイルをsrcディレクトリ内に入れる。

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Hello world!</title>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>

次にnpm startでブラウザ起動しやすいようpackage.jsonを以下の内容に変更する。

{
  "name": "my-parcel",
  "source": "src/index.html",
  "scripts": {
    "start": "parcel --open",
    "build": "rm -r ./dist/; parcel build"
  },
  "devDependencies": {
    "parcel": "latest"
  }
}

以上の手順が完了していればnpm startを実行するだけでブラウザで表示される。

sourceが複数ある場合は配列で"source": ["src/index.html", "src/index2.html"]と指定する。

ホットリロードが有効になっているのでHello world!をHello Japan!などに変更して上書きすると即座にブラウザの表示にも反映される。

buildされたHTMLのhrefやsrcは / から始まるため、もし / を除去したい場合は--public-url ./ のオプションが必要。

"build": "rm -r ./dist/; parcel build --public-url ./"

CSSとJavaScriptを読み込むには

CSSとJavaScriptを読み込むにはlinkタグおよびscriptタグを使用する。

scriptタグはtype="module"を付けるとビルド時にtype="module"に対応したJSファイルと対応していないJSファイルの2ファイルが書き出されるので必ず付けたほうが良い。

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Hello world!</title>
<link rel="stylesheet" href="styles.css">
<script type="module" src="app.js"></script>
</head>
<body>
<h1>Hello world!</h1>
</body>
</html>

styles.cssとapp.jsはindex.htmlと同じくsrcディレクトリに入れて以下のようにする。

h1 {
  color: red;
}
console.log('Hello world!')

この状態でnpm startを実行している状態で確認するとHello world!のテキストが赤くなり、ブラウザのConsoleにはHello world!と表示されることが確認できる。

.scssファイルを読み込む

Sassを使って.scssファイルを読み込みたい場合はCSSの拡張子を.scssにするだけで利用できる。

<link rel="stylesheet" href="styles.scss">

特にSassをインストールするためのコマンドの実行や設定などをしなくてもそのままSassなどが使用可能なのがParcelの特徴の1つとなっている。

Autoprefixerの使用方法

Autoprefixerの使用するには.postcssrcファイルを用意して以下のコードを保存する。

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

.postcssrcを保存したらpackage.json内のbrowserslistにAutoprefixerの対象となる条件を記載すればAutoprefixerによるベンダープレフィックスの自動付与が有効となる。

{
  "name": "my-parcel",
  "source": "src/index.html",
  "browserslist": "> 1%, last 2 versions, not dead",
  "scripts": {
    "start": "parcel --open",
    "build": "rm -r ./dist/; parcel build"
  },
  "devDependencies": {
    "parcel": "latest"
  }
}

TypeScriptの使用方法

TypeScriptは.jsを.tsにして読み込むだけで使用できる。

<script type="module" src="app.ts"></script>
const str:string = 'Hello world!'
console.log(str)

jQueryの使用方法

まず「npm i -D jquery」でjQueryをインストールする。

npm i -D jquery

あとはJavaScriptファイル内でimportでjqueryを読み込むようにすれば使用可能となる。

import $ from 'jquery'

$(function() {
  console.log('Hello world!')
})

VueやReactなども同様に使用する際はnpmでインストールしてimportで読み込めば使用可能。

CSS内の画像をdata URLに変換

CSSの画像読み込み時にurlの先頭にdata-url:を付けるとdata URLに変換することができる。

h1 {
  padding-left: 30px;
  background: url(data-url:rss.png) no-repeat left center;
  background-size: 24px 24px;
  color: red;
}
/* ビルド後 */
h1{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAABIFBMVEX%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FfAH%2FsGf%2Funn%2FhRP%2FljT%2FvX%2F%2Fy5n%2FfgT%2Fky7%2Fgg3%2Fmz3%2FoUn%2Fp1X%2FqVj%2FgQr%2Fhxb%2Fu3z%2Fihz%2FwIT%2FxpD%2FyJP%2FkCj%2F1Kv%2F5cz%2F6NL%2F69j%2F7dv%2F9%2FD%2F%2BfP%2F%2Bvb%2F%2F%2F%2F%2FlTH%2Ffwf%2Fzp%2F%2F1a7%2F17H%2F2rf%2F4sb%2Ft3P%2FuHb%2Fkiv%2F%2FPn%2Fqlv%2F8OH%2Fz6L%2FhBD%2FyZb%2F8eT%2F9Or%2F9u3%2Fo0z%2FpE%2F%2FrF7%2FwYf%2FxI3%2Fs23%2FtXD%2FrWH%2F0aX%2F0qj%2Fix%2F%2FjSL%2FmTr%2F2LT%2Fsmr%2Fn0b%2F7t7%2FjiX%2FnED%2FnkP%2F6dX%2FiBn%2FzJz%2F5s%2F%2Fw4r%2F%2Ffz%2F38AU7TLoAAAAE3RSTlMAAxUYJEtUV1pdlq60yczP5%2Br8%2BcY7KQAAAdlJREFUeF6Vltdy4zAMRekk9u5G9q6j6t57772k9769%2F%2F9fZEhACUdOKPE%2BXXB4RiAADkWo%2FLshVXORGtr1E9CWonmUskWBnbDmWeFtQnwfNQkphLzXpPSOBOWAINmTA8IETU%2FXz6y4O6DagNFl%2BlnV78UED6AaRkECAK3vJIHuomR6BlAtI%2BsZQDXmIuCXZS310qjFEx1dAKBiqfIhhxTFACo5fiF%2Bx8QAyqo9EweCM%2BQ45HPnOStBlf7VyukExvOGTWTEZW0PcAL3%2F9srFbc%2B3MIoZR8xrsXcGtdOwzfqGM%2FcO33OiG9HmFTBfTRGbJB%2BLCCKvlrWpJ6fcAdhq0Wc3cImgFi%2BbRN5GicwqdLbnTYHNnHCGgj%2BOCsYDR0TP6Sb%2Bk0I0gJA%2B4KEQYMlFkEEaNeYh0nbB4fq9F8BUpG%2FGVgfAhGhHs%2BU3ABy7BbUK6xjkFSTyymyAVTxIrN6RCGgc5jDvjiBhy4%2FOD3wl9R%2FZfaPE5jaQJWFK%2BbX1I6h2TExcMP8hNoyrOfeSmnKwgjzK26eKjwAX4Y9cEevWNDi5jjuBMwhltUJzDYB1HejeNpHn4pSXYBlwglXpZ8s%2BUfxg%2Byz6%2FskAyjSvw7SPyegQNBDrfaCAbr3CVq09FuT99xRAAAAAElFTkSuQmCC) no-repeat 0;background-size:24px 24px;color:red;padding-left:30px}

コードが読みにくくなるので個人的にはdata URLの変換は推奨しない。

画像をWebPやAVIFに変換

ParcelではJPGを用意してpictureタグのsourceタグでsrcsetの語尾に?as=avifや?as=webpを付けると自動的に画像をWebPやAVIFに変換したものを書き出してくれる。

そのため別途srcフォルダ内にWebPやAVIFのファイルを別途用意する必要がない。

<picture>
  <source type="image/avif" srcset="image.jpg?as=avif">
  <source type="image/webp" srcset="image.jpg?as=webp">
  <img src="image.jpg" width="750" height="500" alt="">
</picture>

この状態でデベロッパーツールで確認するとChromeの場合、ファイルサイズが一番軽いAVIFで読み込んでいることがわかる。

画像のファイルサイズはAVIF: 21.9KB, WebP: 45KB, JPG: 81KB です。

Chromeデベロッパーツールで確認

ちなみに書き出し後に同じJPG画像が2つあるが、これはファイル削減前のものがdistに残るため。(仕様)

CSSでも同様に?as=で変換可能。

.sample {
  background: url(image.jpg?as=webp);
}

Pugの使用方法

Parcelでpugを使用したい場合はindex.htmlをindex.pugのように拡張子を変更するだけで使用できる。

doctype html
html(lang="ja")
  head
    link(rel="stylesheet", href="styles.scss")
  body
    h1 Hello world!
    script(type="module", src="app.js")

.pugrcの設定ファイルを用意して以下のように変数をpug内に反映することもできる。

{
  "locals": {
    "name": "world"
  }
}
h1 Hello #{name}!

ただし、.pugrcの内容はキャッシュの影響で正しく反映されないことがあるので、その場合は「--no-cache」が必要になる。

{
  "name": "my-parcel",
  "source": "src/index.html",
  "browserslist": "> 1%, last 2 versions, not dead",
  "scripts": {
    "start": "parcel --open --no-cache",
    "build": "rm -r ./dist/; parcel build --no-cache"
  },
  "devDependencies": {
    "parcel": "latest"
  }
}