どうも!かけちまるです!
サイト表示スピードに関わる部分なので、画像圧縮やWebPを活用してファイルサイズを抑えたいところ。
画像圧縮ツールやWebP変換ツールを使うのもいいけど、もう少し自動化できないかなぁと思いました。
そこで、webpack環境で画像の更新を感知して、自動圧縮する設定をしてみました。
GitHubにコードを公開しているのでダウンロードして本記事を見てもらえると理解しやすいと思います。
この記事では、
がわかります。
GitHubから完成形をダウンロードしてから、この記事を読んでもらうと理解しやすいかもです。
圧縮&WebP変換の部分的な解説になるので、コピペしても動かない可能性があります。
完成形に書いてある他の設定も見て、ご自分のディレクトリ構成用に最適化してもらえると良いかと。
完成形のリポジトリはこちらです。
npm i
パッケージインストールを忘れないように。
ちなみに、ディレクトリ構成はこんな感じです。
ディレクトリ構成src ┗ css ┣ (style.css) ┗ images ┗ js ┗(index.js) package-lock.json package.json webpack.common.js webpack.dev.js webpack.prod.js
叶えたい条件としては次のような感じです。
jpg
とpng
/src/images/
を更新したら/dist/images/
に圧縮&WebP変換されること/dist/images/
に不要ファイルが含まれていないことnpm run start
で/src/images/
の監視&ローカルサーバの立ち上げ/src/images/
内を更新/dist/images/
へ圧縮&WebPファイルを作成/src/images/
コピーnpm run build
でproductionモード/dist/images/
内を/src/images/
内にコピーGitHubの完成形をもとに解説しています。
jpg
用のいろんな設定ができるやつ。png
用のいろんな設定ができるやつ。webp
用のいろんな設定ができるやつ。/src/images/
にコピーされてきません。/dist/imeges/
に生成されたWebPを使用できるように/src/images/
にコピーします。webpack.dev.jsconst { merge } = require('webpack-merge'); const common = require('./webpack.common.js'); const path = require('path'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin'); const FileManagerPlugin = require('filemanager-webpack-plugin'); module.exports = merge(common(), { mode: 'development', plugins: [ // コピーの設定 new CopyWebpackPlugin({ patterns: [{ from: path.resolve(__dirname, 'src/images'), to: path.resolve(__dirname, 'dist/images') }] }), // 圧縮&WebP変換の記述 new ImageMinimizerPlugin({ // 圧縮の記述 minimizer: { implementation: ImageMinimizerPlugin.imageminMinify, options: { plugins: [ ['mozjpeg', { quality: 75 }], // jpgの設定 ['pngquant', { quality: [0.75, 0.75] }], // pngの設定 ], }, }, // WebP変換の記述 generator: [ { type: 'asset', implementation: ImageMinimizerPlugin.imageminGenerate, options: { plugins: [ ['webp', { quality: 75 }], // webpの設定 ] }, }, ], }), // ビルドが終わったら、WebPを/src/images/にコピーする new FileManagerPlugin({ events: { onEnd: { copy: [ { source: path.resolve(__dirname, 'dist/images/*.webp'), destination: path.resolve(__dirname, 'src/images/'), }, ], }, } }), ] });
ポイントは、webpack.common.js
のoutput
にclean
オプションをつけること。
これがないと/src/images/
内が更新されたときにうまく動かないです。
webpack.common.jsconst path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = () => ({ entry: './src/js/index.js', output: { clean: true, path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, ・・・ });
/src/images/
内は圧縮していない画像があるのでビルド前に/dist/images/
内を全部コピーしておきます。webpack.prod.jsconst { merge } = require('webpack-merge'); const common = require('./webpack.common.js'); const path = require('path'); const FileManagerPlugin = require('filemanager-webpack-plugin'); module.exports = merge(common(), { mode: 'production', plugins: [ // ビルド前に、/dist/imeges/内の画像を/src/images/にコピーする new FileManagerPlugin({ events: { onStart: { copy: [ { source: path.resolve(__dirname, 'dist/images/*'), destination: path.resolve(__dirname, 'src/images/'), }, ], }, } }) ] });
/src/images/
内でjpg
かpng
なんかしらの更新があったらwebpack.dev.js
の処理が走る。package.json{ ・・・ "scripts": { "start": "webpack serve --config ./webpack.dev.js & onchange ./src/images/*.{jpg,jpeg,png} -- webpack --config ./webpack.dev.js", "build": "webpack --config ./webpack.prod.js", "dev": "webpack --config ./webpack.dev.js" }, ・・・ }
おわり
フィードバックを送信
記事についてのフィードバックはTwitterかお問い合わせフォームから受け付けております。