Set Up Webpack To Work With Static Files by@matheus4lves

Set Up Webpack To Work With Static Files

image
Matheus Alves HackerNoon profile picture

Matheus Alves

(Almost) A computer engineer...

Hi! In this tutorial, I’m gonna show you how you can configure a webpack if you want to serve static files in your application. Besides, you’ll also learn:

  • How to handle CSS files;

First, let’s create the structure of our project:

image

Now, let’s create a package.json file with the following command:

npm init -y

And install the packages we need now:

npm install --save-dev webpack webpack-cli webpack-dev-server

According to the official documentation,

Since version 4.0.0, webpack does not require a configuration file to bundle your project. Nevertheless, it is incredibly configurable to better fit your needs.

In order to config webpack we need to create a configuration file at the root of the project:

touch webpack.config.js

Notice that I did it using the command line (Ubuntu terminal) but you can do it through the IDE or text editor of your choice. I’m using VS Code here:

image

Add this code to index.html:

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="assets/styles/styles.css" />
  </head>
  <body>
    <div class="container">
      <div class="text-contents">
        <h3 class="heading">Knowledge</h3>
        <p class="paragraph">Update me!</p>
      </div>
      <img src="assets/images/bookshelf.png" alt="" />
    </div>
  </body>
</html>

And this to styles.css:

.container {
  display: grid;
  padding: 15px;
  justify-items: center;
  align-content: center;
  height: 100%;
}

.text-contents {
  position: relative;
  align-self: center;
  justify-self: center;
  color: #005f73;
  background: url("../images/freedom.png") no-repeat center;
  background-size: 80%;
  width: 400px;
  height: 200;
}

.heading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.paragraph {
  position: absolute;
  top: 68%;
  left: 50%;
  transform: translate(-50%, -50%);
}

p,
h1 {
  margin: 0;
  padding: 0;
}

img {
  max-width: 50%;
}

After that, you can drag and drop the index.html file over your browser. You should see this:

image

It is time to config webpack accordingly to our needs. To do so, open the webpack.config.js file and add this line:

module.exports = {}

When we start webpack, it will look for its configuration file (webpack.config.js). This file will export an object that has all configurations.

The first property we need to add to that object is the entry point:

module.exports = {
  entry: "./app/assets/scripts/index.js",
};

An entry point indicates which module webpack should use to begin building out its internal dependency graph. Webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly).

To better understand what the documentation says, let’s add this line to index.js:

import "../styles/styles.css";

Since we’re importing styles.css, webpack will add that module to the dependency graph. That file is a direct dependency. Now, let’s suppose that inside the styles.css file we had something like this:

@import "molules/_primary-nav.css";

The primary-nav.css file would be an indirect dependency, because the index.css depends on styles.css, which in turn depends on _primary-nav.css.

Now, we need to add the output property:

const path = require("path");

module.exports = {
  entry: "./app/assets/scripts/index.js",
  output: {
    path: path.resolve(__dirname, "app"),
    filename: "bundle.js",
  },
};

The output property is also an object. We’ll config two properties of it: path and filename.

The first property specifies where the bundle should be emitted to and the second is the name of the bundled file. Since an absolute path is required, we had to require path, which is a core library of Node.js.

NOTE: Although we specify where the bundle should be emitted, webpack does not write it to disk unless we say so. It actually keeps the bundle in memory to work faster.

Right now we can start webpack-dev-server without any configuration. It’ll result in some errors that we’ll tackle soon. To do that, open the package.json file and add this line inside the scripts area:

"dev": "webpack serve"

After that, open the VS Code terminal (Ctrl + j) and type:

npm run dev

Press Enter/Return and wait. The server won't stop until you say so and webpack will try to bundle and serve the contents at localhost:8080, by default.

Since our configuration is incomplete, if you visit that address you should see this message: “Cannot GET /”.

You should see the following in the VS Code terminal:

image

Webpack is warning that we haven’t set up the mode option. To fix that, set the mode to be “development”:

const path = require("path");

module.exports = {
  entry: "./app/assets/scripts/index.js",
  output: {
    path: path.resolve(__dirname, "app"),
    filename: "bundle.js",
  },
  mode: "development"
};

Stop the server (Ctrl + c), save the file, and start it again.

This is what we get now:

image

We’ll fix that in the next section. If you need, take a break, drink some coffee and come back.


Handling CSS files

Ready? Let’s code!

Out of the box, webpack understands only .js files. That’s why we need to install some loaders to make it work with CSS. The configuration file should be updated with the module object:

const path = require("path");

module.exports = {
  entry: "./app/assets/scripts/index.js",
  output: {
    path: path.resolve(__dirname, "app"),
    filename: "bundle.js",
  },
  mode: "development",
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

Don’t forget to install those packages running this:

npm install --save-dev style-loader css-loader

Stop and start the server again. This is what you should see in the terminal:

image


The devServer configuration

Before setting up webpack-dev-server, add this line inside index.html:

<script src="./bundle.js"></script>

You should put it just above the closing </body> tag.

Then, add the devServer object inside the configuration file:

const path = require("path");

module.exports = {
  entry: "./app/assets/scripts/index.js",
  output: {
    path: path.resolve(__dirname, "app"),
    filename: "bundle.js",
  },
  mode: "development",
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  devServer: {
    port: 3000,
    static: {
      directory: path.join(__dirname, "app"),
    },
  },
};

The directory property is used to tell the server where to look for the index.html file.

When you visit localhost:3000 (The specified port) you’ll see our page!

Now, if you go to the index.html file, change the paragraph and save it, webpack-dev-server will automatically reload the page and you’ll see the changes in your browser.

As a test, change the paragraph to the following:

 <p class="paragraph"> = freedom</p>

As I said, as soon as you hit Ctrl + s, you’ll see the page auto-update. Below is the final result:

image

Try changing the styles and see the magic happen.

I hope this tutorial was useful for you. Thanks for reading! You can find the source code of this project at this repo: https://github.com/matheus4lves/serve-static-files.

Tags