Categories
JavaScript webpack

Installing Webpack on Ubuntu 18.04 ( Part II ).

Read responsibly, check out my disclaimer page.

In the last tutorial, Part I, you learned how to install node.js and npm on your Ubuntu system. In this tutorial, we will move forward and install Webpack. This tutorial will only focus on the basic needs to get your project up and running. If you need any additional bells and whistles, then I highly recommend you check out their docs; it’s good; very clear and precise!

A few about dependencies:

For those of you who are unfamiliar with the term, it’s additional software that your project may need to be fully functional. Both the type and the number of dependencies you will need will depend on your project.

You can install webpack globally or locally. This means that you have a choice of installing it system-wide or installing it only in your project directory. This blog will focus on installing it locally.

Setting Up Npm:

We will start by configuring npm. Create a directory; as this will be the home where your project lives :

mkdir <nameOfYourProject>

Lets now change to the directory we created:

cd  <nameOfYourProject>

Now we will need to initialize npm; as we will need to use npm to install webpack and other dependencies; using the following command:

npm init

Once you execute the above command, you will be prompt to answer a few questions; asking for information about your project so it can set up your package.json file. For those of you who want to skip the questions, use the following command:

npm init -–yes

Skipping the questionnaire will force npm to create a default package.json file that looks like this:

{
  "name": "testnpm",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Those of you who want to know how to answer the questions npm asks you, execute the npm init command and answer the following questions when prompted:

Enter a descriptive name for your project. By default, npm will use the name of your directory. Npm will not allow you to enter in any capitalized letters; your name must be in lowercase letters.

package name: (testnpm)

Enter the version number for your project. This is the first version of the project, so I would accept the default version in the parenthesizes by hitting enter.

Version: (1.0.0)

Enter a description for your project (e.g “My first project” ).

Description: My first project

This is where you enter the URL for your git repository (you will either need to create your repository before or after you setup npm. If you don’t plan on using git, just hit enter to go to the next question.)

git repository: https://github.com/<yourUserName>/NameOfYourPackage.git

Your name.

author: RedEyeCoding

Choose the appropriate license for your project or hit enter to select the default.

license: (ISC)

Once completed it will show you an overview of your setup; the contents that your package.json will contain.

{
  "name": "testproject",
  "version": "1.0.0",
  "description": "My first project",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "RedEyeCoding",
  "license": "MIT"
}

Then hit enter to accept. If you execute the ls command in your project directory, you will see the package.json file listed.

Installing webpack:

Lets first install the webpack-cli. The cli for webpack will make your life a little easier when setting up your projects.

Execute the following command:

npm install webpack webpack-cli --save-dev

The webpack-cli is a developer dependency; tools you can use as you progress through your project; it’s not needed to run your application. If you run it without –save-dev, it will save it as a plain’ol dependency. Once you’ve installed webpack and the webpack-cli, you should see the node_module folder appear in your working directory. Verify this with the ls command. Just in case you’re wondering what that folder contains, it’s a folder that contains all the dependencies for your project.

Next, create the directories for both your distribution files and your source files. You can name the folders whatever you want. However, the most publicly known naming convention for the two are dist and src. So let us create those real quick:

mkdir dist && mkdir src 

Now create both the html and JavaScript files; to be placed in the src folder:

touch ./src/index.js && touch ./src/index.html

Open up both the index.js and the index.html files with your favorite text editor and place in the following code:

In your html file:

<!DOCTYPE html>
<html>
  <head>
    <title>Webpack title</title>
  </head>
  <body>
    <div>
      <h1>Hey Webpack, what’s up?</h1>
    </div>
  </body>
</html>

…and in your javaScript file:

function f1(arg){
	return arg;
};
console.log(f1(“If you can see this, then webpack is working!”));

After completing the above, your directory structure should look like the following:

- dist/
- src/
--- index.js
--- index.html
- package.json

Now I’m sure you’re probably used to directly referencing your javascript file like so:

<!DOCTYPE html>
<html>
  <head>
    <title>Webpack title</title>
  </head>
  <body>
    <div>
      <h1>Hey Webpack, what’s up?</h1>
    </div>
	<script src=”./src/index.js”></script>  <-------------
  </body>
</html>

The major problem with manually inserting this information is that you will need to keep track of which javascript file you linked to your html file. However, we won’t need to do that if we’re using webpack; as webpack will auto-magically insert that information for us! 

Configuring webpack:

We will configure webpack using the webpack.config.js file to make sure it has all the information needed so that it can properly bundle our project.

“Wait, why do I need a configuration file? Can’t I just run webpack without it?”

You don’t need a configuration file. However, if you opt out of using one, webpack will assume the following:

  1. Your javascript file is index.js and is located in the src directory.
  2. You have created a dist directory; which it will then use as the destination for the main.js output file.

Now if you don’t mind webpack’s default behavior, then you can skip the configuration section.

So to begin let us create the following file in your project’s home directory:

touch webpack.config.js

Open your webpack configuration file and insert the following code:

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

What does the above mean? Well, the webpack config file is basically saying the following:

require(‘path’):

“I’m a function that comes built into Node.js. What do I do? Well, I give you the ability to extract contents from the module.exports object with your webpack.config.js file. How do I do this? I take a either one or a multiple of <strings> as arguments and return a <string> that represents the absolute path of your file.”

entry:

“Hey webpack, please grab the index.js file, it’s located in the src directory.”

output

“Then I would like for you to bundle everything up, nice & neat. After you do that, I would like the filename that represents that bundle to be called bundle.js; which I will then need for you to place it in my dist folder, thanks!

By default webpack will only bundle your index.js file. It will not bundle your index.html file. Therefore we will need to install and configure a plugin called “HtmlWebpackPlugin”.

npm install --save-dev html-webpack-plugin

Now that you have it installed, you can test things out to make sure that webpack bundles both your html and javascript files.

npx webpack --mode development

Output:

redEyeCoding@ubuntu:~/myproject$ npx webpack 
Hash: 2c84a5236ce7d56aefb0
Version: webpack 4.41.5
Time: 113ms
Built at: 11/16/2019 4:18:50 PM
    Asset       Size  Chunks             Chunk Names
bundle.js  990 bytes       0  [emitted]  main
Entrypoint main = bundle.js
[0] ./src/index.js 101 bytes {0} [built]

Now check the contents of your dist folder:

redEyeCoding@ubuntu:~/myproject$ ls dist
bundle.js
redEyeCoding@ubuntu:~/myproject$ 

Where is the html file? What gives? We will need to install a plugin that will also bundle up our html file! Execute the following:

npm install --save-dev html-webpack-plugin

Then well we need to configure it within the webpack configuration file to get things rolling. Simply declare a variable for your plugin, then add another property within the module.exports object, like-so:

//Here is where you declare your variable
const HtmlWebpackPlugin = require('html-webpack-plugin');

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
//This is where you setup the plugins property
  plugins: [new HtmlWebpackPlugin()] <--------
};

Now lets run it again:

redEyeCoding@ubuntu:~/myproject$ npx webpack 
Hash: 39e416d5751823b15308
Version: webpack 4.41.5
Time: 627ms
Built at: 11/16/2019 4:34:28 PM
     Asset       Size  Chunks             Chunk Names
 bundle.js  990 bytes       0  [emitted]  main
index.html  182 bytes          [emitted]  
Entrypoint main = bundle.js
[0] ./src/index.js 101 bytes {0} [built]

There you have it. Webpack is now bundling both your index.js and index.html files into the dist folder. Lets verify:

redEyeCoding@ubuntu:~/myproject$ ls dist
bundle.js  index.html  //<----That's what we're look'in for
redEyeCoding@ubuntu:~/myproject$ 

Just a moment, folks! Yes webpack is bundling an html file, but is it bundling the correct html file? After executing the npx webpack command, I verified the contents of the html file and it looked like webpack inserted some type of default template instead of the one from my src file. I’m honestly not sure what this happened, but I found a fix for it. You basically will need to pass in an object to the html plugin with filename and template as properties:

  plugins: [
  	new HtmlWebpackPlugin({
  		filename: 'index.html', //<--- 
  		template: './src/index.html' //<---
  	})
  ],

After passing in the object, things should be ok now; webpack should be bundling the correct file.

So this concludes part II for configuring webpack on ubuntu. Part III of this tutorial will go over installing and configuring the webpack-dev-server and will discuss an easier way to bundle your files; who wants to type npx webpack –mode production/development all the time, anyway?

This webpack tutorial getting pretty long. I didn’t anticipate me needing to do more than two parts for this webpack tutorial. As I was typing up this blog post, new things kept popping up that I felt I needed to mention, so to be quite honest, at this point I literally have no idea how many parts this webpack tutorial we be. I guess we’ll both find out!