Next.js 14 と microCMSで作る俺得RSSリーダー：開発編その2, Sass環境構築

## 過去の記事一覧

https://qiita.com/unotame/items/87c148154f2f581c980d

https://qiita.com/unotame/items/50a7fedfc0f2c4589aea

https://qiita.com/unotame/items/72669e069741a57385c0

今回はSassの開発環境整理をしていきます。

## Sass環境構築

### dart-sass

dart-sassをnpm経由でインストール

https://github.com/sass/dart-sass


```
$ npm i sass
```

### typed-scss-modules

CSS modulesを使う時にほぼ必須となるパッケージのインストール
（cssを書いた時の型を自動的に定義してくれる便利パッケージ。）

https://github.com/skovy/typed-scss-modules

```
npm i -D typed-scss-modules
```

```typed-scss-modules.config.ts```ファイルを作成。
以下記述。

```typed-scss-modules.config.ts
export const config = {
  exportType: 'default',
  nameFormat: 'none',
  implementation: 'sass',
  
  //グローバルファイルの指定(絶対パス)
  additionalData: `@use "src/public/styles/global.scss" as *;`,

  //ignoreの指定
  ignore: ['**/global.scss']
}
```

:::note warn
```ignore: ['**/global.scss']```を書かないと、```Module loop: this module is already being loaded.```のエラーがでます。
:::

### npm-run-all

```typed-scss-modules```を使用するときは ```$ npx typed-scss-modules src```を実行する必要がある。
```--watch```オプションでホットリロードに対応しているそうなので、せっかくなら```$ npm run dev```で一気に起動したい

ということで、複数のscriptを直列または並列的に起動できる```npm-run-all```パッケージを導入することになる。

https://github.com/mysticatea/npm-run-all

↑を導入すると、```run-s```で直列, ```run-p```で並列的に実行できるとのこと。

インストール
```
$ npm i npm-run-all
```

やりたいことは ```npm run dev```で ```next dev -p 2405``` と ```typed-scss-modules src```を並列的に実行したい。

ということでpackage.jsonを編集

```diff:package.json
{
    "script":{
-       "dev": "next dev -p 2405",
+       "dev": "run-p dev:next dev:scss",
+       "dev:next": "next dev -p 2405",
+       "dev:scss": "typed-scss-modules src --watch",
    }
}
```

これでOK。

### 実際にsassを書いてみる

```tsx:src/app/layout.tsx
import type { Metadata } from "next";
import "@/public/styles/destyle.css"
import "@/public/styles/global.scss"

export const metadata: Metadata = {
  title: "RSS reader",
  description: "ワタシのワタシによるワタシのためのRSSリーダー",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja" id="html">
      <body>
        <div className="l-inner">
          {children}
        </div>
      </body>
    </html>
  );
}

```

```scss:src/public/styles/global.scss
:root {
  --c-primary: #0a0a0a;
}

@mixin sp {
  @media screen and (max-width: 768px) {
    @content;
  }
}
@mixin ov-pc {
  @media screen and (min-width: 1367px) {
    @content;
  }
}

#html {
  font-size: calc(10 / 1366 * 100vw);

  @include sp {
    font-size: calc(10 / 375 * 100vw);
  }
  body {
    font-size: 1.6rem;
    overflow-x: hidden;
    padding-top: 10rem;
  }
}

.l-inner {
  width: 72%;
  margin-inline: auto;
}
```

```tsx:src/app/page.tsx
import styles from './FrontPage.module.scss'
import { client } from '@/libs/client'

type RSS = {
  title: string
}

export default async function Home() {
  const data = await client.get({
    endpoint: 'rss',
  })

  return (
    <main className={styles['p-front-page']}>
      <ul className={styles['p-front-page__list']}>
        {data.contents.map((rss: RSS) => {
          return (
            <div className={styles['p-front-page__list__item']}>
              <h2 className={styles['p-front-page__list__item--title']}>
                {rss.title}
              </h2>
            </div>
          )
        })}
      </ul>
    </main>
  )
}
```


```src/app/FrontPage.module.scss
.p-front-page {
  $this: &;
  height: 120rem;

  &__list {
    display: flex;
    align-items: center;
    gap: 1.5%;
    &__item {
      width: 32%;
      padding: 1rem;
      border-radius: 1rem;
      box-shadow: 0 0 1rem #ddd;
      &--title {
        font-size: 2rem;
      }
    }
  }
}

```

結果：
![スクリーンショット 2024-05-20 19.58.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2531585/f26144de-29c3-58f3-ca32-30174e3ec5e1.png)

global.scssも効いているし、FrontPage.module.scssも問題なく効いている。
これで開発環境はバッチリ。

一旦ここまででpush。
（.scss.d.ts拡張子を持つファイルはgitignoreで指定しています。）

https://github.com/mkrms/rss-reader/commit/636c77c070ec1cc2c1f4a31d7cedf449df6862b0

## 次回予告
次回はページ・コンポーネントの作成を一気にやっていきます。
ちなみに、今回以降のスタイルコードは省略していきます。（長くなりそうなので...）

一気にプロトタイピングしていくぞ〜〜。

## 案件のご依頼・ご相談について
ワタシが運営するUNOTAMEでは、制作案件やPM業務の外部委託案件などを承っております。
少しでも興味のある方はぜひカジュアルにお話しさせていただけますと嬉しいです。

[Twitter(X)](https://x.com/NiiyamaKeisuke)のDMや下記ポートフォリオサイトからのお問い合わせ、お待ちしております。

https://unotame.com/