Parcel2（Parcel@next）を使ってTypescript + SCSS環境を構築する

フロントエンドで試したいコードがあるが、わざわざ環境を整えるのは煩わしい。そんな時に活用したいのが「Parcel」です。

[parcel\-bundler/parcel: 📦🚀 Blazing fast, zero configuration web application bundler](https://github.com/parcel-bundler/parcel)

Parcelを使えば、簡単な設定で、すぐにコードを書き始められる環境を立ち上げることができます。

この記事ではParcelを使って、TypeScriptとSCSSの開発構築を行う方法とその注意点を解説します。

## Parcelをインストール

最初にディレクトリを作成し、そこにParcelをインストールします。

```shell
$ mkdir sampleProject
$ cd sampleProject

$ yarn init
$ yarn add -D parcel@next
```
parcelのインストールが出来たら、各ファイルを作成していきます。

## index.htmlを作成

まずはディレクトリのTOP階層にに`index.html`を用意します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Parcel Test</title>
</head>
<body>
  <h1 class="sample">Parcel Test</h1>
</body>
</html>
```

`index.html`の中身は何でも大丈夫ですが、後ほどここにSCSSやTSを読み込んでいきます。

## SCSS（Sass）を利用できるようにする

### 「@parcel/transformer-posthtml」をインストール

まず最初に以下をインストールします。
（現状はこれがないと、バンドル時にエラーが発生します）

```shell
$ yarn add -D @parcel/transformer-posthtml
```

### SCSSファイルを作成

「src/style」ディレクトリ配下に、エントリーポイントとなる`app.scss`と`_sampple.scss`を作成します。（もちろんディレクトリ名は何でも大丈夫です。）

```scss
// src/style/app.scss

@import "./sample";
```

```scss
// src/style/_sample.scss

.sample {
  color: blue;
}
```


### index.htmlからscssファイルを読み込む

ここまでできたら、先ほど作成した`index.html`から`app.scss`を読み込みます。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Parcel Test</title>
  <link rel="stylesheet" href="./src/style/app.scss">
</head>
<body>
  <h1 class="sample">Parcel Test</h1>
</body>
</html>
```

これだけで準備は完了です。

## Parcelを使ってバンドル

次に以下のコマンドを実行します。
`index.html`が依存している各ファイルが読み込まれ、「dist」ディレクトリにバンドル後のファイルを出力してくれます。

```shell
$ yarn parcel index.html

yarn run v1.22.10
$ /Users/xxx/sandbox/sampleProject/node_modules/.bin/parcel index.html
Server running at http://localhost:1234
Built in 1.78s
```

コマンドを叩いてビルドが上手くいくと、自動的にローカルサーバーも立ち上がります。

※この時、バンドルするために必要なビルド用のモジュールも、Parcelが検知して勝手にインストールしてくれます。（「sass」など）

この時点ではHMRは効いていませんが、`index.html`に対して、JS（TS）を読み込むことでHMRが効くようになります。


### 変更が反映されない場合

ブラウザを更新しても変更が反映されない場合、Parcelのキャッシュが影響している可能性があります。自動生成されている「.parcel-cache」ディレクトリを削除して、再度Parcelコマンドを実行してみてください。

それでも改善されない場合、以下のようにキャッシュを無効にするオプションを渡すと良いかもしれません。（自身の環境では、この方法で改善されました）

```shell
$ yarn parcel index.html --no-cache
```

## TypeScriptを利用できるようにする

### .tsファイルを作成

まずは「src/ts」ディレクトリ配下に`app.ts`を作成します。

```ts
// src/ts/app.ts

let test: string = 'test'
console.log(test)
```

### TSファイルを読み込む

作成したtsファイルを、`index.html`から直接読み込みます。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Parcel Test</title>
  <link rel="stylesheet" href="./src/style/app.scss">
</head>
<body>
  <h1 class="sample">Parcel Test</h1>
  <script src="./src/ts/app.ts"></script>
</body>
</html>
```

これで一旦準備ができたので、先ほどと同様に以下のコマンドを実行します。

```shell
yarn parcel index.html
```

開発サーバーが立ち上がり、読み込んだTSファイルを実行できていることが確認できると思います。

TS（JS）ファイルを読み込むと、HMRも効くようになります。SCSSファイルだけを読み込んでいる状態では、手動でブラウザを更新する必要がありましたが、今回はリアルタイムで更新が反映されるようになっているはずです。

かなり簡単にTSの環境構築も済んだように思えますが、実はこれだけでは不十分です。

[Parcel TypeScript](https://v2.parceljs.org/languages/typescript/)

上記の公式ドキュメントに記載されていることなのですが、このままでは `tsconfig.json` を使うことができず、型のチェックも行われていません。

試しにstring型にnumber型を代入しても、そのまま動いてしまいます。次はそこを改善していきます。（基本的にはドキュメント通りにやっていきます）


### tsconfig.json を使えるようにする

まずは`tsconfig.json`を使えるようにするために、`@parcel/transformer-typescript-tsc`をインストールします。

ここで注意なのですが、普通にインストールしようとするとalpha版がインストールされて上手く動きません。nightly版をインストールする必要があります。

以下のコマンドでインストール可能なバージョンを確認することができるので、nightly版のバージョンを確認してインストールするようにしてみましょう。

```shell
$ yarn info @parcel/transformer-typescript-tsc versions

$ yarn add -D @parcel/transformer-typescript-tsc@2.0.0-nightly.488
```

次にディレクトリのTOP階層（package.jsonと同階層）に `.parcelrc` というファイルを用意します。以下のように記述することで `tsconfig.json` が使えるようになります。

```json
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
  }
}
```

### alpha版をインストールした場合

alpha版をインストールした場合は「Error: Unexpected token 'export'」というエラーが出てしまいます。

```shell
/Users/xxx/sandbox/sampleProject/node_modules/@parcel/ts-utils/src/index.js:2
export * from './FSHost';
^^^^^^

SyntaxError: Unexpected token 'export'
....
....
```

このバグはnightly版で修正されているため、現状はnightly版を使う必要があるようです。

参考：
[Unexpected Token export while trying to use tranformer\-typescript\-tsc on Parcel 2 nightly · Issue \#4627 · parcel\-bundler/parcel](https://github.com/parcel-bundler/parcel/issues/4627)


## 型エラーが発生するようにする

コンパイル時に型エラーを発生させるには、`@parcel/validator-typescript` を使います。こちらもalpha版だと動かないため、nightly版をインストールするようにします。

```shell
yarn add -D @parcel/validator-typescript@2.0.0-nightly.488
```

インストールが完了したら、先ほど作成した `.parcelrc` に対して以下のように追記します。

```json
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
  },
  "validators": {
    "*.{ts,tsx}": ["@parcel/validator-typescript"]
  }
}
```

また、`tsconfig.json`の`include` オプションを指定してない場合は、合わせて指定しておく必要があるので注意しましょう。

```
{
  "include": ["src/**/*"]
}
```

以上で完了です。これで型チェックが通らなければ、エラーが発生するようになります。


## まとめ

動作が不安定なところもあるため、実務で使うのは難しい印象ですが、それでも簡単な設定でコードを書き始められるので、個人利用においては重宝するのではないかと思います。

Paracelでは、今回紹介した以外にも色々なことができるので、気になる方はドキュメントもチェックしてみてください。

<a href="https://v2.parceljs.org/">Parcel</a>

ドキュメント通りにやって上手く動かないような場合には、issueを確認してみると良いかもしれません。