Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8589

Web制作向けwebpack

$
0
0

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

package.json

package.jsonの作成

terminal
npm init -y

package.jsonの編集

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

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

webpackのインストール

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

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-loaderwebpackでBabelを使えるようにする
@babel/coreBabel本体
@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
パッケージ内容
typescriptTypeScript本体
ts-loaderBabelで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-loadercssを読み込む
style-loaderスタイルを<style>要素としてページに反映させる
mini-css-extract-pluginCSSを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-loaderwebpackでSASSを読み込めるようにする
node-sassSASSを使えるようにする

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
パッケージ内容
postcssPostCSS本体
postcss-loaderwebpackで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-pluginimageminプラグイン本体
imagemin-pngquantpngを圧縮
imagemin-mozjpegjpgを圧縮
imagemin-gifsiclegifを圧縮
imagemin-svgosvgを圧縮

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-pluginHTMLファイルを出力
pug-html-loaderPugをHTMLに変換
pug-loaderwebpackで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-prettierESLint上でPrettierを動かす
eslint-config-prettierESLintと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
パッケージ内容
stylelintStylelint本体
stylelint-webpack-pluginビルド時にstylelintを実行
stylelint-scssSCSS用のルールセット

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-prettierStylelint上でPrettierを動かす
stylelint-config-prettierStylelintと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
huskygitコマンドをきっかけにして指定したコマンドを実行

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
npx webpack-dev-server

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

Create App

リポジトリ

https://github.com/takeshisakuma/webpack_for_webdesign


Viewing all articles
Browse latest Browse all 8589

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>