【webpack5】webpackのテンプレートサンプル紹介【web制作】

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

はじめに

今回はwebpackのテンプレートサンプルを紹介していきます。

web制作でwebpackを使う場合のテンプレートを紹介します。

webpackを導入したけどどういうプラグインを導入すればいいか分からない、どのように構築していけばいいか分からないといった方に見ていただけるとうれしいです。

web制作をしている方はwebpackを使えるようになるとできる幅が広がるのでぜひ参考にしてください。

紹介しているwebpackのテンプレートは試行錯誤中のため参考程度としてください。

気まぐれで随時更新していきます。

対象者
  • web制作をしている方
  • webpackに興味のある方

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

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

スポンサーリンク

ディレクトリ構成

webpackのテンプレートを紹介するにあたって、以下のようなディレクトリ構成を想定しています。

test
├ node_modules
├ dist
├ src
│ ├ font
│ │ └ aaa.ttf
│ │
│ ├ image
│ │ ├ aaa.jpg
│ │ └ bbb.jpeg
│ │
│ ├ js
│ │ ├ module
│ │ │ └ _aaa.js
│ │ ├ another.js
│ │ └ index.js
│ │
│ ├ scss
│ │ ├ flocss
│ │ │ ├ _aaa.scss
│ │ │ └ _bbb.scss
│ │ └ style.scss
│ │
│ ├ another.html
│ └ index.html
│ │
├ .eslintigonre
├ .eslintrc.js
├ .prettierrc.js
├ babel.config.js
├ package-lock.json
├ package.json
├ webpack.common.js
├ webpack.dev.js
└ webpack.prod.js

書き出してみると様々なフォルダがありますね。

another.jsindex.jsをエントリポイントとしています。

開発環境用の処理はwebpack.dev.js、本番環境用の場合はwebpack.prod.js、共通処理はwebpack.common.jsに記述しています。

スポンサーリンク

テンプレートサンプル紹介

それではテンプレートを紹介します。

another.js

import './module/_aaa';
import '@fortawesome/fontawesome-free/css/all.min.css';
import '@scss/styles.scss';

index.js

import '@js/module/_aaa';
import '@fortawesome/fontawesome-free/css/all.min.css';
import '@scss/styles.scss';

.eslintignore

node_modules/
dist/
webpack.config.js
webpack.common.js
webpack.dev.js
webpack.prod.js

.eslintrc.js

module.exports = {
	root: true,
	parser: '@babel/eslint-parser',
	env: {
		browser: true,
		node: true,
	},
	parserOptions: {
		sourceType: 'module',
	},
	extends: ['eslint:recommended', 'prettier'],
};

babel.config.js

module.exports = {
	presets: [
		[
			'@babel/preset-env',
			{
				useBuiltIns: 'usage',
				corejs: {
					version: 3,
					proposals: true,
				},
			},
		],
	],
};

webpack.common.js

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const WebpackWatchedGlobEntries = require('webpack-watched-glob-entries-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: /\.js$/,
				exclude: /node_modules/,
				loader: 'babel-loader',
			},
			{
				test: /\.(sa|sc|c)ss$/i,
				use: [
					MiniCssExtractPlugin.loader,
					'css-loader',
					{
						loader: 'postcss-loader',
						options: {
							postcssOptions: {
								plugins: [require('autoprefixer')({ grid: true })],
							},
						},
					},
					{
						loader: 'sass-loader',
						options: {
							implementation: require('sass'),
						},
					},
				],
			},
			{
				test: /\.(png|jpe?g|gif|svg)$/i,
				generator: {
					filename: `./image/[name].[contenthash][ext]`,
				},
				type: 'asset/resource',
			},
			{
				test: /\.(ttf|otf|eot|woff|woff2)$/i,
				generator: {
					filename: `./font/[name][ext]`,
				},
				type: 'asset/resource',
			},
			{
				test: /\.html$/,
				loader: 'html-loader',
			},
		],
	},

	optimization: {
		splitChunks: {
			chunks: 'initial',
			cacheGroups: {
				vendor: {
					test: /node_modules/i,
					name: 'vendor',
				},
				vendorsModules: {
					test: /src[\\/]js[\\/]modules/i,
					name: 'vendor-modules',
					minSize: 0,
					minChunks: 2,
				},
			},
		},
	},

	performance: {
		hints: false,
	},

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

		...htmlGlobPlugins(entries, './src'),
		new MiniCssExtractPlugin({
			filename: `./css/${outputFile}.css`,
		}),
	],

	resolve: {
		extensions: ['.js', '.json'],
		alias: {
			'@font': path.resolve(__dirname, './src/font/'),
			'@image': path.resolve(__dirname, './src/image/'),
			'@js': path.resolve(__dirname, './src/js/'),
			'@scss': path.resolve(__dirname, './src/scss/'),
		},
	},
});

webpack.dev.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

const outputFile = '[name]';

const bsConf = {
	start: './dist/index.html',
};

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

	plugins: [
		new BrowserSyncPlugin({
			server: {
				baseDir: './',
			},
			startPath: bsConf.start,
			notify: false,
			open: 'external',
		}),
	],
});

webpack.prod.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const ESLintPlugin = require('eslint-webpack-plugin');
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const ImageminMozjpeg = require('imagemin-mozjpeg');

const outputFile = '[name].[chunkhash]';

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

	plugins: [
		new ESLintPlugin({
			fix: true,
		}),

		new ImageminPlugin({
			pngquant: {
				quality: '60-70',
			},
			gifsicle: {
				optimizationLevel: 3,
			},
			svgo: {},
			plugins: [
				ImageminMozjpeg({
					quality: 65,
				}),
			],
		}),
	],
});

package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "npx webpack --config ./webpack.dev.js",
    "pro": "npx webpack --config ./webpack.prod.js",
    "fix": "npm-run-all -s fix:*",
    "fix:eslint": "npx eslint . --fix",
    "fix:prettier": "npx prettier ./src/**/*.{html,js,scss} --write"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.17.4",
    "@babel/eslint-parser": "^7.17.0",
    "@babel/preset-env": "^7.16.11",
    "@fortawesome/fontawesome-free": "^6.0.0",
    "autoprefixer": "^10.4.2",
    "babel-loader": "^8.2.3",
    "browser-sync-webpack-plugin": "^2.3.0",
    "clean-webpack-plugin": "^4.0.0",
    "core-js": "^3.21.1",
    "css-loader": "^6.6.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-webpack-plugin": "^3.1.1",
    "html-loader": "^3.1.0",
    "html-webpack-plugin": "^5.5.0",
    "imagemin-mozjpeg": "^9.0.0",
    "imagemin-webpack-plugin": "^2.4.2",
    "mini-css-extract-plugin": "^2.5.3",
    "npm-run-all": "^4.1.5",
    "postcss-loader": "^6.2.1",
    "prettier": "^2.5.1",
    "sass": "^1.49.7",
    "sass-loader": "^12.6.0",
    "webpack": "^5.69.1",
    "webpack-cli": "^4.9.2",
    "webpack-watched-glob-entries-plugin": "^2.2.4"
  }
}

webpackは特に変なこだわりが無い限り、だいたいが似たような記述の仕方になりますよね。

最初はwebpack独特の記述やたくさんのオプションで難しく感じますが、慣れれば非常に分かりやすく感じます。

特に特殊な書き方はしていないつもりです。

もし書き方が分からない場合や知らないプラグインがある場合は以下あたりを参考にしてください。

スポンサーリンク

インストール手順

先ほど紹介したwebpack.common.jswebpack.dev.jswebpack.pro.jspackage.jsonをベースに新規にプロジェクトを作成する場合はターミナルに以下のコマンドを入力してください。

npm i

package.jsonに記載されたプラグインがnode_modulesにインストールされます。

その他ファイルも必要であればファイルをコピーしてください。

スポンサーリンク

開発環境用と本番環境用で実行する

プラグインのインストールが完了して、フォルダやファイルの作成がおわったらwebpackのタスクを実行していきましょう。

開発環境用の場合

npm run dev

以下のような表示になれば正しく動作しています。

PS C:\Users\shuuk\OneDrive\デスクトップ\test> npm run dev

> test@1.0.0 dev
> npx webpack --config ./webpack.dev.js

assets by path ./ 916 KiB
  assets by path ./font/ 796 KiB
    assets by path ./font/*.ttf 542 KiB 4 assets
    assets by path ./font/*.woff2 254 KiB
      asset ./font/fa-solid-900.woff2 124 KiB [emitted] [from: node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2] (auxiliary name: another, index)
      + 3 assets
  assets by path ./css/*.css 103 KiB
    asset ./css/vendor.css 102 KiB [emitted] (name: vendor) (id hint: vendor) 1 related asset
    asset ./css/src_scss_styles_scss.css 645 bytes [emitted]
  assets by path ./js/*.js 17.4 KiB
    asset ./js/another.js 8.7 KiB [emitted] (name: another) 1 related asset
    asset ./js/index.js 8.7 KiB [emitted] (name: index) 1 related asset
assets by path *.html 852 bytes
  asset another.html 428 bytes [emitted]
  asset index.html 424 bytes [emitted]
Entrypoint another 111 KiB (940 KiB) = ./css/vendor.css 102 KiB ./css/src_scss_styles_scss.css 645 bytes ./js/another.js 8.7 KiB 10 auxiliary assets
Entrypoint index 111 KiB (940 KiB) = ./css/vendor.css 102 KiB ./css/src_scss_styles_scss.css 645 bytes ./js/index.js 8.7 KiB 10 auxiliary assets
runtime modules 8.61 KiB 21 modules
orphan modules 267 KiB (javascript) 796 KiB (asset) [orphan] 13 modules
cacheable modules 344 bytes (javascript) 103 KiB (css/mini-extract)
  javascript modules 344 bytes
    modules by path ./src/js/ 244 bytes
      ./src/js/another.js 107 bytes [built] [code generated]
      ./src/js/index.js 109 bytes [built] [code generated]
      ./src/js/module/_aaa.js 28 bytes [built] [code generated]
    ./node_modules/@fortawesome/fontawesome-free/css/all.min.css 50 bytes [built] [code generated]
    ./src/scss/styles.scss 50 bytes [built] [code generated]
  css modules 103 KiB
    css ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./node_modules/@fortawesome/fontawesome-free/css/all.min.css 103 KiB [built] [code generated]
    css ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./src/scss/styles.scss 0 bytes [built] [code generated]
webpack 5.69.1 compiled successfully in 3974 ms
[Browsersync] Access URLs:
 ---------------------------------------------------------
       Local: http://localhost:3000/./dist/index.html
    External: http://192.168.10.102:3000/./dist/index.html
 ---------------------------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 ---------------------------------------------------------
[Browsersync] Serving files from: ./
assets by status 916 KiB [cached] 12 assets
assets by path . 852 bytes
  asset another.html 428 bytes [emitted]
  asset index.html 424 bytes [emitted]
Entrypoint another 111 KiB (940 KiB) = ./css/vendor.css 102 KiB ./css/src_scss_styles_scss.css 645 bytes ./js/another.js 8.7 KiB 10 auxiliary assets
Entrypoint index 111 KiB (940 KiB) = ./css/vendor.css 102 KiB ./css/src_scss_styles_scss.css 645 bytes ./js/index.js 8.7 KiB 10 auxiliary assets
cached modules 344 bytes (javascript) 103 KiB (css/mini-extract) 6.67 KiB (runtime) [cached] 19 modules
webpack 5.69.1 compiled successfully in 267 ms
[Browsersync] Reloading Browsers...

本番環境用の場合

npm run pro

以下のような表示になれば正しく動作しています。

PS C:\Users\shuuk\OneDrive\デスクトップ\test> npm run pro

> test@1.0.0 pro
> npx webpack --config ./webpack.prod.js

(node:8644) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.
BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
        Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
        Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.
(Use `node --trace-deprecation ...` to show where the warning was created)
assets by path ./ 880 KiB
  assets by path ./font/ 796 KiB
    assets by path ./font/*.ttf 542 KiB 4 assets
    assets by path ./font/*.woff2 254 KiB
      asset ./font/fa-solid-900.woff2 124 KiB [emitted] [from: node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2]
      + 3 assets
  assets by info 84 KiB [immutable]
    assets by path ./css/*.css 81.6 KiB 2 assets
    assets by path ./js/*.js 2.32 KiB
      asset ./js/index.c5974bdf0405d2dc916f.js 1.16 KiB [emitted] [immutable] [minimized] (name: index)
      asset ./js/another.6e1ef21b12d66528ec19.js 1.16 KiB [emitted] [immutable] [minimized] (name: another)
assets by path *.html 922 bytes
  asset another.html 463 bytes [emitted]
  asset index.html 459 bytes [emitted]
Entrypoint another 82.8 KiB = ./css/vendor.41d471b2868ab985fc07.css 81.6 KiB ./css/417.7f4aca11c407bfe98b96.css 1 bytes ./js/another.6e1ef21b12d66528ec19.js 1.16 KiB
Entrypoint index 82.8 KiB = ./css/vendor.41d471b2868ab985fc07.css 81.6 KiB ./css/417.7f4aca11c407bfe98b96.css 1 bytes ./js/index.c5974bdf0405d2dc916f.js 1.16 KiB
orphan modules 90.9 KiB (javascript) 796 KiB (asset) 1.93 KiB (runtime) [orphan] 24 modules
runtime modules 6.08 KiB 10 modules
cacheable modules 244 bytes (javascript) 83.1 KiB (css/mini-extract)
  javascript modules 244 bytes
    ./src/js/another.js 107 bytes [built] [code generated]
    ./src/js/index.js 109 bytes [built] [code generated]
    ./src/js/module/_aaa.js 28 bytes [built] [code generated]
  css modules 83.1 KiB
    css ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./node_modules/@fortawesome/fontawesome-free/css/all.min.css 83.1 KiB [built] [code generated]
    css ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[1].use[3]!./src/scss/styles.scss 0 bytes [built] [code generated]
webpack 5.69.1 compiled successfully in 3784 ms
スポンサーリンク

おわりに

以上web制作でwebpackを使う場合のテンプレートサンプルを紹介していきました。

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

webpackを導入すれば面倒な作業を全て自動化させることができるかもしれないので、気になる方はぜひ導入してみてください。

コメント

  1. でこ より:

    お世話になります。
    現在、ダイナミックインポートを行うとeslintでエラーが発生してしまう事象に悩んでいるのですが、上記の.eslintrcの設定でエラーの発生はありますでしょうか?
    エラー内容は下記になります。
    error Parsing error: ‘import’ and ‘export’ may only appear at the top level
    回答をよろしくお願い致します。

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