emahiro/b.log

日々の勉強の記録とか育児の記録とか。

webpackでhtmlファイルも出力する

ema-hiro.hatenablog.com

昨日の上記エントリへの追記

TODO

  • htmlファイルをdist以下に作成していましたが、frontendのファイルはsrc以下に管理します。
  • webpackでコンパイルしたらdist以下にhtmlファイルも出力させます
  • html-webpack-pluginを使います

install

$ yarn add -D html-webpack-plugin
$ yarn add -D html-loader

webpack.config.js

html-webpack-pluginhtml-loader を加えてコンパイルの設定を更新する

const src = __dirname + "/src";
const dist = __dirname + "/dist"

var webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  context: src,
  entry: "./js/index.js",
  output: {
    path: dist,
    filename: "index.min.js"
  },
  devServer: {
    contentBase: dist,
    port: 3000
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude:/node_modules/,
        loader: "babel-loader",
        query: {
          presets:[
            ["env", {
              "targets": {
                "node": "current"
              }
            }]
          ]
        }
      },
      {
        test: /\.html$/,
        loader: "html-loader"
      }
    ]
  },
  plugins: [
    new UglifyJSPlugin(),
    new HtmlWebpackPlugin({
      template: "./html/index.html"
    })
  ]
};

ディレクトリの変更

- root
  - src
    - js
      - index.js
    - html
      - index.html
  - dist
    - 出力先

index.htmlを作成する

src/html/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test</title>
  </head>
  <body>
    hello world
  </body>
</html>

コンパイルする

$ yarn run build
yarn run v1.1.0
$ yarn run --config webpack
Hash: 1c4cb048a83c8c452b7b
Version: webpack 3.6.0
Time: 577ms
       Asset       Size  Chunks             Chunk Names
index.min.js  814 bytes       0  [emitted]  main
  index.html  195 bytes          [emitted]
   [0] ./js/index.js 400 bytes {0} [built]
   [1] ./js/person.js 171 bytes {0} [built]
Child html-webpack-plugin for "index.html":
     1 asset
       [0] ../node_modules/html-webpack-plugin/lib/loader.js!./html/index.html 168 bytes {0} [built]
✨  Done in 1.71s.

buildpackage.json で新しくscriptsに追加したカスタムビルドコマンド

生成された index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>test</title>
  </head>
  <body>
    hello world
  <script type="text/javascript" src="index.min.js"></script></body>
</html>

コンパイルした index.min.jsscript タグに入ってちゃんと生成されている。

この状態で webpack-dev-server を動かしてちゃんと動作するかを確認する

おまけ

複数のhtmlファイルをコンパイルしたい

refs: https://github.com/jantimon/html-webpack-plugin#generating-multiple-html-files

SPAならindex.htmlだけ作成してそこにSPAの要素を追加していくのもありであるが、複数のhtmlファイルを出力したい場合がある。 そういう場合は html-webplack-plugin はデフォでは index.html しか出力しないが、別のファイルを新しくpluginで指定してfile名とコンパイル対象のtemplateを指定すれば良い。

// 略
plugins: [
  // index
  new HtmlWebpackPlugin({
    template: "./html/index.html"
  }),
  // その他
  new HtmlWebpackPlugin({
    filename: "admin.html",
    template: "./html/admin.html"
  })
]
$ ls dist/
admin.html  index.html

htmlファイルが複数出力されている

所感

webpack一発でフロントエンドの環境が構築されるっていうのはこういうことかってわかってきた。
今回はベタなhtmlをそのままコンパイルしているがテンプレ(ejsファイルとか)をコンパイルすることも可能