【webpack5】sassのコンパイルをする【web制作】

html/css
この記事は約17分で読めます。
スポンサーリンク

はじめに

前回はhtml-webpack-pluginで複数のhtmlファイルを動的に出力するやり方について紹介しました。

まだの方はこちらを参考にしてください。

今回はwebpackでsassをコンパイルするやり方ついて紹介します。

web制作ではsassのコンパイルは必須ですよね。

webpackでももちろんsassのコンパイルは出来るのですが、いろんなローダーやプラグインを使用しないといけないので意外と面倒です。

sassのコンパイルのやり方が分からない方は参考にしてください。

対象者
  • webpackでsassのコンパイルをさせたい方
  • webpackに興味がある方

webpackの使い方まとめについてはこちら。

web制作をする場合のwebpackのテンプレート紹介についてはこちら。

それでは説明に移ります。

スポンサーリンク

使用するプラグイン

webpackでsassをコンパイルするにあたって、使用するローダーとプラグインをまとめておきます。

プラグイン名内容
sass-loadersassをコンパイルしてcssに変換するローダー
sassDart Sassを使えるようにするプラグイン
sass-loaderのオプションで使用する
postcss-loaderPostCSSでcssを処理するためのローダー
PostCSSでcssをいろんな形に加工する
autoprefixcerベンダープレフィックスを自動付与するプラグイン
postcss-loaderのオプションで使用する
css-loadercssをCommonJS形式に変換してjavaScriptで扱えるようにするローダー
mini-css-extract-plugincssファイルとして別ファイルに出力するプラグイン

sassをコンパイルしてcssファイル出力するには上記内容を上から順に処理していくことになります。

スポンサーリンク

ディレクトリ構成

今回のディレクトリ構成は以下です。

test
├ node_modules
├ dist
│ └ css
├ src
│ ├ js
│ │ └ index.js
│ ├ scss
│ │ ├ flocss
│ │ │ ├ _footer.scss
│ │ │ └ _header.scss
│ │ └ style.scss
│ └ index.html
├ package-lock.json
├ package.json
├ webpack.common.js
├ webpack.dev.js
└ webpack.prod.js

src/scss/style.scssをコンパイルしてdist/cssフォルダに出力させていきましょう。

webpackでsassをコンパイルするためにエントリポイントのjsファイルにstyle.scssを読み込ませるやり方で説明していきます。

スポンサーリンク

ファイル内容

今回はwebpack.common.js の記述がメインとなるので、それ以外のファイル内容を参考までに示しておきます。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>index.htmlです</h1>
</body>
</html>

style.scss

@use './flocss/header';
@use './flocss/footer';

index.js

import '../scss/style.scss';     // ここでsassの読み込みをさせる

console.log('index.jsです');

エントリポイントであるindex.jsにsassの読み込みをさせます。

webpack.dev.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const outputFile = '[name]';

module.exports = merge(common(outputFile), {
  mode: 'development',
  devtool: 'source-map',

});

webpack.prod.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const outputFile = '[name].[chunkhash]';

module.exports = merge(common(outputFile), {
  mode: 'production',

});
スポンサーリンク

プラグインをインストールしよう

それではsassをコンパイルするためのローダーとプラグインをインストールしていきましょう。

npm i -D sass-loader sass

下記コマンドをターミナルで実行してsass-loaderとsassをインストールします。

npm i -D sass-loader sass

sass-loader公式

sass公式

npm i -D postcss-loader autoprefixer

こちらも同様にインストールします。

npm i -D postcss-loader autoprefixer

postcss-loader公式

autoprefixcer公式

npm i -D css-loader

こちらも同様にインストールします。

npm i -D css-loader

css-loader公式

npm i -D mini-css-extract-plugin

こちらも同様にインストールします。

npm i -D mini-css-extract-plugin

mini-css-extract-plugin公式

スポンサーリンク

webpack.common.jsを編集する

ローダーとプラグインのインストールが完了したらwebpack.common.jsを編集していきましょう。

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WebpackWatchedGlobEntries = require('webpack-watched-glob-entries-plugin');

// 追加
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const entries = WebpackWatchedGlobEntries.getEntries([path.resolve(__dirname, './src/js/**/*.js')], {
	ignore: path.resolve(__dirname, './src/js/**/_*.js'),
})();

const htmlGlobPlugins = (entries, srcPath) => {
	return Object.keys(entries).map(
		(key) =>
			new HtmlWebpackPlugin({
				inject: 'body',
				filename: `${key}.html`,
				template: `${srcPath}/${key}.html`,
				chunks: [key],
			})
	);
};

module.exports = (outputFile) => ({
	entry: entries,

	output: {
		path: path.resolve(__dirname, './dist'),
		filename: `./js/${outputFile}.js`,
	},

	module: {
		rules: [
			// 追加
			{
				test: /\.(sa|sc|c)ss$/i,
				use: [
					// cssファイルとして別ファイルに出力する
					MiniCssExtractPlugin.loader,

					// cssをCommonJS形式に変換してjavaScriptで扱えるようにする
					'css-loader',
					{
						// PostCSSでcssを処理する
						loader: 'postcss-loader',
						options: {
							postcssOptions: {
								// ベンダープレフィックスを自動付与する
								plugins: [require('autoprefixer')({ grid: true })],
							},
						},
					},
					{
						// sassをコンパイルしてcssに変換する
						loader: 'sass-loader',
						options: {
							// Dart Sassを使えるようにする
							implementation: require('sass'),
						},
					},
				],
			},

			{
				test: /\.html$/i,
				loader: 'html-loader',
			},

			{
				test: /\.(png|jpe?g|gif|svg)$/i,
				generator: {
					filename: `./image/[name].[contenthash][ext]`,
				},
				type: 'asset/resource',
			},
		],
	},

	plugins: [
		new CleanWebpackPlugin(),
		new WebpackWatchedGlobEntries(),

		// 追加
		new MiniCssExtractPlugin({
			filename: `./css/${outputFile}.css`,
		}),

		...htmlGlobPlugins(entries, './src'),
	],
});

追加した箇所について説明していきます。

モジュール読み込み

以下の記述でmini-css-extract-pluginを読み込みしています。

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

ローダー処理定義

以下の記述でsassをコンパイルするための処理を定義しています。

{
	test: /\.(sa|sc|c)ss$/i,
	use: [
		// cssファイルとして別ファイルに出力する
		MiniCssExtractPlugin.loader,

		// cssをCommonJS形式に変換してjavaScriptで扱えるようにする
		'css-loader',
		{
			// PostCSSでcssを処理する
			loader: 'postcss-loader',
			options: {
				postcssOptions: {
					// ベンダープレフィックスを自動付与する
					plugins: [require('autoprefixer')({ grid: true })],
				},
			},
		},
		{
			// sassをコンパイルしてcssに変換する
			loader: 'sass-loader',
			options: {
				// Dart Sassを使えるようにする
				implementation: require('sass'),
			},
		},
	],
},

ローダーの記述は順番が逆になっていることに注意してください。

webpackのローダーの処理順序は下から順番に実行されます。

autoprefixerでベンダープレフィックスを自動付与させるにはpackage.json を編集する必要があります。

package.jsonbrowserslist オプションを追記することで、どのブラウザのいつのバージョンまでベンダープレフィックスを自動付与させるか設定させることができます。

browserslist の値はご自身の環境に合わせて変更してみてください。

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.common.js",
  "scripts": {
    "dev": "npx webpack --config ./webpack.dev.js",
    "pro": "npx webpack --config ./webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^10.4.2",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.6.0",
    "html-loader": "^3.1.0",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.5.3",
    "postcss-loader": "^6.2.1",
    "sass": "^1.49.7",
    "sass-loader": "^12.4.0",
    "webpack": "^5.68.0",
    "webpack-cli": "^4.9.2",
    "webpack-watched-glob-entries-plugin": "^2.2.3"
  },


  "browserslist": [
		"last 2 versions",
		"ie >= 11",
		"Android >= 4"
	]
}

プラグイン追加

以下でwebpackにmini-css-extract-pluginのプラグインを追加させています。

new MiniCssExtractPlugin({
	filename: `./css/${outputFile}.css`,
}),

filenameオプションでcssファイルを出力する場所とファイル名を指定しています。

filenameオプションには[name]や[contenthash]などののプレースホルダーを指定することもできます。

スポンサーリンク

コンパイルする

設定が完了したのでコンパイルしてみましょう。

以下のコマンドをターミナルから打ち込みます。

npx webpack --config ./webpack.dev.js

以下のようなメッセージが出力されていれば正しく実行できています。

PS C:\Users\shuuk\OneDrive\デスクトップ\test> npx webpack --config ./webpack.dev.js
assets by chunk 3.32 KiB (name: index)  asset ./js/index.js 2.46 KiB [emitted] (name: index) 1 related asset
  asset ./css/index.css 881 bytes [emitted] (name: index) 1 related asset
asset ./image/embedded_covid03.7d5f9ce136732547b4ce.jpg 788 KiB [emitted] [immutable] [from: src/image/embedded_covid03.jpg] (auxiliary name: index)
asset index.html 435 bytes [emitted]
Entrypoint index 3.32 KiB (790 KiB) = ./css/index.css 881 bytes ./js/index.js 2.46 KiB 3 auxiliary assets
orphan modules 5.08 KiB (javascript) 788 KiB (asset) 1.08 KiB (runtime) [orphan] 10 modules
runtime modules 279 bytes 1 module
cacheable modules 110 bytes (javascript) 278 bytes (css/mini-extract)
  ./src/js/index.js 60 bytes [built] [code generated]
  ./src/scss/style.scss 50 bytes [built] [code generated]  css ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[0].use[2]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[0].use[3]!./src/scss/style.scss 278 bytes [built] [code generated]
webpack 5.68.0 compiled successfully in 1754 ms
PS C:\Users\shuuk\OneDrive\デスクトップ\test>

cssファイルが出力されているはずです。

スポンサーリンク

画像やフォントの読み込みがうまくいかない

ここまででsassをコンパイルするやり方について説明しました。

ただし1点注意として、sassで記述した画像やフォントの指定をwebpackが解決してくれなくてエラーになる場合があります。

原因はsass記述する際の相対パスの基準が変わるためです。

これらを解決する方法については別記事にて紹介します。

スポンサーリンク

おわりに

以上webpackでsassをコンパイルするやり方ついて紹介しました。

いかがだったでしょうか。

webpackでsassのコンパイルするやり方が分からない方は参考にしてください。

次回はwebpackでsassの画像やフォントのアセットファイルの依存関係を解決するやり方ついて紹介します。

コメント

タイトルとURLをコピーしました