next.js14のプロジェクトにSASSを使おうと思って詰まったので備忘。
CSSはFLOCSSを使おうとしているためstyleディレクトリ配下に置いている。
エラーの原因はnext.config.mjsのsassOptionsの書き方だった。
開発環境
"dependencies": {
"next": "14.2.3",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"sass": "^1.77.2"
}
最終的にうまくいったコード
src/
|- app/
| |- layout.js
| |- page.js
| |-component
| |-Header.js
|- style
| |- foundation
| | |- _base.scss
| | |- _index.scss
| | |- _reset.scss
| |- global
| | |- _index.scss
| | |- _mixin.scss
| | |- _variables.scss
| | ~ 省略 ~
| |- style.scss
next.config.mjs
import "../style/style.scss";
~省略~
@use "../global/" as *; //@useでglobalを読み込む
html {
font-size: 62.5%;
}
body {
background: $color-main;
font-size: 1.6rem;
line-height: 1.4;
@include sp {
font-size: 1.4rem;
}
}
@forward "./reset";
@forward "./base";
@use "./foundation";
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const nextConfig = {
sassOptions: {
includePaths: [path.join(__dirname, "styles")],
},
};
export default nextConfig;
エラー SassError: @use rules must be written before any other rules.
原因はnext.config.mjsのsassOptionsの書き方だった。
エラー全文
Failed to compile
SassError: @use rules must be written before any other rules.
╷
3 │ @use "foundation";
│ ^^^^^^^^^^^^^^^^^
╵
src/style/style.scss 3:1 root stylesheet
Import trace for requested module:
./src/style/style.scss.webpack[javascript/auto]!=!./node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[13].use[2]!./node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[13].use[3]!./node_modules/next/dist/build/webpack/loaders/resolve-url-loader/index.js??ruleSet[1].rules[13].oneOf[13].use[4]!./node_modules/next/dist/compiled/sass-loader/cjs.js??ruleSet[1].rules[13].oneOf[13].use[5]!./src/style/style.scss
./src/style/style.scss
エラー発生時のnext.config.mjs
sassOptionsの書き方の部分でsrc/style/global/を全てのSCSSファイルに効かせようとしていた。
import path from "path";
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const nextConfig = {
sassOptions: {
prependData: `@import "${path.resolve(
__dirname,
"src/style/global/_index.scss"
)}";`,
},
};
export default nextConfig;
上記nextConfigファイルで@useでglobalを記載していなくても変数が使えたため、@use "../global/" as *;
を記載していなかった。
html {
font-size: 62.5%;
}
body {
background: $color-main;
font-size: 1.6rem;
line-height: 1.4;
@include sp {
font-size: 1.4rem;
}
}
エラーに至ってしまった経緯と解決まで
公式サイトのconfig設定からsassOptionsの部分をそのまま持ってくるだけだと「__dirname」の部分でエラーが出てしまい、ローカルサーバが終了してしまった。
const path = require('path')
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles')],
},
}
ReferenceError: __dirname is not defined in ES module scope
そのため「next.js scss」などで検索して変数をファイル全体で使用する設定を見つけたわけだが、@useエラーにぶつかってしまった。
「__dirname」の部分でエラーはnext.config.mjsに以下部分を追加すると解消される。
import { fileURLToPath } from "url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@useのエラー内容で検索してもnext.configの書き方についての記事は出てこず苦戦した。
「__dirname」のエラー解消の上記記述を残したままsassOptionsを公式の書き方に戻してみたところ、「_base.scss」内で使用していた変数($color-main)の部分がSassErrorで出てきたため「_base.scss」に「@use "../global/" as *;」の記述を追加したところ正常にコンパイルでき解決に至った。
参考サイト