Where to Discuss?

Preface

Goal: Put the whole stuff together using webpack bundler.

Source Examples

You can obtain source examples here:


8: Javascript - Compile Coffeescript

Again, consider go back for a while to split assets. Now we are going to bundle a coffeescript assets.

Objective

Bundle Javascript to dist/bundle.js from js/script.coffee

Directory Tree

Using dist/example.html as usual.

Additional file: js/script.coffee.

.
├── css
│   └── style.css
├── dist
│   ├── bundle.js
│   └── example.html
├── js
│   ├── live.js
│   └── script.coffee
├── package.json
└── webpack.config.js

HTML View

The html/index.html contain the dist/bundle.js.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Example Webpack</title>
    <script src="./bundle.js"></script>
    <script src="../js/live.js"></script>
  </head>
  <body>
    ...
  </body>
</html>

Coffeescript

document.addEventListener 'DOMContentLoaded', (event) ->
  alertButtons = document.getElementsByClassName('dismissable')
  i = 0
  while i < alertButtons.length

    alertButtons[i].onclick = ->
      @parentElement.style.display = 'none'
      console.log 'Close Button. Element ' + @parentElement.id + ' dismissed'
      false

    i++
  return

package.json

Additional node module coffee-script and coffee-loader.

  "devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "css-loader": "^3.5.3",
    "style-loader": "^1.2.1",
    "coffee-script": "^1.12.7",
    "coffee-loader": "^0.7.3"
  },

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',
  entry: {
    bundle: [
      "./js/script.coffee",
      "./css/style.css",
    ],
  },
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.coffee$/,
        use: [ 'coffee-loader' ]
      }
    ],
  }  
};

Command Line Interface

Just run the webpack in terminal

$ webpack
Hash: b7252a974bbe17042669
Version: webpack 4.43.0
Time: 1705ms
Built at: 05/09/2020 2:17:19 AM
    Asset      Size  Chunks             Chunk Names
bundle.js  18.1 KiB  bundle  [emitted]  bundle
Entrypoint bundle = bundle.js
[0] multi ./js/script.coffee ./css/style.css 40 bytes {bundle} [built]
[./css/style.css] 519 bytes {bundle} [built]
[./js/script.coffee] 417 bytes {bundle} [built]
[./node_modules/css-loader/dist/cjs.js!./css/style.css] 1.44 KiB {bundle} [built]
    + 2 hidden modules

Webpack: Compile Coffeescript: Running Webpack in Terminal

There is only bundle.js generated.

View in Browser

Check again, if the dismissable button works.

Entry Point in Configuration

The entry point, has been altered into this:

    bundle: [
      "./js/script.coffee",
      "./css/style.css",
    ],

instead of this:

    bundle: [
      "./js/script.js",
      "./css/style.css",
    ],

Loader in Configuration

Also we have this simple coffee-loader rules:

      {
        test: /\.coffee$/,
        use: [ 'coffee-loader' ]
      }

9: Tools: Dev Server

Webpack is equipped by a web server. Instead of browsersync or other simple webserver, you may use webpack-dev-server.

Objective

Serve Development Site, along with livereload.js.

Official Documentation

You should read this first.

Directory Tree

We are going to use, our last 4: Template - HTML example. But this time, without live.js in html/index.html.

Removed file: js/live.js.

.
├── css
│   └── style.css
├── dist
│   ├── bundle.js
│   ├── index.html
│   └── style.js
├── html
│   └── index.html
├── js
│   └── script.js
├── package.json
└── webpack.config.js

package.json

Additional node module coffee-script and coffee-loader.

  "devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0"
  },

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm

module.exports = {
  mode: 'development',
  entry: {
    bundle: "./js/script.js",
    style: "./css/style.css"
  },
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({template: './html/index.html'})
  ],
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000
  }
};

Command Line Interface

Just run the webpack-dev-server in terminal

$ webpack-dev-server
ℹ 「wds」: Project is running at http://localhost:9000/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /home/epsi/Documents/html-basic/04-webpack/51-all/dist
ℹ 「wdm」: Hash: 6edb011f8c5c512539bb
Version: webpack 4.43.0
Time: 7674ms

Webpack Dev Server: Running in Terminal

Livereload

With webpack, we can utilize livereload.js instead of live.js. While live.js attach javascript in source code, livereload utilize websocket protocol.

You can have a look of what is happening on the inside, by using inspect element in your browser.

LiveReload: Websocket in Inspect Element

You should find websocket stuff over there.


10: Putting All Stuff Together

As a summmary, we are going to complete this example, by put a bunch of configuration into one.

Objective

Putting Together, Pug + Stylus + Coffeescript

Directory Tree

This should be self explanatory. A bunch of code, in a blender.

.
├── css
│   └── style.styl
├── dist
│   ├── bundle.js
│   ├── index.html
│   ├── style.css
│   └── style.js
├── js
│   └── script.coffee
├── pug
│   ├── alert.pug
│   └── partials
│       └── body.pug
├── package.json
└── webpack.config.js

Webpack: Nerdtree configuration

package.json

Whoaaa, what a long dependency. We finally made it!

  "devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0",
    "html-webpack-plugin": "^4.3.0",
    "mini-css-extract-plugin": "^0.9.0",
    "css-loader": "^3.5.3",
    "style-loader": "^1.2.1",
    "pug": "^2.0.4",
    "pug-loader": "^2.4.0",
    "stylus": "^0.54.7",
    "stylus-loader": "^3.0.2",
    "coffee-script": "^1.12.7",
    "coffee-loader": "^0.7.3"
  },

webpack.config.js

Tips: Do not get initimidated by long config, once you understand, you can reuse in other project.

And you have a cool configuration too.

const
  path = require('path'),
  HtmlWebpackPlugin = require('html-webpack-plugin'),
  MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  mode: 'development',
  entry: {
    bundle: "./js/script.coffee",
    style: "./css/style.styl"
  },
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.pug$/i,
        use: [
          {
            loader: 'pug-loader',
            options: {
              pretty: true
            }
          }
        ],
      },
      {
        test: /\.styl$/i,
        use: [
          MiniCssExtractPlugin.loader, 
          'css-loader', 
          'stylus-loader'],
      },
      {
        test: /\.coffee$/,
        use: [ 'coffee-loader' ]
      }
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./pug/alert.pug"
    }),
    new MiniCssExtractPlugin({
      filename: "[name].css"
    })
  ],
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    compress: true,
    port: 9000
  }
};

Command Line Interface

Just run the webpack in terminal

$ webpack
Hash: 9f11c9d00cf928503b36
Version: webpack 4.43.0
Time: 5976ms
Built at: 05/09/2020 2:25:36 AM
     Asset      Size  Chunks             Chunk Names
 bundle.js  4.21 KiB  bundle  [emitted]  bundle
index.html  1.31 KiB          [emitted]  
 style.css  1.15 KiB   style  [emitted]  style
  style.js  3.84 KiB   style  [emitted]  style
Entrypoint bundle = bundle.js
Entrypoint style = style.css style.js
[./css/style.styl] 39 bytes {style} [built]
[./js/script.coffee] 417 bytes {bundle} [built]
    + 1 hidden module

Webpack: Putting it all together: Running Webpack in Terminal

Directory Tree Result

You can see the dist directory content here:

Webpack: All: Directory Tree

View in Browser

It is a good time to check again, if everything works fine in browser.

Change in Configuration

The webpack configuration is pretty self-explanatory. All has been discussed, step by step.

I think that’s all about webpack. Now you are ready to generate your static site, without any framework, nor SSG, nor backend.


What’s Next?

Consider continue reading [ Bundler - Rollup - Part One ].