Building Static Sites with Webpack

August 29, 2016

Webpack is module bundler which takes modules with dependencies and generates static assets representing those modules. Webpack replaces gulp/grunt as a task runner. It also enables the ability to use npm packages instead of managing separate js/css files.

Getting Started

In the following folder structure the source code of the site will be placed in the app folder.

.
├── LICENSE
├── README.md
├── app
│ ├── favicon.ico
│ ├── img
│ │
│ ├── index.html
│ ├── js
│ │ ├── imports.js
│ │ └── index.js
│ ├── manifest.json
│ ├── manifest.webapp
│ ├── robots.txt
│ └── scss
│ └── style.scss
├── package.json
└── webpack.config.js

The webpack.config.js file looks like following.

module.exports = {
context: path.resolve("./app"),
entry: "./js/index.js",
output: {
path: path.resolve("./dist/"),
filename: "js/bundle.js",
publicPath: "/",
},
module: {
devtool: "source-map",
loaders: [
{
test: /\\.js$/,
loader: "babel",
exclude: /node\_modules/,
query: {
presets: ["es2015"],
},
},
{
test: /\\.html$/,
loader: "html",
},
{
test: /\\.scss$/,
loaders: ["style", "css", "sass"],
},
{
test: /\\.css$/,
loaders: ["style", "css"],
},
{
test: /\\.woff(2)?(\\?v=\[0-9\]\\.\[0-9\]\\.\[0-9\])?$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff&name=fonts/[name].[ext]",
},
{
test: /\\.(ttf|eot|svg)(\\?v=\[0-9\]\\.\[0-9\]\\.\[0-9\])?$/,
loader: "file?name=fonts/[name].[ext]",
},
{
test: /\\.(jpe?g|png|gif)$/,
loader: "file?name=img/[name].[ext]",
},
],
},
plugins: [
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
template: "./index.html",
}),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
}),
new BrowserSyncPlugin({
server: {
baseDir: ["dist"],
},
port: 3000,
host: "localhost",
}),
new CopyWebpackPlugin([
{
from: "./manifest.json",
},
{
from: "./manifest.webapp",
},
{
from: "./robots.txt",
},
{
from: "./favicon.ico",
},
{
from: "./img/**/*",
to: "./",
},
]),
],
};

entry — the top level file which is the entry point for the application

output

  • path - is the location and name of the directory where the final build folder will be places
  • filename - the name file. You can also specify a folder to place the file in.
  • publicPath — Route to expose for web server to display public paths

module

  • devtool - Define type of sourcemaps
  • loaders - All your loaders will be defined here. We are using babel-loader html-loader, style-loader, css-loader, sass-loader, url-loader and file-loader

plugins

  • clean-webpack-plugin — remove dist directory before each build
  • html-webpack-plugin — create html file for dist with scripts injected based on a template provided
  • provide-plugin — automatically load modules based on the key and value
  • browser-sync-webpack-plugin — Live reloading using browsersync
  • copy-webpack-plugin — copy files and directories to dist folder

After having the webpack file setup you can require dependencies. For example

import "bootstrap/dist/js/bootstrap.js";
import "bootstrap/dist/css/bootstrap.css";
import "../scss/style.scss";
import "font-awesome/css/font-awesome.css";

To start browsersync server run

webpack --watch

which will open the site in default browser which live reloading enabled. It also provides the IP of the machine which can also be using to .

To finally package everything and get it ready to deploy run

webpack -p

which will create a dist folder which can be used to place on web server.

I have created a boilerplate which uses webpack, ES6, bootstrap, fontawesome and browsersync. It can be found on Github. Please check it out and leave your feedback.