#4 Step By Step: Javascript and Css
Friday, August 3, 2018
In this article we start from scratch and will examine what we need to do in order to have webpack create both a javascript and css bundle. We will see all the packages that we need to install from npm as well as their version numbers at the time of the writing of the article. We will also explain the purpose of each entry that we make within our webpack configuration file.
Won't get far without installing Webpack
- WebUi
- package.json
If you have not already created a package.jon file navigate a command propmpt to the root of our project and run
the command npm init -y
. Now that we have a package.json file we need to install
the first two packages into our project using the install command shown in (a). The
versions of the two packages that we just installed are shown in (b). In addition
to the version numbers you should note the key value pair located within the scripts object. With this in place
we will be able to run the command npm run build
when we are ready to trigger
bundling to be performed.
Terminal
npm install --save-dev
webpack
webpack-cli
package.json
{
...
"devDependencies": {
"webpack": "^4.6.0",
"webpack-cli": "^2.1.2"
},
"scripts": {
"build": "set NODE_ENV=development&&webpack --progress"
},
...}
Hello World strikes again
- WebUi
- Source
- index.js
- webpack.config.js
- Source
Now that webpack is installed we need to create a file for us to include in our bundle (c) and the configuration file that webpack will use when creating our bundles (d).
index.js
console.log("hello world");
Our configuration file contains the least amount of information that we need to create our bundles. We start by specifying the location of the name of our bundle and its entry point. This is done via the cleverly named entry object. As you might have guessed the keys within our objects will be the name of our bundles and their values are the locations of the entry points. For now the entry point is a single string but we will soon make it an array of string. Next we have the output object. In the output we tell webpack that the file name should be whatever the key is in the entry object appended with '.bundle.js' and that the path to the bundle will be the js folder contained with a wwwroot folder that itself is contained within our current working directory. Lastly we add the mode to our exports because without it by default webpack will assume we are building a production bundle.
webpack.config.js
const mode = process.env.NODE_ENV || "development";
const entry = {
"index": "./Source/index.js"
}
const output = {
filename: "[name].bundle.js",
path: __dirname + "/wwwroot/js/"
}
module.exports = {
entry,
mode,
output
}
Now that our configuration is made we can have webpack get down to business by using the command
npm run build
that I mentioned previously. Once we do that we should output
in our terminal very similar to (e);

If we look inside the bundle that was just created we should see a whole bunch of bootstrapping code at the top and at the bottom see a function wrapping the code that we created (f).
index.bundle.js
/******/ (function(modules) { // webpackBootstrap
...
/***/ "./Source/index.js":
/*!*************************!*\
!*** ./Source/index.js ***!
\*************************/
/*! no static exports found */
/***/ (function(module, exports) {
eval("console.log(\"hello world\");\n\n//# sourceURL=webpack:///./Source/index.js?");
/***/ })
...
An index file needs an index page
- WebUi
- index.html
Now that we have a bundle we need to create a webpage that we can included it in. For now we will just create a static html page located in the root of our project (g).
index.html
<!DOCTYPE html>
<html>
<head>
<title>Webpack 4 - Step By Step</title>
</head>
<body>
<script src="wwwroot/js/index.bundle.js"></script>
</body>
</html>
Now that the script is included we can take a look in the developer console and we should see our 'hello world' string as shown in (h).

If there was only javascript we would be done
- WebUi
- Source
- index.css
- webpack.config.js
- Source
The next thing we are going to tackle is creating a css bundle. Not suprsingly our first step is to create a css file (i).
index.css
body { background-color: blue; }
Now that we have another file we need to tell webpack that we need to include it within a bundle. To do this we will just return to our config file and modify the entry point to be an array of strings instead of a single string (j).
webpack.config.js
...
const entry = {
"index": ["./Source/index.js", "./Source/index.css"]
}
...
Now if we kick off the building of our bundles again we are unfortunately going to be greeted with a bunch of red text as shown in (k). We are receiving this error because on its own webpack only knows how to deal with javascript. Since we are trying to create a css bundle we need to give it a little help.

Loaders loaders everywhere
- WebUi
- package.json
- webpack.config.js
The way that we tell webpack how to deal with different file types is by using loaders within our configuration file. Bet you can't guess what type of loader we need now. The first loader that we are going to include within our project will be the css loader. You can once again us the terminal to isntall it (l) which again at the time of the writing of this article will import the version shown in (m).
Terminal
npm install --save-dev css-loader
package.json
{
...
"devDependencies": {
"css-loader": "^0.28.11",
},
...
}
Now that the loader is added we need to tell webpack when and how to use it. To do this we specify a new object that we will add to our export (n). As you can see this new object contains a rules array. Each element within the array may contain several properties. Here we are using a regex expression as the test in order to tell webpack when to apply this rule, an exclude regex to tell webpack not to deal with these files, and a use array. The use array may contain any number of loaders which are applied from the top to the bottom.
webpack.config.js
...
const _module = {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
"css-loader"
]
}
]
}
module.exports = {
...,
module: _module,
...
}
If we once again build our bundle and take a look inside in addition to what we had before we
now have an array that corresponds to the content of our index.css
file (o).
index.bundle.js
...
/***/ "./Source/index.css":
/*!**************************!*\
!*** ./Source/index.css ***!
\**************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
eval("exports = module.exports = __webpack_require__(/*! ../node_modules/css-loader/lib/css-base.js */ \"./node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.i, \"body { background-color: blue; }\", \"\"]);\n\n// exports\n\n\n//# sourceURL=webpack:///./Source/index.css?");
/***/ }),
...
Don't want to use a javascript string to style my page
- WebUi
- package.json
- webpack.config.js
Although not impossible at least in this instance we do not want to use the string that is now included within our javascript bundle to style our page. What we want is to create a separate css bundle that we can serve to the page via a link tag. To do that we need to return our saviour npm. The command to install the plugin to extract our css is shown in (p) and its version number at the time of the writing of this article is shown in (q).
Terminal
npm install --save-dev mini-css-extract-plugin
package.json
{
...
"devDependencies": {
"mini-css-extract-plugin": "^0.4.0",
},
...
}
Now that we have installed a plugin the obvious next step is to return to our configuration file. What we need to do is require the plugin and add it to the top of our rule that deals with css files. Once that is done we need to configure the plugin with we do by creating a new plugins object, instantiating an instance of the plugin and including a configuration object when we do so (r).
webpack.config.js
...
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
...
const _module = {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
...
const plugins = [
new MiniCssExtractPlugin({
filename: "../css/[name].bundle.css"
})
];
module.exports = {
...,
plugins
}
Take note of the filename that we have specified for our css bundle. If you remember at the start we specified
that our javascript bundles should be located within a js folder inside of our wwwroot folder. Since I want
the css to live in a css folder that is a sibling of the js folder we simply need to move up one directory
and then into the css folder. Once again we are using the [name]
token so that the key for the entry point is used as the name for our bundle.
Now when we build our bundles we should see in our console that webpack has now emitted two different bundles (s).

Time to style that page
- WebUi
- index.html
Now that we have our css bundle all we need to do is add it to our page using a link tag (t). I am going to refrain from adding an image of the result as I am sure you can guess what it should look like.
index.html
<!DOCTYPE html>
<html>
<head>
...
<link rel="stylesheet" href="wwwroot/css/index.bundle.css">
</head>
...
</html>