React

React TypeScript で flexWrap、flexDireciton がエラー: CSSProperties を指定して回避

皆さまこんにちは、ウチイダです。

表題の件でエラーに遭遇したので、対策をメモしておきます。

環境

  • React 18.2.0
  • Typescript 4.9.3
  • @types/React 18.0.26
  • Vite 3.2.5

事象

CSS in JS でスタイルを記述した際、flexWrapを含んだオブジェクトを変数に格納してから、style 属性に渡すとエラーが出ます。

style 属性にそのままオブジェクトを書いた場合はエラーになりません。

export const FlexStyleError = () => {
	const elementStyle = {
		flexWrap: 'wrap'
	};

	return (
		<>
			<div style={{ flexWrap: 'wrap' }}>これはセーフ</div>
			<div style={elementStyle}>オブジェクトで渡すとエラー</div>
		</>
	)
}

エラーメッセージはこんな感じ。flexWrapの値として、string 型は渡せないよ~と言われてます。

Type '{ flexWrap: string; }' is not assignable to type 'Properties<string | number, string & {}>'.
  Types of property 'flexWrap' are incompatible.
    Type 'string' is not assignable to type 'FlexWrap | undefined'.ts(2322)
index.d.ts(1869, 9): The expected type comes from property 'style' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'

ちなみに、flexDirection でも同じエラーが起こります。

原因:csstype の型定義が使えてないから?

flexWrap とflexDirection には、それぞれFlexWrap と FlexDirection という専用の型があります。

  export type FlexWrap = Globals | "nowrap" | "wrap" | "wrap-reverse";

指定の文字列リテラルのUnion型として定義されていて、オブジェクトに渡した内容が正しく型を認識できてないぽいです。

解決方法:推論に任せず指定する

原因は分かったけど、よい解決策がわかりません。

というわけでエラーメッセージで検索したら、GitHubでissue が立っていました。

flexDirection is not assignable to CSSProperties 

まさにこれだ~と思いながらレスを追っていくと、いくつか対策が書かれていました。

要するに、型推論がちゃんとされなくてエラーになっちゃってるので、明確に指定すれば大丈夫ということです。

個人的には、styleに渡すオブジェクト全体に、React.CSSProperties を指定するのがいいかなと思いました。

flexDirection 以外のプロパティで問題が出ても、対処できそうです。

export const FlexStyleError = () => {
	// const elementStyle = {
	// React.CSSProperties 型を指定
	const elementStyle: React.CSSProperties = {
		flexWrap: 'wrap'
	};

	return (
		<>
			<div style={{ flexWrap: 'wrap' }}>これはセーフ</div>
			<div style={elementStyle}>オブジェクトで渡すとエラー</div>
		</>
	)
}

エラーも出なくなったし、そのうえ、プロパティのヒントも出してくれるように!

ReactCSSProperties を型指定することで、ヒントが正確に出る

CSS in JS を使うときは、型指定するとよい感じにプロパティが書けそうです。

以上です。

あなたのお役に立てればうれしいです。

Vite で自動ビルドしたい – build に –watch オプションをつける

皆さまこんにちは、ウチイダです。

React とともに、firebase を本格的に触り始めています。

React + firebase で開発速度を上げて、小規模の開発を効率化できないかな~と試行錯誤しています。

firebase の エミュレータがとても充実しているということを最近知りました。便利です。

今回はその中で調べたことをメモしておきます。

firebase hosting のエミュレータが修正を反映しない

ソースコードを修正して、hosting エミュレータのURLを開いても変更が反映されません。

よくよく考えれば当たり前なんですけど、「hosting のエミュレータ」なので、ビルド済みの静的ファイルを読み込んでいるんですよね。

hosting のエミュレータで修正内容を反映するには、ソースコード修正後は一度ビルドしてデプロイ用のファイルも更新しないといけません。

Vite でローカル環境を動かしていたので、つい忘れていました。

Vite のビルドを自動で実行する

とはいえ、毎回手動でビルドのコマンドを実行するのは面倒です…

ソースコードを修正して保存したら、自動でビルドを実行してもらいたいです。

というわけで結論から。以下のコマンドで、Vite(の内部で動いてるRollup)を、watch モードで実行することができます。

$ npx vite build --watch
vite v3.2.2 building for production...

watching for file changes...

build started...
✓ 974 modules transformed.
# ... 省略 ...
built in 7582ms.

公式サイトには言及が少ないですが、

vite build --watch で rollup のウォッチャを有効にすることができます。

本番環境用のビルド | Vite

と書いてありました。

https://ja.vitejs.dev/guide/build.html#ファイル変更時のリビルド

Vite コマンドのヘルプにも、オプションの一覧に載っていました。

$ npx vite build --help
vite/3.2.2

Usage:
  $ vite build [root]

Options:
# ... 省略 ...
  -w, --watch                   [boolean] rebuilds when modules have changed on disk 
  -c, --config <file>           [string] use specified config file 
  --base <path>                 [string] public base path (default: /) 
  -l, --logLevel <level>        [string] info | warn | error | silent 
  --clearScreen                 [boolean] allow/disable clear screen when logging 
  -d, --debug [feat]            [string | boolean] show debug logs 
  -f, --filter <filter>         [string] filter debug logs 
  -m, --mode <mode>             [string] set env mode 
  -h, --help                    Display this message

npm script にも、build:watch として 登録しておきました。

{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "build:watch": "vite build --watch",
    "preview": "vite preview"
  },
}

まとめ

ビルド処理には少し時間かかってしまいますが、毎回手でコマンド実行するよりははるかにいいですね。

基本的にはHMRが使えるVite サーバ上で作業して、hosting エミュレータ上で動作確認・微調整をする際にwatch モードで自動ビルドさせようと思います。

以上です。あなたのお役に立てれば幸いです。

ESLint の初期設定時、Airbnb のスタイルガイドが選択肢に表示されない – 手動インストールする

みなさんこんにちは、ウチイダです。

最近フロントエンドをきちんと学ぼうと思って、Reactのキャッチアップを進めています。

せっかくなのでTypeScriptで開発するようにしているのですが、その際の環境構築でつまづくことがあったので書き留めておきます。

環境

  • Windows 11 21H2
  • WSL2 Ubuntu20.04
  • Node.js v18.12.0
  • npm 8.19.3

事象:Airbnbのスタイルガイドを選択できない

JavaScriptのスタイルガイドとしてポピュラーなものに、Airbnb が作成しているものがあります。

これをESLintでのチェックに利用しようと思いました。

ESLint を導入する際、以下のコンフィグファイルの初期化コマンド を実行します。

$ npm init @eslint/config 

手順を説明しているページなどを見ると、スタイルガイドの選択時にAirbnbが出てくるようだったのですが、ウチイダの環境だとそれが表示されませんでした。

選択肢が2つしか表示されない

原因:AirbnbのスタイルガイドがTypeScriptに対応していないため

初期設定を行うコマンド eslint-config で行われた修正が原因でした。

ここで、TypeScriptに標準で対応していないスタイルガイドを表示しないように変更されていました。

https://github.com/eslint/create-config/pull/33

自分の作業手順漏れを疑っていたのですが、仕様変更だったんですね。。。

ちなみに、これは最近参加しているコミュニティの方が調べて教えてくれました。感謝!

対応:手動でAirbnbのスタイルガイドを追加する

自動でインストールしてくれないのは仕方ないので、とりあえずeslintrc の生成を済ませて、あとからAirbnbのスタイルガイドを読み込ませるように設定していきます。

1. eslintrc を生成する

スタイルガイドでStandard を選択して、設定を進めます。

次に「依存パッケージをインストールするか」を聞かれるので、no を選んでおきます。

Standardのスタイルガイドのパッケージを後から削除するのであれば、yes でもよいです。

$ npm init @eslint/config
✔ How would you like to use ESLint? · style

✔ What type of modules does your project use? · esm

✔ Which framework does your project use? · react

✔ Does your project use TypeScript? · No / Yes

✔ Where does your code run? · browser

✔ How would you like to define a style for your project? · guide

✔ Which style guide do you want to follow? · standard-with-typescript

✔ What format do you want your config file to be in? · JavaScript

Checking peerDependencies of eslint-config-standard-with-typescript@latest
Local ESLint installation not found.
The config that you've selected requires the following dependencies:

eslint-plugin-react@latest eslint-config-standard-with-typescript@latest @typescript-eslint/eslint-plugin@^5.0.0 eslint@^8.0.1 eslint-plugin-import@^2.25.2 eslint-plugin-n@^15.0.0 eslint-plugin-promise@^6.0.0 typescript@*

✔ Would you like to install them now? · No / Yes

A config file was generated, but the config file itself may not follow your linting rules.
Successfully created .eslintrc.cjs file in /home/y-uchiida/develop/eslint_airbnb_none

2. Airbnb のスタイルガイドのパッケージを追加する

npm で、スタイルガイドのパッケージを導入します。

Airbnb のTypeScript のスタイルガイドは本家の設定の拡張なので、本家も含めてインストールします。

$ npm install --save-dev eslint-config-airbnb eslint-config-airbnb-typescript

3. eslintrc にスタイルガイドを読み込ませる

eslintrc を編集して、Airbnb のスタイルガイドを読み込みさせます。

    "extends": [
        "plugin:react/recommended",
        // "standard-with-typescript" // standard スタイルガイドは使わないので消す
        'airbnb', // 追加
        'airbnb-typescript' // 追加
    ],

ちなみに、Reactのプロジェクトかそうでないかによって、利用するパッケージが違うので注意が必要です。

詳しくはGitHubのREADMEをご確認ください…

https://github.com/iamturns/eslint-config-airbnb-typescript#setup

まとめ

ESLintの初期設定を自分でやったことがなかった&比較的最近の変更で、見つかる情報と齟齬があった(Airbnbが出てくると書いてあるものが多かった)ことでハマってしまいました。

ツールチェイン周りのキャッチアップは大変です…

ちなみに、ウチイダと同じ疑問を持った人がGitHubでissueを立てていました。

やり方を覚えてしまえばなんてことはないですが、手作業インストールするのちょっとだけ面倒ですね…

上記のissueの中で、「将来的に –config オプションを実装する予定があるので、それができたら簡単になるよ」といった旨のコメントがついていました。

https://github.com/eslint/create-config/issues/35#issuecomment-1216457480

早く利用できるようになるといいですね。

それでは以上となります。あなたのお役に立てれば幸いです。