@importとcss-loaderを使い分けて、TypeScriptでCSS/SCSSモジュールを読み込む
TypeScriptでCSS/SCSSモジュールをインポートしようとすると、Cannot Find Module
というエラーが発生することがあります。
原因
TypeScriptはデフォルトで.scss
ファイルを読み込むことができません。そのため、import
文を使って読み込もうとすると、エラーが発生します。
解決策
この問題を解決するには、以下の2つの方法があります。
@import
を使ってCSS/SCSSファイルをインポートすることができます。
@import "./styles.scss";
この方法は、簡単な方法ですが、いくつかのデメリットがあります。
- Sassの機能を全て利用できない
- モジュール化ができない
css-loader
を使うと、CSS/SCSSファイルをJavaScriptモジュールとしてインポートすることができます。
import styles from "./styles.module.scss";
const App = () => {
return (
<div className={styles.container}>
<h1>Hello, World!</h1>
</div>
);
};
export default App;
この方法は、以下のメリットがあります。
詳細
それぞれの方法の詳細については、以下のサイトをご覧ください。
補足
sass
とscss
は基本的に同じですが、scss
はsass
にネスト構文を追加したものです。css-loader
以外にも、style-loader
など、CSS/SCSSファイルをインポートするためのライブラリがいくつかあります。
@importを使う
// styles.scss
.container {
color: red;
}
// App.tsx
import React from "react";
const App = () => {
return (
<div className="container">
<h1>Hello, World!</h1>
</div>
);
};
export default App;
css-loaderを使う
// styles.module.scss
.container {
color: red;
}
// App.tsx
import React from "react";
import styles from "./styles.module.scss";
const App = () => {
return (
<div className={styles.container}>
<h1>Hello, World!</h1>
</div>
);
};
export default App;
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true,
},
},
],
},
],
},
};
このサンプルコードは、@import
とcss-loader
の両方を使って、CSS/SCSSモジュールをインポートする方法を示しています。
実行
webpack
npx start
ブラウザでhttp://localhost:3000
を開くと、Hello, World!
という文字が赤色で表示されます。
webpack.config.js
は、webpackの設定ファイルです。
CSS/SCSSモジュールをインポートする他の方法
sass-loader
を使うと、@import
を使ってSassファイルをインポートすることができます。
// styles.scss
@import "./styles.module.scss";
// App.tsx
import React from "react";
import styles from "./styles.module.scss";
const App = () => {
return (
<div className={styles.container}>
<h1>Hello, World!</h1>
</div>
);
};
export default App;
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true,
},
},
"sass-loader",
],
},
],
},
};
メリット
@import
を使ってSassファイルをインポートできるので、Sassの機能を全て利用できる
css-loader
を使うよりも複雑な設定が必要
node-sass
を使うと、JavaScriptから直接Sassファイルをコンパイルすることができます。
// styles.scss
.container {
color: red;
}
// App.tsx
import React from "react";
import nodeSass from "node-sass";
const sass = nodeSass.renderSync({
file: "./styles.scss",
});
const App = () => {
return (
<div style={{ cssText: sass }}>
<h1>Hello, World!</h1>
</div>
);
};
export default App;
- 設定が複雑
- ビルド時間が長くなる
CSS in JSを使うと、JavaScriptコードの中にCSSコードを直接記述することができます。
import React from "react";
const App = () => {
return (
<div style={{ color: "red" }}>
<h1>Hello, World!</h1>
</div>
);
};
export default App;
- 設定が簡単
- コード量が少なくなる
- スタイルの管理が難しい
- 大規模なプロジェクトには向かない
- 小さなプロジェクトであれば、
@import
を使う方法がおすすめです。 - Sassの機能を全て利用したい場合は、
sass-loader
を使う方法がおすすめです。 - コード量を少なくしたい場合は、CSS in JSを使う方法がおすすめです。
typescript import sass