17
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Snowpack+React+Typescriptを公式手順でinitする

Last updated at Posted at 2020-06-19

zennに移行しました: https://zenn.dev/cumet04/articles/snowpack-react-typescript
qiita側の記事を消す予定は特にありませんが、更新することはありません。


趣味でVueを触っている筆者がReactに入門してみたので、調査・実施した初期構築のメモです。
最初はスタンダードにcreate-react-appしていたのですが、Vueのviteのスピード感を体験していたためwebpack環境に我慢できず、snowpackを使うことにしました。

参考までに、以下の内容を実施したリポジトリです: https://github.com/cumet04/snow-react-ts-init

はじめに; 参考

本記事と同様にSnowpack + React + Typescriptな環境を作る記事として

などがあり、これらでは利用するreactパッケージの指定やimportパス、babelのプラグインなどを設定していますが、本記事執筆時点ではsnowpack公式のCreate Snowpack App (CSA)が存在しており12非常に簡単に入門できるようになっています。

初期公開後追記:
上記参考記事はSnowpack v1の頃の話で、本記事で対象にしているCSAはSnowpack 2.0のリリースとともに公開されたもの、ということのようです。

また本記事ではSnowpackとはなにか・そもそも何をしているのか等は一切気にせずスッとinitするだけに留まるため、そのあたりの背景が気になる方は上記参考記事、また後者の筆者の方が2.0について書かれた下記を参考にするとよいと思います。

ひとまずinitする

Create Snowpack Appを使ってプロジェクトを作成します。
公式手順の通りですが、ここではReact + Typescriptなので以下のようになります:

npx create-snowpack-app {プロジェクト名} --template @snowpack/app-template-react-typescript

実行すると

  • カレントディレクトリに{プロジェクト名}のディレクトリが作成される
  • 上記ディレクトリ下にテンプレート一式が展開され、initial commitが打たれる
  • npm installが実行される

状態になります。
作成されたディレクトリ下でnpm startするとsnowpackのdevサーバが起動します。

なお、この時点で何もせずともHot Reloadが有効です。src/App.tsxあたりを編集すると即時反映されるかと思います。

TypeScriptについて

create時にテンプレとしてtypescriptを指定しておけば、特に何もせずとも.ts(.tsx)が使えます。
本記事はタイトルにTypescriptと入っていますが、特別な操作は不要なためこれ以降tsの話はありません。

またdevサーバ実行時やビルド時にはtsc --noEmitが走るようになっており、型チェックの面でもデフォルトのままで安心です。

(一部WSLユーザのみ)devサーバが起動するようにする

筆者がそうなのですが、WSLユーザかつWSL内のPATHにWindowsのもの含めないようにしていた場合、この初期状態ではdevサーバが起動しません。
これはcreate-react-appと同じ問題で、あちらでは起動コマンドにBROWSER=noneを足すと解決するのですが、snowpackの場合は起動コマンドに--open noneを足すことで解決できます。

package.json
{
  "scripts": {
-    "start": "snowpack dev",
+    "start": "snowpack dev --open none",
    "build": "snowpack build",
    "test": "jest",
    "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",

commit: https://github.com/cumet04/snow-react-ts-init/commit/f0561178cf73f0da0fc43822439d581f86bb3a38

postcssを動かす

プロジェクト内のcssでPostCSSが機能するようにします。

公式手順の通りなのですが、postcss-cliパッケージの追加・snowpack.config.jsonへの追記を行えばよいです。
postcssの設定は特に特殊なことはなく、postcss.config.jsでもpackage.jsonでも好きなところに記述できます。

snowpack.config.json
{
  "extends": "@snowpack/app-scripts-react",
-  "scripts": {},
+  "scripts": {
+    "build:css": "postcss"
+  },
  "plugins": []
}

下記commitでは、動作テストとしてpostcss-nestingを追加しAppのcssを変更しています。
commit: https://github.com/cumet04/snow-react-ts-init/commit/ef9ba8f7513738362dc5204c29cf4ef852010483

CSS Moduleする

cssをscopedに書きたいのでCSS Moduleします。

こちらは特に作業は必要なく、ファイル名を変更してそのまま使えます
commit: https://github.com/cumet04/snow-react-ts-init/commit/49684b94d31fd3b8940984519edd9f9f41a275e0

bundleなproduction buildする

snowpackはasset bundleを行わないため、デフォルトではproduction buildでも全ソースが別個のファイルになります。

bundleしたい場合、公式手順としてはwebpackを使うプラグインが提供されているため2、これを使います。
その場合は@snowpack/plugin-webpacknpm installsnowpack.config.jsonに下記追記します:

snowpack.config.json
  "scripts": {
    "build:css": "postcss"
  },
-  "plugins": []
+  "plugins": [["@snowpack/plugin-webpack", {}]]
}

commit: https://github.com/cumet04/snow-react-ts-init/commit/92e15f7bba7b9c72e95c59594f94ca15b074136c

この状態でnpm run buildすると、bundleされた状態のビルドが出来上がります。

(おまけ)@octokit/request (node-fetch) を使う

別の個人プロジェクトで@octokit/restを使うとしたところ、node-fetchパッケージのNode built-inパッケージの問題に当たりました。
通常、公式のトラブルシューティングにあるようにrollup-plugin-node-polyfillsを使うなどすればよいのかもしれませんが、この場合はrollupのplugin-node-XXXを色々試しても解決できませんでした。

そこで「SPAだしブラウザでしか動かさないわけでnode-fetch使わず普通のfetchでよくない?」という発想の元、node_modules内の@octokit/requestのソースを直接書き換えることにしました。

lib/patch.sh
#!/bin/bash

set -eu
cd $(dirname $0)/..

file="node_modules/@octokit/request/dist-web/index.js"
before=$(cat $file)
sed -i 's|^import nodeFetch|//import nodeFetch|' $file
sed -i 's|^\s*const fetch|//const fetch|' $file

# display changed lines
echo "$before" | diff - $file

commit: https://github.com/cumet04/snow-react-ts-init/commit/0aeb3d8449b65ce5c476abbffd65eb884fe82688

fetchを使うところが抽象化されてまとまっていたため、node-fetchのimportとfetchの定義書き換え部分をコメントアウトするだけとなっています。

ゴリ押し解決のためnode-fetch以外のNode built-inパッケージ問題には適用できませんが、同じようなハマり方をしているかたの参考になれば。

※もっと真っ当な方法で対応&実際に動作する方法があればご教示いただけると。。。

まとめ

基本的なところは公式が提供してくれており、ぶっちゃけ公式ドキュメントの紹介みたいになってしまいました。

まだこれでちゃんとしたプロダクトを書いたわけでは全くなく、特殊なユースケースでは難しいこともあるかもしれませんが、これらの基本的なところは安心の公式手順で楽しめそうです。

  1. create-snowpack-appのinitial commitは4/22となっており、参考記事執筆時には存在しなかったようです

  2. 後日追記: Snowpack 2.0としてCSAが公開されたかたちなのですが、初期執筆時に筆者がそのあたりの経緯を知らなかった(CSAがおもむろに登場したと思っていた)ため文章の表現に少し違和感があるかもしれません 2

17
16
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?