LoginSignup
19
17

More than 3 years have passed since last update.

webpack + jQuery(webpack.config.js書き方の例)

Last updated at Posted at 2020-02-08

webpack + jQuery

自分用メモ

webpackはモジュールバンドラー

エントリーポイントに設定したjsファイルを中心に、各モジュールのjsファイルを纏めてbundle

  • モジュール管理できるため機能ごとに開発ができ保守性が上がる
  • 複数のjsファイル(cssや画像も)を一つのファイルにbundleできるためリクエスト数減少とパフォーマンス向上 ※ ファイルサイズの増大によるパフォーマンス低下もありうる
  • 依存関係の解消

CSSをインラインのstyleではなく、CSSファイルとして出力

1. webpack使用の下準備

1.1. webpackでの基本的なパッケージのインストール

$ npm init -y
$ npm i -S jquery
$ npm i -D webpack webpack-cli 
$ npm i -D terser-webpack-plugin optimize-css-assets-webpack-plugin mini-css-extract-plugin
$ npm i -D node-sass css-loader sass-loader style-loader postcss-loader
$ npm i -D babel-loader @babel/core @babel/polyfill @babel/preset-env 
$ npm i -D autoprefixer

# 分割したcssの読み込みをリロードしない(brouser-sinc代用)
$ npm i -D webpack-dev-server

# gulp使うとき
$ npm i -D gulp gulp-eslint gulp-notify gulp-plumber

1.2. package.jsonの編集

package.json
{
  "name": "webpack_test",
  "version": "1.0.0",
  "description": "",
- "main": "index.js",
  "scripts": {
-   "test": "echo \"Error: no test specified\" && exit 1",
    // sassも監視対象
+   "build:dev": "webpack --mode development --watch",
+   "build": "webpack --mode production",
    // dev-serverだけだとjsの監視はされるが、バンドルはされない
    // 保存すると自動リロードがかかるため更新はされるが、監視よりも遅いため二回目リロード時にバンドルが反映される
+   "start": "webpack --mode development --watch & webpack-dev-server",
  },
    "scripts": {
    },
+ "private": true,
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "jquery": "^3.4.1"
  },
  "devDependencies": {
    "@babel/core": "^7.4.5",
    "@babel/polyfill": "^7.4.4",
    "@babel/preset-env": "^7.4.5",
    "autoprefixer": "^9.6.0",
    "babel-loader": "^8.0.6",
    "css-loader": "^3.0.0",
    "mini-css-extract-plugin": "^0.7.0",
    "node-sass": "^4.12.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "terser-webpack-plugin": "^1.3.0",
    "webpack": "^4.35.2",
    "webpack-cli": "^3.3.5",
    "webpack-dev-server": "^3.7.2"
  }
}

1.2. webpack.config.jsの作成

webpackをインストールしたらwebpack.config.jsを手動で作成

webpack.config.js
// 開発or本番モードの選択(development、production、noneのいずれか設定必須)
// development: 開発時のファイル出力のモード(最適化より時間短縮,エラー表示などを優先)
// production: 本番時のファイル出力のモード(最適化されて出力される)
const MODE = "development";
// ソースマップの利用有無(productionのときはソースマップを利用しない)
const enabledSourceMap = MODE === "development";

// ファイル出力時の絶対パス指定に使用
const path = require('path');

// プラグイン
// js最適化
const TerserPlugin = require('terser-webpack-plugin');
// css最適化
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
// css抽出
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// jQueryで使用
const webpack = require('webpack');


module.exports = {
  // エントリーポイント(メインのjsファイル)
  entry: './src/js/app.js',
  // ファイルの出力設定
  output: {
    // 出力先(絶対パスでの指定必須)
    path: path.resolve(__dirname, 'dist/js'),
    // 出力ファイル名
    filename: "bundle.js"
  },
  mode: MODE,
  // ソースマップ有効
  devtool: 'source-map',
  // ローダーの設定
  module: {
    rules: [
      {
        // ローダーの対象 // 拡張子 .js の場合
        test: /\.js$/,
        // ローダーの処理対象から外すディレクトリ
        exclude: /node_modules/,
        use: [
          {
            // Babel を利用する
            loader: "babel-loader",
            // Babel のオプションを指定する
            options: {
              presets: [
                // プリセットを指定することで、ES2019 を ES5 に変換
                "@babel/preset-env"
              ]
            }
          }
        ]
      },
      {
        // ローダーの対象 // 拡張子 .scss の場合
        test: /\.scss/,
        // Sassファイルの読み込みとコンパイル
        use: [
          // linkタグに出力する機能
          "style-loader",
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              // css出力先を指定
              publicPath: path.resolve(__dirname, 'dist/css'),
              // developmentのときのみ有効
              hmr: process.env.NODE_ENV === 'development',
            },
          },
          // CSSをバンドルするための機能
          {
            loader: "css-loader",
            options: {
              // CSS内のurl()メソッドの取り込みを禁止する
              // 画像ファイルをbase64でエンコードするとかでは無い限り、必要なし
              url: false,
              // ソースマップの利用有無
              sourceMap: enabledSourceMap,
              // Sass+PostCSSの場合は2を指定
              // 0 => no loaders (default);
              // 1 => postcss-loader;
              // 2 => postcss-loader, sass-loader
              importLoaders: 2
            }
          },
          // PostCSS(Autoprefixer)のための設定
          // ベンダープレフィックスを追加するためのPostCSS用プラグイン
          {
            loader: "postcss-loader",
            options: {
              // PostCSS側でもソースマップを有効にする
              sourceMap: enabledSourceMap,
              plugins: [
                // Autoprefixerを有効化
                require("autoprefixer")({
                  grid: true
                })
              ]
            }
          },
          // Sassをバンドルするための機能
          {
            loader: "sass-loader",
            options: {
              // ソースマップの利用有無
              sourceMap: enabledSourceMap
            }
          }
        ]
      }
    ]
  },
  // mode:puroductionでビルドした場合のファイル圧縮
  optimization: {
    minimizer: production
      ? []
      : [
        // jsファイルの最適化
        new TerserPlugin({
          // すべてのコメント削除
          extractComments: 'all',
          // console.logの出力除去
          terserOptions: {
            compress: { drop_console: true }
          },
        }),
        // 抽出したcssファイルの最適化
        new OptimizeCssAssetsPlugin({})
      ]
  },
  // js, css, html更新時自動的にブラウザをリロード
  devServer: {
    // サーバーの起点ディレクトリ
    // contentBase: "dist",
    // バンドルされるファイルの監視 // パスがサーバー起点と異なる場合に設定
    publicPath: '/dist/js/',
    //コンテンツの変更監視をする
    watchContentBase: true,
    // 実行時(サーバー起動時)ブラウザ自動起動
    open: true,
    // 自動で指定したページを開く
    openPage: "index.html",
    // 同一network内からのアクセス可能に
    host: "0.0.0.0"
  },
  plugins: [
    // 抽出したCSSファイル最適化
    new OptimizeCssAssetsPlugin({
      assetNameRegExp: /\.optimize\.css$/g,
      cssProcessor: require('cssnano'),
      cssProcessorPluginOptions: {
        preset: ['default', { discardComments: { removeAll: true } }],
      },
      canPrint: true
    }),
    // ビルドされたjsファイルからstyleの部分を抽出してcssファイルで出力
    // jsファイルからcssの内容消える
    // v3でのextract-text-pluginのようなもの
    new MiniCssExtractPlugin({
      // 出力先ファイル名 // prefix は output.path
      filename: "../css/[name].css",
      chunkFilename: "[id].css"
    }),
    new webpack.ProvidePlugin({
      $: 'jquery'
    })
  ]
};

2. webpackの処理対象となるjsファイルの書き方

エントリーポイントとなるjsファイルをapp.jsモジュールファイルをmodule1.jsとすると次のように書く

app.js
import "../scss/style.scss";
import jQuery from 'jquery';
import "@babel/polyfill";
import { モジュールから呼び出す関数 } from './modules/module1';
module.js
// 関数を定義
index.html
<!DOCTYPE html>
<html lang="ja" dir="ltr">
<head>
  <meta charset="utf-8">
  <title>webpack_sample</title>
  <link rel="stylesheet" href="./dist/css/main.css">
</head>
<body> 
  // 
  <script src="./dist/js/bundle.js"></script>
</body>

</html>

3. webpack実行

実行コマンド

package.jsonscriptsで設定した名称で実行

$ npm run build:dev  # バンドル(開発用)実行
$ npm run build  # バンドル(本番用)実行
$ npm run start  # バンドルと監視スタート
19
17
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
19
17