0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

webpackの使い方

Last updated at Posted at 2022-04-06

npmを使えるように

npm  init

package.jsonが生成される

"private": "true", // プライベートにする
  "devDependencies": { // 公開しないようにする
    "css-loader": "^5.0.1",
    "webpack": "^5.15.0",
    "webpack-cli": "^4.3.1"
  }

インストールの基本

バージョンを確認

npm view velocity-animate

開発環境用のプラグイン --save-devをつけてインストールする

npm install --save-dev webpack@4.41.6

実行環境用のプラグイン --saveをつけてインストールする

npm install --save velocity-animate@1.5.2 jquery@3.7.0 

package.json
Screenshot 2023-06-18 14.30.51.png

最初に作るもの

  • src フォルダ
  • index.js
  • webpack.config.js
webpack.config.js
const path = require('path') // pathの設定

module.exports = {
    entry: './src/javascripts/main.js', // srcのメインの読み込み先
    output: {
        path: path.resolve(__dirname, './dist'), // 出力する場所
        filename: "./javascripts/main.js"
    },
}

scripts 関連

package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server",
    "build:dev": "webpack",
    "build:production": "webpack --mode production"
  }

webstormにnpmを設定する

Screenshot 2023-06-17 16.13.01.png

webpack設定関連

webpackインストール

npm view  webpack
npm install --save-dev webpack@4.41.6
npm view webpack-cli
npm install --save webpack-cli@hogehoge
  • srcフォルダを作る
  • ./src/main.js を作る
  • ./webpack.config.js を作る

webpack ビルド

npx webpack --mode development // 開発環境
npx webpack --mode production // 本番環境用

webpack.config.js
const path = require('path') // pathの設定

module.exports = {
    mode: "development",
    entry: './src/javascripts/main.js', // srcのメインの読み込み先 
    output: {
        path: path.resolve(__dirname, './dist'), // 出力する場所 絶対パスのみ指定可能
        filename: "./javascripts/main.js"
    },
}

web-dev-serverを使う

web-dev-serverをインストール

 npm install webpack-dev-server@4.15.1 --save-dev

サーバー立ち上げ

 npx webpack serve --mode=development

scripts

package.json
"start": "webpack-dev-server --config webpack.dev.js",

webpack-mergeでの記述なので注意

webpack.dev.js
const path = require('path');

module.exports = merge(commonConfig, {
    mode: 'development',
    devServer: { // サーバー
        // open: true // 自動で開く
        port: 3000,
        static: {
            directory: path.resolve(__dirname, 'public'), // 出力
        }
    }
});

cliの相性がよくなくて立ち上がらなかったのでcliのバージョンをあげた

 npm install webpack-cli@5.1.4 --save-dev

参考 https://qiita.com/syuuu/items/69485076f11a06530200
@syuuu さんより

キャッシュ対策

jsファイルにハッシュを付与することでキャッシュ対策する

webpack.commno.js
module.exports = {
    // entry: './src/app.js', // srcのメインの読み込み先
    entry: {
        app: './src/javascripts/app.js', // app.jsを読み込む
        another: './src/javascripts/another.js', // another.jsを読み込む
        other: './src/javascripts/other.js', // other.jsを読み込む
    },
    output: {
        path: path.resolve(__dirname, 'public'), // 出力する場所 絶対パスのみ指定可能
        filename: "javascripts/[name].[contenthash].js", // ハッシュを付属させる
        chunkFilename: "javascripts/[name].[contenthash].js", // ハッシュを付属させる
    },
}

distのファイルを一度削除する

clean-webpack-plugin インストール

npm install --save-dev clean-webpack-plugin@3.0.0
webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
    },
    module: {
    },
    plugins: [
       new CleanWebpackPlugin(),
    ]
}

index.js

  • cssの読み込み
  • javascriptsの呼び出しを行っている
src/javascripts/index.js
import my from './my'; // javascriptsの中から呼び出し同じ階層
import '../stylesheets/main.css'; // cssの呼び出し違う階層だから..で上に上げている

my(); // javascripts/my.jsのmy関数を呼び出し

CSS関連

css-loader

npm install --save-dev css-loader@5.0.1

style-loader

npm install --save-dev style-loader@2.0.0

mini-css-extract-pluginを使うならこれは不要になる

webpack.config.js
module: {
        rules: [
            {
                test: /\.css/, // .cssのファイルを検知する \.は正規表現のドット検知するため
                use: [
                    {
                        loader: "style-loader"// 処理するモジュール
                    },
                    {
                        loader: "css-loader" // 読み込むモジュール
                    }
                ]
            }
        ]
    }

useは下から上に読み込まれるので注意する

mini-css-extract-plugin

npm install --save-dev mini-css-extract-plugin@1.3.4

これを入れた場合 style-loaderが不要になるためアンイストールする

webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    module: {
        rules: [
            {
                test: /\.css/, // .cssのファイルを検知する \.は正規表げのドット検知するため
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader // 処理する, dist/main.cssを作成する
                    },
                    {
                        loader: "css-loader" // 読み込むモジュール
                    }
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: './stylesheets/main.css' // 出力されるcssの名前を変える
        }),
    ]
}

./main.cssが生成される

useは下から上に読み込まれるので注意する
プラグインを変数に入れる
pluginsをmodulesの下に追加

sass関連

sass-loaderインストール

npm install --save-dev sass-loader@12.4.0
webpack.confing.js
module.exports = {
    mode: "development",
    module: {
        rules: [
            {
                test: /\.css|sass|scss/, // .cssのファイルを検知する \.は正規表げのドット検知するため
                use: [
                    // {
                    //     loader: "style-loader"// 処理するモジュール
                    // },
                    {
                        loader: MiniCssExtractPlugin.loader //
                    },
                    {
                        loader: "css-loader" // 読み込むモジュール
                    },
                    {
                        loader: "sass-loader" // sass読み込み
                    }
                ]
            },
        ]
    },
    plugins: [
        
    ],
}

useは下から上に読み込まれるので注意する

node-sass

npm install --save-dev node-sass@9.0.0 

source-mapを作る

webpack.config.js
{
                        loader: "css-loader", // 読み込むモジュール
                        options: {
                            sourceMap: true, // 元のscssファイルをブラウザに表示させる 本番環境ではfalseにする
                        }
                    },

Screenshot 2023-06-17 15.41.30.png

Screenshot 2023-06-17 15.41.40.png

HTML関連

html-webpack-plugin と html-loader

インストール

 npm install --save-dev html-webpack-plugin@5.0.0
 npm install --save-dev html-loader@1.3.2 // requireで画像を読み込まなくて済むように
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
    },
    module: {
        rules: [
            {
                test: /\.pug/,
                use: [
                    {
                        loader: 'html-loader',
                    },
                ],
            },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/templates/index.html", // 読み込み先
            filename: "index.html"// 出力ファイルネーム
        }),
    ]
}

index.htmlが生成される

useは下から上に読み込まれるので注意する
プラグインを変数に入れる
pluginsをmodulesの下に追加

pug関連

pug-html-loaderインストール

npm install --save-dev pug-html-loader@1.1.5
webpack.config.js

module.exports = {
    entry: './src/javascripts/main.js', // srcのメインの読み込み先
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: "./javascripts/main.js" //// 出力されるfileの名前を変更
    },
    module: {
        rules: [
            {
                test: /\.pug/,
                use: [
                    {
                        loader: 'html-loader',
                    },
                    {
                        loader: 'pug-html-loader',
                        options: {
                            pretty: true,
                        },
                    },
                ],
            },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            // template: "./src/templates/[name].html", // 読み込み先(htmlの場合)
            template: "./src/templates/index.pug", // 読み込み先(pugの場合)
            // filename: "[name].html"// 出力ファイルネーム
            filename: "index.html"// 出力ファイルネーム
        }),
        new HtmlWebpackPlugin({
            // template: "./src/templates/[name].html", // 読み込み先(htmlの場合)
            template: "./src/templates/access.pug", // 読み込み先(pugの場合)
            // filename: "[name].html"// 出力ファイルネーム
            filename: "access.html"// 出力ファイルネーム
        }),
    ]
}

javascript 関連

特定のページに特定のjsを読み込ませる

webpack.common.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    // entry: './src/app.js', // srcのメインの読み込み先
    entry: {
        app: './src/javascripts/app.js', // app.jsを読み込む
        another: './src/javascripts/another.js', // another.jsを読み込む
        other: './src/javascripts/other.js', // other.jsを読み込む
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/html/index.html", // 読み込み先
            // filename: "index.html"// 出力ファイルネーム
            chunks: ['app'], // app.htmlだけで読み込ませたいjsファイルを記載 entryでしたファイル
        }),
        new HtmlWebpackPlugin({
            filename: "another.html",
            template: "./src/html/another.html", // 読み込み先
            chunks: ['another'], // another.htmlだけで読み込ませたいjsファイルを記載 entryでしたファイル
        }),
        new HtmlWebpackPlugin({
            filename: "other.html",
            template: "./src/html/other.html", // 読み込み先
            chunks: ['other'], // other.htmlだけで読み込ませたいjsファイルを記載 entryでしたファイル
        }),
    ],
}

共通のライブラリを抽出する

webpack.common.js
module.exports = {
    // entry: './src/app.js', // srcのメインの読み込み先
    entry: {
        app: './src/javascripts/app.js', // app.jsを読み込む
        another: './src/javascripts/another.js', // another.jsを読み込む
        other: './src/javascripts/other.js', // other.jsを読み込む
    },
    optimization: {
        splitChunks: {
            chunks: 'initial',
            cacheGroups: {
                vendor: { // node_modulesが対象
                    test: /node_modules/, // 分割の対象を指定
                    name: 'vendor', // 付けたいファイル名
                },
                vendorsModules: { // 自作さたjsで共通して使わているところを切り出す
                    // chunks: 'initial',
                    test: /src[\\/]javascripts[\\/]modules/, // 指定
                    name: 'vendor-modules', // ファイル名
                    minSize: 0, // 分割するファイルの最小サイズ(キロバイト)
                    minChunks: 2, // モジュールが共通で使われいる最少個数
                },
            },
        },
    },
}

node_modulesで共通のものはvendor.jsで抽出される
自作した共通のjsはvendor-modules.jsで抽出される

トランスコンパイルする

ES5に対応するためにES6を変換する必要がある

babel-loader インストール

 npm install --save-dev babel-loader@8.2.2

babel/core インストール

npm install --save-dev @babel/core@7.12.10

babel/preset-env インストール

npm install --save-dev @babel/preset-env@7.12.11
webpack.common.js
module.exports = {
    module: {
        rules: [
            {
                test: /\.js$/, // 対象ファイル
                exclude: /node_modules/, // 除外ファイル
                loader: "babel-loader",
            },
        ],
    },
}
babel.config.js
module.exports = {
    presets: ['@babel/preset-env'],
}

対象外にしたブラウザの指定

.browserslistrcを作成する

.browserslistrc
defaults

おすすめサイト
https://coliss.com/articles/build-websites/operation/work/target-browsers-between-different-front-end-tools.html

ポリフィルを取り込む方法

corejsをインストールする

npm install --save-dev core-js@3.31.0 

babel.config.jsを作る

corejsがデフォルトが2なのでbabel.config.jsで3にする

srcの中に入れないように注意!!

babel.config.js
module.exports = {
    presets: [
        [
            '@babel/preset-env',
            {
                useBuiltIns: 'usage',
                corejs: 3, // 必ず3にするデフォルトは2
                // debug: true, // 使い終わったらコメントアウトする
            },
        ],
    ],
};

debugをtrueにしてビルドすると対象の古いブラウザに合わせてポリフィル(es6未満のに合わせる)を作成する

ソースマップ作成

webpack.confing.js
devtool: 'source-map',

Screenshot 2023-06-17 15.42.26.png

webpack.confing.js
module.exports = {
    mode: "development",
    devtool: 'source-map',
    module: {
        rules: [
            {
                test: /\.js/, // jsファイルを検知する
                exclude: /node_modules/, // 除外することを明記
                use: [
                    {
                        loader: "babel-loader", //
                        options: {
                            presets: [
                                ['@babel/preset-env', {'targets': '> 0.25%, not dead'}] // 0.25%以上のシェアがあり サポートが終了していないブラウザと指定している
                            ]
                        }
                    }
                ]
            },
        ]
    },
    plugins: [
        
    ],
}

画像関連

image-webpack-loader インストール

npm install --save-dev image-webpack-loader@7.0.1
webpack.config.js
module.exports = {
    module: {
        rules: [
            {
                test: /\.(eot|svg|ttf|woff|woff2|png|jpg|jpeg|gif)/,
                type: "asset/resource", //webpack5から
                generator: {
                    filename: 'images/[path][name][ext]' //webpack5から
                },
                use: [
                    // { // webpack4まで
                    //     loader: 'file-loader',
                    //     options: {
                    //         esModule: false,
                    //         name: 'images/[name].[ext]',
                    //     }
                    // },
                    {
                        loader: "image-webpack-loader", // 画像の圧縮
                        options: {
                            mozjpeg: { // オプション
                                progressive: true,
                                quality: 65, // 画質下げ
                            }
                        }
                    }
                ]
            },
        ]
    },
    plugins: []
}

よく使うライブラリ

jQuery

実行環境なので-devはいらない

npm install --save jquery@3.7.0 
app.js
import $ from 'jquery'; // jqueryを$で扱うようにしている

$('body').append(result);
velocity($('h1'), 'fadein', {duration: 2000, loop: true});

webpack-merge

webpack.config.js を 共通, 開発, 本番に分ける

インストール

npm install --save-dev webpack-merge@5.9.0 
webpack.common.js
const path = require('path') // pathの設定

module.exports = {
    entry: './src/app.js', // srcのメインの読み込み先
    output: {
        path: path.resolve(__dirname, 'public'), // 出力する場所 絶対パスのみ指定可能
        filename: "javascripts/bundle.js"
    },
}

webpack.dev.js
const {merge} = require('webpack-merge');
const commonConfig = require('./webpack.common'); // ディレクトリの書きミスに注意

module.exports = merge(commonConfig, {
    mode: 'development',
    // watch: true, ファイの更新があるbuildする
})

webpack.prod.js
const {merge} = require('webpack-merge');
const commonConfig = require('./webpack.common'); // ディレクトリの書きミスに注意

module.exports = merge(commonConfig, {
    mode: 'production',
})
package.json
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },

terser-webpack-plugin

console.logを削除
ライセンスの抽出 また それを出力しないようにする

インストール

npm install --save-dev terser-webpack-plugin@5.3.9 
webpack.prod.js
const TerserPlugin = require('terser-webpack-plugin');

module.exports = merge(commonConfig, {
    optimization: {
        minimizer: [
            new TerserPlugin({
                extractComments: false, // ライブラリーのライセンスファイルを削除
                terserOptions: {
                    compress: {
                        drop_console: true // console.logの表示を削除
                    }
                }
            })
        ]
    }
})

ソースマップ作成

絶対の開発環境のみで使う!!
本番環境禁止!!

webpack.dev.js
module.exports = merge(commonConfig, {
    devtool: 'eval-cheap-module-source-map', // ソースマップ作成 // 書き方が昔と違うので注意
});

どのファイルーでエラーを起こしているかわかる
Screenshot 2023-06-18 16.53.52.png

clean-webpack-plugin

buildする前にファイルを自動で削除させる

npm install --save-dev clean-webpack-plugin@3.0.0
webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
    },
    module: {
    },
    plugins: [
       new CleanWebpackPlugin(),
    ]
}

eslint

jsのコードに一貫性を持たせるツール

インストール

npm install --save-dev eslint@8.43.0 
npm install --save-dev eslint-webpack-plugin@4.0.1
webpack.common.js
const ESLintPlugin = require("eslint-webpack-plugin");

module.exports = {
    plugins: [
        new ESLintPlugin({
            extensions: ['.js' ],
            exclude: 'node_modules',
            fix: true, // 自動修正にするか
        }),
    ],
}
.eslintrc.js
module.exports = {
    root: true, // trueにするとこの設定があるディレクトリーよりも親階層上の設定ファイルを探しにいかなくなる
    env: { // 検証するjavascriptの実行環境
        browser: true, // console.logでエラーを発生させないか
        es2020: true, // es2020までの構文を利用してもエラーが発生しなくなる
    },
    parserOptions: {
        sourceType: "module", // importやexportの構文を使ってもエラーが発生しなくなる
    },
    extends: ['eslint:recommended'], // 外部が勧めるeslintのルールを指定 今回はeslintがおすすめ設定を指定している
    rules: {
        'prefer-const':'error', // 更新しない変数にconstが使われいたらエラーが出るようにしている
    },
}

prettier

空白やコーテーションマークに一貫性を持たせる

インストール

 npm install --save-dev prettier@2.8.8
npm install --save-dev eslint-config-prettier@8.8.0 
npm install --save-dev eslint-plugin-prettier@4.2.1 
.eslintrc.js
module.exports = {
    extends: [
        'eslint:recommended', // 外部が勧めるeslintのルールを指定 今回はeslintがおすすめ設定を指定している
        'plugin:prettier/recommended', // prettierを有効にする こちら必ず最後に追加する
    ],
}
.prettierrc.js
module.exports = {
    singleQuote: true,
};

auto prefixer

インストール

npm install --save-dev postcss-loader@7.3.3
npm install --save-dev autoprefixer@10.4.14 

設定

webpack.common.js
module.exports = {
  module: {
      {
        test: /\.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader, //
          },
          {
            loader: 'css-loader', // 読み込むモジュール
            options: {
              sourceMap: true, // 元のscssファイルをブラウザに表示させる 本番環境ではfalseにする
              // importLoaders: 2, // Sass+PostCSSの場合は2を指定
            },
          },
          {
            loader: 'postcss-loader',
          },
          {
            loader: 'sass-loader', // sass読み込み
          },
        ],
      },
    ],
  },
};

順番を間違えないように

postcss.config.js
// eslint-disable-next-line no-undef
module.exports = {
  // eslint-disable-next-line no-undef
  plugins: [require('autoprefixer')],
};
.browserslitsrc.js
defaults

purge-webpack-plugin

CSSフレームワークの使ってないCSSの部分をカットする

設定

webpack.common.js
const path = require('path'); // pathの設定
const glob = require('glob');
const {PurgeCSSPlugin} = require('purgecss-webpack-plugin');

// eslint-disable-next-line no-undef
module.exports = {
  plugins: [
    // 使っていないCSSをカット
     new PurgeCSSPlugin({
       paths: glob.sync(
         `${path.join(__dirname, 'src/')}/**/*`,
         {nodir: true},
       ),
    }),
  ],
};
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?