Preface
Goal: Bundle Pug + Stylus + Coffeescript together, using webpack.
While the previous grunt
article target is conservative web development,
now comes the time for webpack
targeting modern web development.
Source Examples
You can obtain source examples here:
![Webpack: Nerdtree configuration][41-nerdtree-webpack]
Example: In a Nutshell
Webpack is a bundler.
How does it looks like?
Supposed that you have these source assets:
├── css
│ └── style.styl
├── js
│ └── script.coffee
└── pug
├── alert.pug
└── partials
└── body.pug
All the sources, including pug
, stylus
, and coffeescript
,
will be bundled into one bundle.js
and one index.html
.
└── dist
├── bundle.js
└── index.html
It means, the stylesheet also included,
as a part of javascript bundle.js
.
I hope this explains 🙏🏽.
Official Documentation
You should read this first.
This article is useless if you never touch the official documentation.
Credits
I’m not an expert on webpack. In fact I don’t get what webpack is all about, after reading the good official documentation. One day, my friend in a local group gave me, a short example of webpack configuration, that turn the lights on my brain. So, thank you, Alfian Hidayat. You make these webpack article happened.
Learn by Example
If in the past we learn that, we can put assets as inline, internal, or external file. With webpack we can put assets as bundle. It means we can put stylesheet in javascript, along with all other js script.
Just like grunt
, webpack can translate template,
such as pug
to html
, stylus
to css
,
coffeescript
to javascript
and so on.
Webpack as a bundler is more than just template preprocessor.
Rendering webpack
is useful,
when it comes to SPA (Single Page Application).
But for a starter, this article only cover this preprocessor stuff.
Any beginner can dive deeper later to enhance their knowledge.
This article use previous example,
converted to webpack
configuration,
explained step by step.
1: Preparation
For each step, we are going to need these
-
package.json
, and -
webpack.config.js
-
Assets in respective directory, such as
js
,css
and so on. -
Output directory, in this example is
dist
.
package.json
All you need to know is each step has different devDependencies
.
"devDependencies": {
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},
To begin with each step, you need to run npm install
first.
Directory Tree
Our preparation example only have to files.
-
js/script.js
with the same content with our previous article. -
dist/bundle.js
generated by webpack later. You can removedist/bundle.js
anytime.
$ tree
.
├── dist
│ └── bundle.js
├── js
│ └── script.js
├── package.json
└── webpack.config.js
2 directories, 4 files
Th example script.js
contain this file:
document.addEventListener("DOMContentLoaded", function(event) {
var alertButtons = document.getElementsByClassName("dismissable");
for (var i=0; i < alertButtons.length; i++) {
alertButtons[i].onclick = function() {
this.parentElement.style.display='none';
console.log('Close Button. Element ' + this.parentElement.id + ' dismissed');
return false;
};
};
});
webpack.config.js
A typical configuration is shown as below.
const path = require('path');
module.exports = {
mode: 'development',
entry: {
bundle: [
"./js/script.js"
],
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, 'dist'),
}
};
Now you can run webpack
in your favorite terminal.
$ webpack
Hash: 7c1326f6ac166c3d0b5f
Version: webpack 4.43.0
Time: 126ms
Built at: 05/09/2020 12:27:01 AM
Asset Size Chunks Chunk Names
bundle.js 4.62 KiB bundle [emitted] bundle
Entrypoint bundle = bundle.js
[0] multi ./js/script.js 28 bytes {bundle} [built]
[./js/script.js] 515 bytes {bundle} [built]
As you can see, the webpack
generate bundle.js
,
that contain long lines, and also this lines somewhere.
eval("(function() {\n document.addEventListener('DOMContentLoaded', function(event) ...
I think that’s enough about preparation.
2: Assets - Bundle
Consider start with example.
Objective
Bundle both the
css/style.css
andjs/script.js
stylesheet intodist/bundle.js
Directory Tree
Additional file: css/style.css
.
.
├── css
│ └── style.css
├── dist
│ ├── bundle.js
│ └── example.html
├── js
│ ├── live.js
│ └── script.js
├── package.json
└── webpack.config.js
HTML View
I create dist/example.html
manually,
so you examine the bundle result in page.
I also utilize live.js
so the page refreshed automatically,
while using simple web server such as browsersync
.
<!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>
Stylesheet
...
.red {
color: #fff !important;
background-color: #f44336 !important;
}
...
package.json
Additional node modules css-loader
and style-loader
.
"devDependencies": {
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"css-loader": "^3.5.3",
"style-loader": "^1.2.1"
},
webpack.config.js
The configuration has one entry point: the bundle
.
const path = require('path');
module.exports = {
mode: 'development',
entry: {
bundle: [
"./js/script.js",
"./css/style.css",
],
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
};
Command Line Interface
Just run the webpack
in terminal
$ webpack
Hash: b13fabe1718a323be83c
Version: webpack 4.43.0
Time: 1243ms
Built at: 05/09/2020 12:49:18 AM
Asset Size Chunks Chunk Names
bundle.js 18.1 KiB bundle [emitted] bundle
Entrypoint bundle = bundle.js
[0] multi ./js/script.js ./css/style.css 40 bytes {bundle} [built]
[./css/style.css] 519 bytes {bundle} [built]
[./js/script.js] 515 bytes {bundle} [built]
[./node_modules/css-loader/dist/cjs.js!./css/style.css] 1.44 KiB {bundle} [built]
+ 2 hidden modules
View in Browser
Run your browsersync
or just open the example.html
from file manager.
You will see something similar like this below:
Have a look at the source code,
the stylesheet is written inside javascript instead of CSS
file.
Entry Point in Configuration
The webpack configuration is pretty self-explanatory. Of course, with assumption that the audience of this article, has ability to read official documentation.
The entry point, has been altered into this:
entry: {
bundle: [
"./js/script.js",
"./css/style.css",
],
},
Instead of the previous one below.
entry: {
bundle: [
"./js/script.js"
],
},
Loader in Configuration
Also you need rules in modules that use both style-loader
and css-loader
.
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
3: Assets - Split
Objective
Split
css/style.css
intodist/style.js
Directory Tree
Additional output: dist/style.js
.
.
├── css
│ └── style.css
├── dist
│ ├── bundle.js
│ ├── example.html
│ └── style.js
├── js
│ ├── live.js
│ └── script.js
├── package.json
└── webpack.config.js
The webpack
should generate two files:
dist/bundle.js
, anddist/style.js
, and
HTML View
I add style.js
in header of dist/example.html
manually,
so that the page have stylesheet.
<head>
<meta charset="utf-8">
<title>Example Webpack</title>
<script src="./bundle.js"></script>
<script src="./style.js"></script>
<script src="../js/live.js"></script>
</head>
package.json
Still the same package.json
.
with these two css-loader
and style-loader
.
"devDependencies": {
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"css-loader": "^3.5.3",
"style-loader": "^1.2.1"
},
webpack.config.js
The configuration has two entry point: bundle
and style
.
const path = require('path');
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'],
},
],
}
};
Command Line Interface
Just run the webpack
in terminal
❯ webpack
Hash: 2d794c3b85947839df0a
Version: webpack 4.43.0
Time: 1332ms
Built at: 05/09/2020 1:04:40 AM
Asset Size Chunks Chunk Names
bundle.js 4.29 KiB bundle [emitted] bundle
style.js 16.9 KiB style [emitted] style
Entrypoint bundle = bundle.js
Entrypoint style = style.js
[./css/style.css] 519 bytes {style} [built]
[./js/script.js] 515 bytes {bundle} [built]
[./node_modules/css-loader/dist/cjs.js!./css/style.css] 1.44 KiB {style} [built]
+ 2 hidden modules
As you can see, the webpack
generate two js
files.
View in Browser
If evertyhing goes well, the result in browser should show similar looks, and the dismissable button should works too.
Entry Point in Configuration
The entry point, has been altered into this:
entry: {
bundle: "./js/script.js",
style: "./css/style.css"
},
Instead of the previous one below.
entry: {
bundle: [
"./js/script.js",
"./css/style.css",
],
},
That is all.
What’s Next?
Consider continue reading [ Bundler - Webpack - Part Two ].