【初学者向け】TypeScript/Next.jsにStorybookなど開発環境を構築する時や開発時に出会った「なんで？」「これなに？」のまとめ

npmでpackage.jsonにモジュールを追加してinstallを繰り返す過程でエラーが起こった時の対処方法を紹介します。

私の場合は表題のとおり、TypeScript/Next.js、Storybookを入れて開発しようとしたところエラーが発生して環境を構築するのに時間がかかってしまいました。

今後どこかで困るかもしれない方のためのTipsとして残しておきます。

:::note info
【こんな方にオススメ】
・これからTypeScriptやNext.jsを勉強する
・Storybookをこれから勉強する
・TypeScriptやNext.js、Storybookのエラーに現在苦しんでいる
:::

学習の手助けになれば幸いです。

## 環境設定編
### node_moduleの依存関連で怒られた時はとりあえず消して、再インストールしてみる
`node_modules`と`package-lock.json`を削除して`npm install`を実行してみてください。
これで直ることもあります。

`package.json`に下記のように`^（ハット）`が指定してある場合は、一番左のバージョンを更新せずに変更が行われます。

```
 "hogehoge": "^8.3.0",
```

バージョンを変えない範囲でよしなにインストールしてくれるので動いてくれる可能性もあります。
それでも動かない場合はアップデートしていきましょう。


```javascript
npx npm-check-updates
```

無事開発環境を立ち上げることができました。

## TypeScript編
## importする時のファイルパスを絶対パスで指定したい
コンポーネントを作成するときに下記のように絶対パスで指定したいところです。
相対パスだと冗長的で非常にわかりづらいです。
```js
// 絶対パス
import Text from 'Components/atoms/Text';

// 相対パス
import Text from '../../../components/atoms/Text';
```

ただ、この書き方をするには`tsconfig.json`の`compilerOptions`に設定を追加する必要があるます。
```diff_javascript
{
  "compilerOptions": {
+    "baseUrl": "src"
  },
}
```
`"baseUrl": "src"`を指定することで`src`からのパスで記述することができるのでシンプルになります。

## Storybook編
### exportで定義しているのにエラー表示が消えない…
キャッシュなのか何が原因かよくわからない…定義しているのにないと言われている場合は一度処理を止めてもう一度`npm run storybook`することで直りました。

:::note info
さっきまで大丈夫だったのに…という時は一度立ち上げ直してから原因を調査する方が効率的だと思います！
:::

### Storybookを立ち上げようとしたらエラー出た`Error: error:0308010C:digital envelope routines::unsupported`

導入した時は動いたはずなのにいつの間にか立ち上がらなくなってしまった…。
エラー文を確認するとその中の一文に下記のような文がありました。
```javascript
at NormalModule._initBuildHash (/Users/akiratanimoto/dev/nextjs-app/node_modules/@storybook/builder-webpack4/node_modules/webpack/lib/NormalModule.js:417:16)
```

あれ？webpack5でビルドしているはずなのに…と思いつつ色々調べると`.storybook/main.js`に下記の記述を追加することで正常に動くようになりました。

```diff_javascript
module.exports = {
+  core: {
+    builder: 'webpack5'
+  },
}
```

### 急にStorybookのControlsが表示されなくなった！？
僕の場合はエラーではなく、ただ表示を消してただけだったので`D`キー（ショートカット）を押すことで画面右側に再表示されます。

ターミナルやStorybook上でエラーが起こっていない場合はショートカットコマンドを使ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/5c7ec927-ed2e-c354-ee96-23261d64d168.png)

## Storybookで画像が表示されない…
`.Storybook`配下にpublicディレクトリを作成しその中に配置した画像を表示したいと思いましたがエラーにはならないけど画像が表示されない現象に出会いました。

こちらの記事を参考にしました。

https://qiita.com/miyawa-tarou/items/3f6166e7b617634e6a1c

Next.jsで画像をサポートする時は設定が必要なようです。

`./storybook/main.js`には下記の設定がされていることが前提です。

```javascript:.storybook/main.js
staticDirs: ['public'],
```

```diff_javascript
+ import * as nextImage from 'next/image';

+ Object.defineProperty(nextImage, 'default', {
+  configurable: true,
+  value: (props) => <img {...props} />
+ });
```

上記の記述を追加したら一度環境を落として、再度`yarn storybook`を実行すると無事表示されました。

### stories.tsxに記述はしているはず…だけどControlsの項目に反映されない…

argTypesには記述したけどControlsに反映されない状態でした…。
本来は下記のように表示してほしかったです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/4309e206-80fd-1f94-6002-67c9afa28e9a.png)

けど実際は下記のように表示され、なぜだ…となっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/6311821d-b266-5c5c-09d4-d6f639a16cb4.png)

:::note alert
結論。ただの脱字でした…
:::

```diff_javascript:index.stories.tsx
- argType: { 
+ argTypes: {
}
```

エラーにならずに表示されてしまったことで、見つけるのに少し時間がかかりました…。

## styled-components
### スタイルの拡張
styled-componentsは引数に既に定義したコンポーネントを渡すことで渡したコンポーネントを拡張する記法ができる。

```jsx
const Text = styled.p`
  font-size: 1.4em;
  font-weight: bold;
`;

const AlertText = styled(Text)`
  color: red;
`;
```

importしてきたコンポーネントも引数に渡すことができます。
```jsx
import Text from 'components/Atoms/Text';

const AlertText = styled(Text)`
  color: red;
`;
```