LoginSignup
22
36

More than 3 years have passed since last update.

Web制作向けwebpack

Last updated at Posted at 2020-10-03

Web制作向けwebpack

JavaScriptのBundle、TypeScriptのBundleとTranspile、CSSやSCSSのBundleとベンダープレフィックスの追加、画像の圧縮、Pugのコンパイル、JavaScriptとCSSのLint、ソースマップの出力などを行います。

ファイル構成

 website
 ├ src
 │ ├ pug
 │ │ ├ index.pug
 │ │ ├ sub.pug
 │ │ ├ _include
 │ │   └ _included.pug
 │ │
 │ ├ img
 │ │ ├ img.jpg
 │ │ ├ img.png
 │ │ ├ img.svg
 │ │ └ img.gif
 │ │ 
 │ ├ css
 │ │ ├ style.css
 │ │ └ sub.css
 │ │ 
 │ ├ scss
 │ │ ├ style.scss
 │ │ └ sub.scss
 │ │
 │ ├ ts
 │ │ └ sub.ts
 │ │
 │ ├ js
 │ │ └ sub.js
 │ │
 │ ├ index.js
 │ └ index.ts
 │
 ├ package.json
 ├ package-lock.json
 │
 ├.gitignore
 │
 ├ tsconfig.json
 │
 ├ .babelrc
 │
 ├ .browserslistrc
 │
 ├ postcss.config.js
 │
 ├ .eslintrc.json 
 ├ .eslintignore
 │
 ├ .prettierrc.json
 ├ .prettierignore
 │
 ├ .stylelintrc.json
 └ .stylelintignore

webpack使用の準備

package.jsonの作成

terminal
npm init -y

webpackのインストール

terminal
npm i -D webpack webpack-cli
パッケージ 内容
webpack webpack本体
webpack-cli webpackのコマンドラインツール

package.jsonの編集

package.jsonにビルドコマンドを追記

packege.json
"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production",
  "watch": "webpack  --mode development --watch"
}

JavaScriptファイルのバンドル

webpack.config.jsの作成

webpackの設定ファイルwebpack.config.jsを作成します。

webpack.config.js
const path = require("path");

module.exports = {
  mode: "production",

  entry: "./src/index.js",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js",
  }
};

バンドルするJavaScriptファイルの準備

index.jsの作成

webpackを使うにはエントリーポイントになるjsファイルが必要なので最初にindex.jsを作成します。

src/index.js
import { hello } from "./js/sub";

console.log("JavaScript 変換成功");

hello();

sub.jsの作成

バンドルできているか確認用に、importするjsファイルも作成します。

src/js/sub.js
export function hello() {
   console.log("JavaScript import成功");
}

JavaScrptを読み込むHTML(動作確認用)の準備

バンドルして生成したmain.jsを読み込む動作確認用のHTMLを作成します。

src/index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>トップページ</title>

     <!-- defer対応ブラウザの時はこちらを使う-->
     <!-- <script src="../dist/js/main.js" defer></script> -->

  </head>
  <body>

    <!-- defer非対応ブラウザの時はこちらを使う-->
    <script src="../dist/js/main.js"></script>
  </body>
</html>

ビルド

terminal
npm run build

JavaScriptのTranspile

旧ブラウザに対応する必要がある場合、Babelを使ってJavaScriptのバージョンを下げます。
IE11対応

Babelのインストール

terminal
npm i -D babel-loader @babel/core @babel/preset-env
パッケージ 内容
babel-loader webpackでBabelを使えるようにする
@babel/core Babel本体
@babel/preset-env 指定したブラウザ環境で動作するように変換するプラグイン

Babelの設定ファイルを作成

.babelrc
{
  "presets": ["@babel/preset-env"]
}

.browserslistrcの準備

Transpileターゲットのブラウザを指定します。

.browserslistrc
defaults    

.browserslistrcで対象ブラウザを指定する

webpack.config.jsの変更

jsファイルをbabelに渡します。

webpack.config.js
const path = require("path");

module.exports = {
  mode: "production",

  entry: "./src/index.js"

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js"
  },

  module: {
    rules: [

      //追加
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      }

    ]
  }
};

Transpileの動作確認

今回はPolyfillの追加は扱いませんので、with IE(JavaScriptのIE11対応)を参照してください。

index.jsの変更

アロー関数でをTranspileして、IE11で動作確認してみます。

index.js
import { hello } from "./js/sub";

console.log("JavaScript 変換成功");

hello();

//追加
window.addEventListener("load", () => {
  console.log("IE11で表示されたらJavaScript Transpile成功");
});

ビルド

terminal
npm run build

IE11で動作確認

IE11でsrc/index.htmlを開き、「Transpile成功」が表示されればTranspileが出来ていることが確認できました。

TypeScriptファイルのコンパイル、バンドル

今回はPolyfillの追加は扱いませんので、with IE(JavaScriptのIE11対応)を参照してください。

TypeScriptのインストール

terminal
npm i -D typescript ts-loader
パッケージ 内容
typescript TypeScript本体
ts-loader BabelでTypeScriptを読み込めるようにする

webpack.config.jsの変更

tsファイルをts-loaderで読み込む設定を追加します。

webpack.config.js
const path = require("path");

module.exports = {

  mode: "production",

  //エントリーポイントをsrc/index.tsに変更
  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js",
  },

  module: {
    rules: [

      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },

      //追加
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader",
      },

    ],
  },

  //追加 import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"],
  },

};

tsconfig.jsonの作成

プロジェクトルートにTyppeScriptの設定ファイルのtsconfig.jsonを作成します。

tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",//生成するJSモジュールの形式
    "target": "es5",//生成するJSのバージョン
    "noImplicitAny": false,//trueの場合、暗黙的なany型を許容しない
  },
  "exclude": ["node_modules"] //node_modulesフォルダは除外
}

設定はこちらを参照してください。
https://www.typescriptlang.org/ja/tsconfig

TypeScriptファイルの作成

index.tsの作成

src/index.ts
import { hello } from "./ts/sub";

console.log("TypeScript 変換成功");

hello();

window.addEventListener("load", () => {
  console.log("IE11で表示されたらTypeScript Transpile成功");
});

sub.tsの作成

src/ts/sub.ts
export function hello() {
  console.log("TypeScript import成功");
}

ビルド

terminal
npm run build

CSSファイルのバンドル

terminal
npm i -D css-loader style-loader mini-css-extract-plugin
パッケージ 内容
css-loader cssを読み込む
style-loader スタイルを<style>要素としてページに反映させる
mini-css-extract-plugin CSSをJSにバンドルせず、別ファイルにわける

変換するCSSファイルの準備

index.tsの変更

index.tsからcssを読み込みます。

src/index.ts
import { hello } from "./ts/sub";
import "./css/style.css";

console.log("TypeScript 変換成功");

hello();

window.addEventListener("load", () => {
  console.log("IE11で表示されたらTypeScript Transpile成功");
});

style.cssの作成

/src/css/style.css
@import url("sub.css");

.example {
  display: flex;
  color: black;
  width: 100%;
  background-color: red;
}

sub.cssの作成

importしたcssがバンドルされるか確認用のcssを作ります。

/src/css/sub.css
body {
  background-color: green;
}

webpack.config.jsの変更

背景画像などをurlで指定する場合に、エラーにならないように url: falseを指定します。

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

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js",
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader",
      },

      //追加
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },
        ],
      },
    ],
  },
 //追加
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/style.css",
    }),
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"],
  },
};

src/index.htmlの変更

バンドルしたdist/style.cssを読み込みます。

src/index.html
<!DOCTYPE html>
  <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>トップページ</title>

      <!-- 追加 CSSファイルの読み込み -->
      <link rel="stylesheet" href="../dist/css/style.css">


      <!-- defer対応ブラウザの時はこちらを使う-->
      <!-- <script src="../dist/js/main.js" defer></script> -->

    </head>
    <body>

    <!-- defer非対応ブラウザの時はこちらを使う-->
    <script src="../dist/js/main.js"></script>
  </body>
</html>

ビルド

terminal
npm run build

SASSファイルのコンパイル、バンドル

パッケージのインストール

terminal
npm i -D sass-loader node-sass
パッケージ 内容
sass-loader webpackでSASSを読み込めるようにする
node-sass SASSを使えるようにする

index.tsの変更

index.jsからscssを読み込むように変更

src/js/index.js
import { hello } from "./ts/sub";

//CSSからSCSSに変更
//import "./css/style.css";
import "./scss/style.scss";

console.log("TypeScript 変換成功");

hello();

window.addEventListener("load", () => {
  console.log("IE11で表示されたらTypeScript Transpile成功");
});

変換するscssの準備

/src/scss/style.scss
@import "./sub.scss";

.example {
  display: flex;
  color: black;
  width: 100%;
  background-color: red;
}

importしたSCSSがバンドルできるか確認用のSCSS

/src/scss/style.scss
body {
  background-color: green;
}

webpack.config.jsの変更

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

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js",
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader",
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },

          "postcss-loader",
        ],
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },

          "postcss-loader",

          "sass-loader",
        ],
      },
    ],
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/style.css",
    }),
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"],
  },
};

ビルド

terminal
npm run build

PostCSSの使用

パッケージのインストール

terminal
npm i -D postcss postcss-loader
パッケージ 内容
postcss PostCSS本体
postcss-loader webpackでPostCSSを使えるようにする

webpack.config.jsの変更

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

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js",
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader",
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },
          //追加
          "postcss-loader",
        ],
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },
          //追加
          "postcss-loader",

          "sass-loader",
        ],
      },
    ],
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/style.css",
    }),
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"],
  },
};

CSSのプロパティにベンダープレフィックスを付ける

パッケージのインストール

terminal
npm i -D autoprefixer

postcss.config.jsファイルの作成

post-cssの設定ファイル内でautoprefixerを指定します。
AutoprefixerでIE 11対応を行うために、grid: trueを指定してみます。

postcss.config.js
module.exports = {
  plugins: [
    require("autoprefixer")({ grid: true })
  ]
};

対象ブラウザの指定

作成済みであれば不要です。
Babelの項目で.browswerslistrcを作成していないときは、新規に作成します。

.browswerslistrc
ie 11

CSSのminify

devでビルドしたときもminifyします。
不要無い場合は不要です。

パッケージのインストール

terminal
npm i -D cssnano 

postcss.config.jsファイルの変更

post-cssの設定ファイル内でcssnanoを追加します。

postcss.config.js
module.exports = {
  plugins: [
    require("autoprefixer")({ grid: true }), 
    require("cssnano")]
};

プロパティのソート

Stylelintでソートする場合は不要です。

パッケージのインストール

terminal
npm i -D postcss-sorting

postcss.config.jsファイルの変更

post-cssの設定ファイル内でpostcss-sortingを追加

postcss.config.js
module.exports = {
  plugins: [
    require("autoprefixer")({ grid: true }),
    require("cssnano"),
    require("postcss-sorting")({
      "properties-order": ["margin", "padding", "border", "background"]
    })
  ]
};

画像を圧縮する

パッケージのインストール

terminal
npm i -D copy-webpack-plugin imagemin-webpack-plugin imagemin-pngquant imagemin-mozjpeg imagemin-gifsicle imagemin-svgo
パッケージ 内容
copy-webpack-plugin ファイルのコピー
imagemin-webpack-plugin imageminプラグイン本体
imagemin-pngquant pngを圧縮
imagemin-mozjpeg jpgを圧縮
imagemin-gifsicle gifを圧縮
imagemin-svgo svgを圧縮

webpack.config.jsの変更

webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const ImageminMozjpeg = require("imagemin-mozjpeg");

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js",
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader",
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },

          "postcss-loader",
        ],
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },

          "postcss-loader",

          "sass-loader",
        ],
      },
    ],
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/style.css",
    }),

    new CopyPlugin({
      patterns: [
        { from: "src/img", to: "img" },
        { from: "./src/favicon.png", to: "favicon.png" },
        { from: "./src/favicon.svg", to: "favicon.svg" },
      ],
    }),

    new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: "70-80",
      },
      gifsicle: {
        interlaced: false,
        optimizationLevel: 10,
        colors: 256,
      },
      svgo: {},
      plugins: [
        ImageminMozjpeg({
          quality: 85,
          progressive: true,
        }),
      ],
    }),
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
     extensions: [".ts", ".js", ".json"],
  },
};

ビルド

terminal
npm run build

src/img内の画像ファイルと、src/favicon.pngとsrc/favicon.svgがdist配下にコピー、圧縮されます。

Pugのコンパイル

パッケージのインストール

terminal
npm i -D html-webpack-plugin pug-html-loader pug-loader
パッケージ 内容
html-webpack-plugin HTMLファイルを出力
pug-html-loader PugをHTMLに変換
pug-loader webpackでPugを使えるようにする

webpack.config.jsの変更

HTMLは1ファイルにバンドルしないので、個別に指定します。

webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const ImageminMozjpeg = require("imagemin-mozjpeg");

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js",
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader",
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader",
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },

          "postcss-loader",
        ],
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false,
            },
          },

          "postcss-loader",

          "sass-loader",
        ],
      },

      {
        test: /\.pug$/,
        use: [
          {
            loader: "pug-loader",
            options: {
              pretty: true,
            },
          },
        ],
      },
    ],
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/style.css",
    }),

    new CopyPlugin({
      patterns: [
        { from: "src/img", to: "img" },
        { from: "./src/favicon.png", to: "favicon.png" },
        { from: "./src/favicon.svg", to: "favicon.svg" },
      ],
    }),

    new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: "70-80",
      },
      gifsicle: {
        interlaced: false,
        optimizationLevel: 10,
        colors: 256,
      },
      svgo: {},
      plugins: [
        ImageminMozjpeg({
          quality: 85,
          progressive: true,
        }),
      ],
    }),

   //追加
   new HtmlWebpackPlugin({
      template: "./src/pug/index.pug", //変換元のPugファイルの指定
      filename: "index.html", //出力するHTMLのファイル名
      inject: false, //バンドルしたjsファイルを読み込むscriptタグを自動出力しない
      minify: false, //minifyしない
    }),

    //追加
    new HtmlWebpackPlugin({
      template: "./src/pug/sub.pug",
      filename: "sub.html",
      inject: false,
      minify: false,
    }),
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"],
  },
};

pugファイルを作成

src/pug/index.pug
html(lang="ja")
  head
    meta(charset="UTF-8")
    meta(name="viewport", content="width=device-width, initial-scale=1.0")
    title トップページ
    //script(src="./js/main.js" defer)
  body
    p トップページ
    a(href="sub.html") リンク
    img(src="./img/img.jpg")
    script(src="./js/main.js")
    include ./_include/_included.pug
src/pug/test.pug
html(lang="ja")
  head
    meta(charset="UTF-8")
    meta(name="viewport", content="width=device-width, initial-scale=1.0")
    title サブページ
    //script(src="./js/main.js" defer)
  body
    p サブページ
    script(src="./js/main.js")
src\pug\_include\_included.pug
p Include 成功

ビルド

terminal
npm run build

コードの整形、Lint

prettier

インストール

terminal
npm i -D prettier

prettierの設定ファイルの作成

.prettierrc
 {
   "printWidth": 120,
   "tabWidth": 2,
   "singleQuote": false,
   "trailingComma": "none",
   "semi": true,
   "parser": "typescript",
   "endOfLine": "auto"
 }

.prettierrc

eslint

インストール

terminal
npm i -D eslint eslint-loader 

.eslintrc.jsonの作成

.eslintrc.json
{
  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module"
  },

   "env": {
       "browser": true
     },

  "root": true,

  "rules": {
       "quotes": ["error", "single"] //クォーテーションががシングルのときエラー
     }
}

設定はこちらを参照してください。
https://eslint.org/docs/rules/

webpack.config.jsの変更

webpack.config.json
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const ImageminMozjpeg = require("imagemin-mozjpeg");

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js"
  },

  module: {
    rules: [

      //追加
      {
        enforce: "pre",
        test: /\.(js|ts)$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          fix: true, //autofixモードの有効化
          failOnError: true //エラー検出時にビルド中断
        }
      },

      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader"
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader"
        ]
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader",

          "sass-loader"
        ]
      },

      {
        test: /\.pug$/,
        use: [
          {
            loader: "pug-loader",
            options: {
              pretty: true
            }
          }
        ]
      }
    ]
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/style.css"
    }),

    new CopyPlugin({
      patterns: [
        { from: "src/img", to: "img" },
        { from: "./src/favicon.png", to: "favicon.png" },
        { from: "./src/favicon.svg", to: "favicon.svg" }
      ]
    }),

    new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: "70-80"
      },
      gifsicle: {
        interlaced: false,
        optimizationLevel: 10,
        colors: 256
      },
      svgo: {},
      plugins: [
        ImageminMozjpeg({
          quality: 85,
           progressive: true
        })
      ]
    }),
    new HtmlWebpackPlugin({
      template: "./src/pug/index.pug", //変換元のPugファイルの指定
      filename: "index.html", //出力するHTMLのファイル名
      inject: false, //バンドルしたjsファイルを読み込むscriptタグを自動出力しない
      minify: false //minifyしない
    }),
    new HtmlWebpackPlugin({
      template: "./src/pug/sub.pug",
      filename: "sub.html",
      inject: false,
      minify: false
    })
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"]
  }
}

Lint

terminal
//lint
npx eslint src/index.ts

//lint+自動修正
npx eslint src/index.ts --fix

//複数ファイルをlint+自動修正
npx eslint src/**/*.ts --fix

PrettierとEslintの連携

インストール

terminal
npm i -D eslint-plugin-prettier eslint-config-prettier
パッケージ 内容
eslint-plugin-prettier ESLint上でPrettierを動かす
eslint-config-prettier ESLintとPrettierで競合するルールを無効にする

.eslintrc.jsonの変更

.eslintrc.json
{
  //追加
  "extends": ["plugin:prettier/recommended"],

  "parserOptions": {
    "ecmaVersion": 6,
    "sourceType": "module"
  },

  "env": {
    "browser": true
  },

  "root": true,

  "rules": {
    "quotes": ["error", "single"]//クォーテーションががシングルのときエラー
  }

}

stylelint

terminal
npm i -D stylelint stylelint-webpack-plugin stylelint-scss
パッケージ 内容
stylelint Stylelint本体
stylelint-webpack-plugin ビルド時にstylelintを実行
stylelint-scss SCSS用のルールセット

webpack.config.jsの変更

webpack.config.jsにローダーを登録します。

webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const ImageminMozjpeg = require("imagemin-mozjpeg");

const HtmlWebpackPlugin = require("html-webpack-plugin");

const StyleLintPlugin = require("stylelint-webpack-plugin");

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js"
  },

  module: {
    rules: [
      {
        enforce: "pre",
        test: /\.(js|ts)$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          fix: true, //autofixモードの有効化
          failOnError: true //エラー検出時にビルド中断
        }
      },

      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader"
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader"
        ]
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader",

          "sass-loader"
        ]
      },

      {
        test: /\.pug$/,
        use: [
          {
            loader: "pug-loader",
            options: {
              pretty: true
            }
          }
        ]
      }
    ]
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/style.css"
    }),

    new CopyPlugin({
      patterns: [
        { from: "src/img", to: "img" },
        { from: "./src/favicon.png", to: "favicon.png" },
        { from: "./src/favicon.svg", to: "favicon.svg" }
      ]
    }),

    new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: "70-80"
      },
      gifsicle: {
        interlaced: false,
        optimizationLevel: 10,
        colors: 256
      },
      svgo: {},
      plugins: [
        ImageminMozjpeg({
          quality: 85,
          progressive: true
        })
      ]
    }),

    new HtmlWebpackPlugin({
      template: "./src/pug/index.pug", //変換元のPugファイルの指定
      filename: "index.html", //出力するHTMLのファイル名
      inject: false, //バンドルしたjsファイルを読み込むscriptタグを自動出力しない
      minify: false //minifyしない
    }),
    new HtmlWebpackPlugin({
      template: "./src/pug/sub.pug",
      filename: "sub.html",
      inject: false,
      minify: false
    }),

    new StyleLintPlugin({
      configFile: ".stylelintrc",
      fix: true //自動修正可能なものは修正
    })
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"]
  }
}

.stylelintrcの作成

.stylelintrc
{
  "plugins": ["stylelint-scss"], 
  "rules": {
    "at-rule-no-unknown": null,
    "scss/at-rule-no-unknown": true,
    "color-no-invalid-hex": true
  }
}

.stylelintrc

Lint

terminal
//lint
npx stylelint src/scss/style.scss

//lint+自動修正
npx stylelint src/scss/style.scss --fix

//複数ファイルをlint+自動修正
npx stylelint src/scss/**.scss --fix

PrettierとStylelintの連携

インストール

termina
npm i -D stylelint-prettier stylelint-config-prettier
パッケージ 内容
stylelint-prettier Stylelint上でPrettierを動かす
stylelint-config-prettier StylelintとPrettierで競合するルールを無効にする

.stylelintrcの変更

.stylelintrc
{
  "plugins": ["stylelint-scss"], 

  "extends": [
    "stylelint-prettier/recommended",
    "stylelint-config-prettier"
  ],

  "rules": {
    "at-rule-no-unknown": null,
    "scss/at-rule-no-unknown": true,
    "color-no-invalid-hex": true
  }
}

コード整形の除外

.stylelintignore、.prettierignore、.eslintignoreで、除外したいファイルやフォルダを指定できます。
書き方は.gitignoreと同じです。

git commit前にLint

インストール

terminal
npm i -D lint-staged husky
パッケージ 内容
lint-staged ステージングされたファイルにLint
husky gitコマンドをきっかけにして指定したコマンドを実行

package.jsonの変更

package.json
"husky": {
  "hooks": {
    "pre-commit": "lint-staged" // コミット前に以下のコマンドが実行される
  }
}, 
"lint-staged": {
  "*.{ts,tsx}": [
    "tslint --fix",
    "git add"
  ],
  "*.{css,scss}": [
    "stylelint --fix",
    "git add"
  ]
}

distフォルダ内のファイルの削除

srcフォルダ内から削除したファイルから生成したファイルがdistフォルダに残ったままになっていると事故がおこりやすいので、ビルドする度に自動で削除するようにします。

インストール

terminal
npm i -D clean-webpack-plugin

webpack.config.jsの変更

webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const ImageminMozjpeg = require("imagemin-mozjpeg");

const HtmlWebpackPlugin = require("html-webpack-plugin");

const StyleLintPlugin = require("stylelint-webpack-plugin");

//追加
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js"
  },

  module: {
    rules: [
      {
        enforce: "pre",
        test: /\.(js|ts)$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          fix: true, //autofixモードの有効化
          failOnError: true //エラー検出時にビルド中断
        }
      },

      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader"
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader"
        ]
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader",

          "sass-loader"
        ]
      },

      {
        test: /\.pug$/,
        use: [
          {
            loader: "pug-loader",
            options: {
              pretty: true
            }
          }
        ]
      }
    ]
  },

  plugins: [

    //追加
    new CleanWebpackPlugin({ verbose: true }),

    new MiniCssExtractPlugin({
      filename: "css/style.css"
    }),

    new CopyPlugin({
      patterns: [
        { from: "src/img", to: "img" },
        { from: "./src/favicon.png", to: "favicon.png" },
        { from: "./src/favicon.svg", to: "favicon.svg" }
      ]
    }),

    new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: "70-80"
      },
      gifsicle: {
        interlaced: false,
        optimizationLevel: 10,
        colors: 256
      },
      svgo: {},
      plugins: [
        ImageminMozjpeg({
          quality: 85,
          progressive: true
        })
      ]
    }),
    new HtmlWebpackPlugin({
      template: "./src/pug/index.pug", //変換元のPugファイルの指定
      filename: "index.html", //出力するHTMLのファイル名
      inject: false, //バンドルしたjsファイルを読み込むscriptタグを自動出力しない
      minify: false //minifyしない
    }),
    new HtmlWebpackPlugin({
      template: "./src/pug/sub.pug",
      filename: "sub.html",
      inject: false,
      minify: false
    }),

    new StyleLintPlugin({
      configFile: ".stylelintrc",
      fix: true //自動修正可能なものは修正
    })
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"]
  }
};

ソースマップの生成

webpack.config.jsの変更

devtool: "source-map"を追加すると、ビルド時にJSとCSSにソースマップが生成されます。

webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const ImageminMozjpeg = require("imagemin-mozjpeg");

const HtmlWebpackPlugin = require("html-webpack-plugin");

const StyleLintPlugin = require("stylelint-webpack-plugin");

const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  devtool: "source-map",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js"
  },

  module: {
    rules: [
      {
        enforce: "pre",
        test: /\.(js|ts)$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          fix: true, //autofixモードの有効化
          failOnError: true //エラー検出時にビルド中断
        }
      },

      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader"
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader"
        ]
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader",

          "sass-loader"
        ]
      },

      {
        test: /\.pug$/,
        use: [
          {
            loader: "pug-loader",
            options: {
              pretty: true
            }
          }
        ]
      }
    ]
  },

  plugins: [
    new CleanWebpackPlugin({ verbose: true }),

    new MiniCssExtractPlugin({
      filename: "css/style.css"
    }),

    new CopyPlugin({
      patterns: [
        { from: "src/img", to: "img" },
        { from: "./src/favicon.png", to: "favicon.png" },
        { from: "./src/favicon.svg", to: "favicon.svg" }
      ]
    }),

    new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: "70-80"
      },
      gifsicle: {
        interlaced: false,
        optimizationLevel: 10,
        colors: 256
      },
      svgo: {},
      plugins: [
        ImageminMozjpeg({
          quality: 85,
          progressive: true
        })
      ]
    }),

    new HtmlWebpackPlugin({
      template: "./src/pug/index.pug", //変換元のPugファイルの指定
      filename: "index.html", //出力するHTMLのファイル名
      inject: false, //バンドルしたjsファイルを読み込むscriptタグを自動出力しない
      minify: false //minifyしない
    }),
    new HtmlWebpackPlugin({
      template: "./src/pug/sub.pug",
      filename: "sub.html",
      inject: false,
      minify: false
    }),

    new StyleLintPlugin({
      configFile: ".stylelintrc",
      fix: true //自動修正可能なものは修正
    })
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"]
  }
};

ビルド

terminal
npm run build

dist/css/style.css.mapとdist/js/main.js.mapが生成されます。

webpack-dev-server

インストール

terminal
npm i -D webpack-dev-server

webpack.config.jsの変更

devServerの設定を追加します。

webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const ImageminMozjpeg = require("imagemin-mozjpeg");

const HtmlWebpackPlugin = require("html-webpack-plugin");

const StyleLintPlugin = require("stylelint-webpack-plugin");

const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  mode: "production",

  //entry: "./src/index.js",
  entry: "./src/index.ts",

  devtool: "source-map",

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/main.js"
  },

  module: {
    rules: [
      {
        enforce: "pre",
        test: /\.(js|ts)$/,
        exclude: /node_modules/,
        loader: "eslint-loader",
        options: {
          fix: true, //autofixモードの有効化
          failOnError: true //エラー検出時にビルド中断
        }
      },

      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
      },

      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: "ts-loader"
      },

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,

          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader"
        ]
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              url: false
            }
          },

          "postcss-loader",

          "sass-loader"
        ]
      },

      {
        test: /\.pug$/,
        use: [
          {
            loader: "pug-loader",
            options: {
              pretty: true
            }
          }
        ]
      }
    ]
  },

  //追加
  devServer: {
    contentBase: path.resolve(__dirname, "dist"),
    open: true, //起動時にブラウザを開く
    overlay: true //エラーをオーバーレイ表示
  },

  plugins: [
    new CleanWebpackPlugin({ verbose: true }),

    new MiniCssExtractPlugin({
      filename: "css/style.css"
    }),

    new CopyPlugin({
      patterns: [
        { from: "src/img", to: "img" },
        { from: "./src/favicon.png", to: "favicon.png" },
        { from: "./src/favicon.svg", to: "favicon.svg" }
      ]
    }),

    new ImageminPlugin({
      test: /\.(jpe?g|png|gif|svg)$/i,
      pngquant: {
        quality: "70-80"
      },
      gifsicle: {
        interlaced: false,
        optimizationLevel: 10,
        colors: 256
      },
      svgo: {},
      plugins: [
        ImageminMozjpeg({
          quality: 85,
          progressive: true
        })
      ]
    }),

    new HtmlWebpackPlugin({
      template: "./src/pug/index.pug", //変換元のPugファイルの指定
      filename: "index.html", //出力するHTMLのファイル名
      inject: false, //バンドルしたjsファイルを読み込むscriptタグを自動出力しない
      minify: false //minifyしない
    }),
    new HtmlWebpackPlugin({
      template: "./src/pug/sub.pug",
      filename: "sub.html",
      inject: false,
      minify: false
    }),

    new StyleLintPlugin({
      configFile: ".stylelintrc",
      fix: true //自動修正可能なものは修正
    })
  ],

  //import文で拡張子が.tsのファイルを解決する
  resolve: {
    extensions: [".ts", ".js", ".json"]
  }
};

dev-serverの起動

terminal
//webpack4までの場合
npx webpack-dev-server

//webpack5以降の場合
npx webpack serve

webpackの設定ファイルのジェネレータ

Create App

リポジトリ

22
36
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
22
36