Next.js×TypeScript×CSS Modules×Sass×sass-mq
2022-04-23
導入にかなり苦戦したのですが、ようやく納得の行く形で組めたので書いていこうと思います。
前提
- src 以下に格納 で書いていますが、ルート直下でも動作確認済みです
実装
breakpoints.scss
まずはブレークポイント(src/styles/breakpoints.scss
)をば。
$breakpoints: (
vga: 640px,
svga: 800px,
xga: 1024px,
uxga: 1600px,
);
今回はわかりやすく書くために、すべて上書きしています。
mq-settings.scss
つぎに設定ファイル(src/styles/mq-settings.scss
)です。
@use "styles/breakpoints" as *;
$show-breakpoints: (vga, svga, xga, uxga);
@use "sass-mq" with (
$breakpoints: $breakpoints,
$show-breakpoints: $show-breakpoints
);
mq.scss
大事なルートファイル(src/styles/mq.scss
)となります。
@use "styles/breakpoints" as *;
@forward "sass-mq" with (
$breakpoints: $breakpoints
);
ここで forward
を使えば良いことにやたら時間を取られました…。
_app.tsx
Next.js でブレークポイントの表示の出し分けを行います。
import type { AppProps } from "next/app";
if (process.env.NODE_ENV !== "production") {
require("styles/mq-settings.scss");
}
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
export default MyApp;
本番環境では表示したくないので、動的にインポートを行うようにしています。
next.config.js
webpack を介して Sass の設定を上書きします。
const path = require("path");
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
sassOptions: {
additionalData: async (content, { resourcePath }) => {
if (resourcePath.endsWith("mq-settings.scss")) {
return content;
}
return "@use 'styles/mq' as mq;" + content;
},
includePaths: [path.join(__dirname, "src/styles")],
},
};
module.exports = nextConfig;
当初 additionalData
でなく prependData
で実装していたのですが。
prependData
の場合はパスによる出し分けが行えないようです。(Next.js の仕様?)
*.module.scss
てきとうな CSS Modules ファイルになります。
.hoge {
@include mq.mq($until: xga) {
color: red;
font-size: 3rem;
}
@include mq.mq($from: xga) {
color: blue;
font-size: 4rem;
}
}
今回は next.config.js
で src/styles/mq.scss
を読み込むようにしているので、そのまま mixin が書けるようにしています。
もちろん設定側で @use
の処理を省いて、都度 @use "styles/mq" as mq
と書いて読み込んでも問題ないです。
tsconfig.json
最後に TypeScript でスタイルシートの絶対パスによる読み込みを行えるようにしてあげます。
{
"compilerOptions": {
...
"baseUrl": "src",
...
"paths": {
"styles/*": [
"styles/*"
]
},
...
}
もちろん設定が必須ではないです、相対パス派はよしなにしていただければと。
実装に結構時間がかかったのですが @forward
の仕様さえ把握してしまえばあっという間でした。