Skip to main content

Lab-1-4

(2.5% of the course mark)

Express.js Static Lab

  • A hands-on workshop focusing on utilizing Express.js framework to efficiently serve static files such as HTML, CSS, and JavaScript. Participants learn to leverage Express's built-in middleware for static file serving, explore best practices for organizing static assets, and gain practical insights into optimizing performance for web applications. This lab also introduces the following CSS frameworks: Bootstrap, Bulma, and Tailwind.

Lab objectives

  • Mastering the implementation of Express middleware for static file serving.

  • Understanding best practices for organizing and managing static assets within Express.js projects.

  • Optimizing performance strategies for web applications through hands-on exercises and real-world examples.

  • Introduce students on how to setup and use the following CSS frameworks: Bootstrap, Bulma, and Tailwind.

Create an Express.js app

  1. Open VSCode and create a folder named Express-Static-App.

  2. Open the terminal and change the directory to Express-Static-App.

  3. Initialize the app by running the following command:

npm init -y
  1. Install Express.js by running the following command:
npm install express
  1. Create a file named index.js and add the following code:
// Developer:
// Purpose:

const express = require("express");
const app = express();
const port = 3000;
const APP_NAME = "Express-Static-App";

app.use(express.static("public"));

app.get("/", (req, res) => {
res.sendFile(`${__dirname}/public/index.html`);
});

app.listen(port, () => {
console.log(`${APP_NAME} listening on port ${port}`);
});
info
app.use(express.static("public"));

express.static("public") - Is the middleware responsible for serving static files. It uses public as the folder where the other folders and files are located.

  1. Save the changes.

Add nodemon

  1. Install nodemon by running the following command:
npm install -D nodemon
  1. Configure the package.json file by adding a new entry to the scripts property:
"start": "nodemon index.js"
  1. In the terminal, run the following command:
npm run start
  1. Confirm that the terminal output is similar the following image:
nodemon
Benefit of using nodemon

Nodemon restarts your app automatically when it detects file changes, which removes the need to manually stop and restart the server during development.

Add static files

  1. Create the following folders:
Express-Static-App/public
Express-Static-App/public/css
Express-Static-App/public/images
Express-Static-App/public/js
  1. Inside the public folder, create a file named: index.html and create an HTML app that satisfies the following conditions:

    • The HTML app must use a css file and place it inside Express-Static-App/public/css.

    • The HTML app must use an image file and place it inside Express-Static-App/public/images.

    • The HTML app must use a js file and place it inside Express-Static-App/public/js.

  2. Save the changes.

  3. Open your browser and navigate to: http://localhost:3000 It should display the HTML file that was saved inside the public folder. Take a screenshot and save it as public.png.

Add css frameworks route

  1. Update index.js and add a new route with the following code:
app.get("/css-frameworks", (req, res) => {
res.sendFile(`${__dirname}/public/css-frameworks/index.html`);
});
  1. Inside the folder: Express-Static-App/public, create a folder named: css-frameworks.

  2. Inside the folder: Express-Static-App/public/css, create a file named: normalize.css and add the following code:

button,
hr,
input {
overflow: visible;
}
progress,
sub,
sup {
vertical-align: initial;
}
[type="checkbox"],
[type="radio"],
legend {
box-sizing: border-box;
padding: 0;
}
html {
line-height: 1.15;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
details,
main {
display: block;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
hr {
box-sizing: initial;
height: 0;
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
a {
background-color: initial;
}
abbr[title] {
border-bottom: none;
text-decoration: underline;
text-decoration: underline dotted;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
img {
border-style: none;
}
button,
input,
optgroup,
select,
textarea {
font-family: inherit;
font-size: 100%;
line-height: 1.15;
margin: 0;
}
button,
select {
text-transform: none;
}
[type="button"],
[type="reset"],
[type="submit"],
button {
-webkit-appearance: button;
}
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner,
button::-moz-focus-inner {
border-style: none;
padding: 0;
}
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring,
button:-moz-focusring {
outline: ButtonText dotted 1px;
}
fieldset {
padding: 0.35em 0.75em 0.625em;
}
legend {
color: inherit;
display: table;
max-width: 100%;
white-space: normal;
}
textarea {
overflow: auto;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
summary {
display: list-item;
}
[hidden],
template {
display: none;
}
  1. Inside the folder: Express-Static-App/public/css, create a file named: sakura.css and add the following code:
h1,
h2,
h3,
h4,
h5,
h6,
html {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica
Neue, Arial, Noto Sans, sans-serif;
}
img,
p,
pre,
ul,
video {
margin-top: 0;
margin-bottom: 2.5rem;
}
blockquote,
img,
p,
pre,
ul,
video {
margin-bottom: 2.5rem;
}
table,
textarea {
width: 100%;
}
html {
font-size: 62.5%;
}
body {
background-color: #f9f9f9;
color: #4a4a4a;
font-size: 1.8rem;
line-height: 1.618;
margin: auto;
max-width: 38em;
padding: 13px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 700;
line-height: 1.1;
margin-bottom: 1.5rem;
margin-top: 3rem;
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
}
h1 {
font-size: 2.35em;
}
h2 {
font-size: 2em;
}
h3 {
font-size: 1.75em;
}
h4 {
font-size: 1.5em;
}
h5 {
font-size: 1.25em;
}
h6,
pre > code {
font-size: 1em;
}
small,
sub,
sup {
font-size: 75%;
}
hr {
border-color: #1d7484;
}
a {
color: #1d7484;
text-decoration: none;
}
a:visited {
color: #144f5a;
}
a:hover {
border-bottom: 2px solid #4a4a4a;
color: #982c61;
}
ul {
padding-left: 1.4em;
}
li {
margin-bottom: 0.4em;
}
blockquote {
background-color: #f1f1f1;
border-left: 5px solid #1d7484;
margin-left: 0;
margin-right: 0;
padding: 0.8em 0.8em 0.8em 1em;
}
blockquote p {
margin-bottom: 0;
}
img,
video {
height: auto;
max-width: 100%;
}
pre {
display: block;
overflow-x: auto;
padding: 1em;
}
code,
kbd,
pre,
samp {
background-color: #f1f1f1;
font-size: 0.9em;
}
code,
kbd,
samp {
padding: 0 0.5em;
white-space: pre-wrap;
}
pre > code {
background-color: initial;
padding: 0;
white-space: pre;
}
table {
border-collapse: collapse;
margin-bottom: 2rem;
text-align: justify;
}
td,
th {
border-bottom: 1px solid #f1f1f1;
padding: 0.5em;
}
.button,
button,
input[type="button"],
input[type="file"]::file-selector-button,
input[type="reset"],
input[type="submit"] {
background-color: #1d7484;
border: 1px solid #1d7484;
border-radius: 1px;
box-sizing: border-box;
color: #f9f9f9;
cursor: pointer;
display: inline-block;
padding: 5px 10px;
text-align: center;
text-decoration: none;
white-space: nowrap;
}
.button[disabled],
button[disabled],
input[type="button"][disabled],
input[type="file"]::file-selector-button[disabled],
input[type="reset"][disabled],
input[type="submit"][disabled] {
cursor: default;
opacity: 0.5;
}
.button:hover,
button:hover,
input[type="button"]:hover,
input[type="file"]::file-selector-button:hover,
input[type="reset"]:hover,
input[type="submit"]:hover {
background-color: #982c61;
color: #f9f9f9;
outline: 0;
}
.button:focus-visible,
button:focus-visible,
input[type="button"]:focus-visible,
input[type="file"]::file-selector-button:focus-visible,
input[type="reset"]:focus-visible,
input[type="submit"]:focus-visible {
outline-style: solid;
outline-width: 2px;
}
input,
select,
textarea {
background-color: #f1f1f1;
border: 1px solid #f1f1f1;
border-radius: 4px;
box-shadow: none;
box-sizing: border-box;
color: #4a4a4a;
margin-bottom: 10px;
padding: 6px 10px;
}
input:focus,
select:focus,
textarea:focus {
border: 1px solid #1d7484;
outline: 0;
}
input[type="checkbox"]:focus {
outline: #1d7484 dotted 1px;
}
fieldset,
label,
legend {
display: block;
font-weight: 600;
margin-bottom: 0.5rem;
}
@media (max-width: 684px) {
body {
font-size: 1.53rem;
}
}
@media (max-width: 382px) {
body {
font-size: 1.35rem;
}
}
  1. Inside the folder: Express-Static-App/public/css-frameworks, create a file named: index.html and add the following code:
<!--
Developer:
Purpose:
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>CSS Frameworks</title>
<link rel="stylesheet" href="../css/normalize.css" />
<link rel="stylesheet" href="../css/sakura.css" />
</head>

<body>
<h1>CSS Frameworks</h1>

<section>
<h2><a href="bootstrap.html">Bootstrap</a></h2>
</section>

<section>
<h2><a href="bulma.html">Bulma</a></h2>
</section>

<section>
<h2><a href="tailwind.html">Tailwind</a></h2>
</section>
</body>
</html>
  1. Save the changes.

  2. Open your browser and navigate to: http://localhost:3000/css-frameworks It should display the HTML file that was saved inside the public/css-frameworks folder. Take a screenshot and save it as public-css-frameworks.png.

Add Bootstrap

  1. Inside the folder: Express-Static-App/public/css-frameworks, create a file named: bootstrap.html and copy the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Bootstrap Demo</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container">
<h1>Bootstrap Demo</h1>
<div class="alert alert-primary" role="alert">alert alert-primary</div>
<div class="alert alert-secondary" role="alert">
alert alert-secondary
</div>
<div class="alert alert-success" role="alert">alert alert-success</div>
<div class="alert alert-danger" role="alert">alert alert-danger</div>
<div class="alert alert-warning" role="alert">alert alert-warning</div>
<div class="alert alert-info" role="alert">alert alert-info</div>
<div class="alert alert-light" role="alert">alert alert-light</div>
<div class="alert alert-dark" role="alert">alert alert-dark</div>
</div>

<!-- This is optional -->
<script
src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
crossorigin="anonymous"
></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.min.js"
integrity="sha384-G/EV+4j2dNv+tEPo3++6LCgdCROaejBqfUeNjuKAiuXbjrxilcCdDz6ZAVfHWe1Y"
crossorigin="anonymous"
></script>
</body>
</html>
  1. Save the changes.

  2. Open your browser and navigate to: http://localhost:3000/css-frameworks and click on Bootstrap. Take a screenshot and save it as public-css-frameworks-bootstrap.png.

  3. Bootstrap has many built-in components. Customise a built-in component of your choice and add the code on a file named: bootstrap-component.html inside the folder: Express-Static-App/public/css-frameworks.

  4. Save the changes.

  5. Open your browser and navigate to: http://localhost:3000/css-frameworks/bootstrap-component.html. Take a screenshot and save it as public-css-frameworks-bootstrap-component.png.

Add Bulma

  1. Inside the folder: Express-Static-App/public/css-frameworks, create a file named: bulma.html and add the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Bulma Demo</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bulma@1.0.4/css/bulma.min.css"
/>
</head>
<body>
<section class="section">
<h1 class="is-size-1">Bulma Demo</h1>
<div class="container">
<div class="notification is-primary">notification is-primary</div>
<div class="notification is-info">notification is-info</div>
<div class="notification is-success">notification is-success</div>
<div class="notification is-warning">notification is-warning</div>
<div class="notification is-danger">notification is-danger</div>
<div class="notification is-white">notification is-white</div>
<div class="notification is-black">notification is-black</div>
</div>
</section>
</body>
</html>
  1. Save the changes.

  2. Open your browser and navigate to: http://localhost:3000/css-frameworks and click on Bulma. Take a screenshot and save it as public-css-frameworks-bulma.png.

  3. Bulma has many built-in components. Customise a built-in component of your choice and add the code on a file named: bulma-component.html inside the folder: Express-Static-App/public/css-frameworks.

  4. Save the changes.

  5. Open your browser and navigate to: http://localhost:3000/css-frameworks/bulma-component.html. Take a screenshot and save it as public-css-frameworks-bulma-component.png.

Add Tailwind

  1. Inside the folder: Express-Static-App/public/css-frameworks, create a file named: tailwind.html and add the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tailwind Demo</title>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
</head>
<body>
<div class="m-4">
<h1 class="mb-2 text-3xl font-bold">Tailwind Demo</h1>

<div
class="mb-2 px-4 py-3 rounded bg-blue-100 border border-blue-300 text-blue-900 text-sm"
>
mb-2 px-4 py-3 rounded bg-blue-100 border border-blue-300 text-blue-900
text-sm
</div>

<div
class="mb-2 px-4 py-3 rounded bg-green-100 border border-green-300 text-green-900 text-sm"
>
mb-2 px-4 py-3 rounded bg-green-100 border border-green-300
text-green-900 text-sm
</div>

<div
class="mb-2 px-4 py-3 rounded bg-yellow-100 border border-yellow-300 text-yellow-900 text-sm"
>
mb-2 px-4 py-3 rounded bg-yellow-100 border border-yellow-300
text-yellow-900 text-sm
</div>

<div
class="mb-2 px-4 py-3 rounded bg-red-100 border border-red-300 text-red-900 text-sm"
>
mb-2 px-4 py-3 rounded bg-red-100 border border-red-300 text-red-900
text-sm
</div>

<div
class="mb-2 px-4 py-3 rounded bg-gray-100 border border-gray-300 text-gray-900 text-sm"
>
mb-2 px-4 py-3 rounded bg-gray-100 border border-gray-300 text-gray-900
text-sm
</div>

<div
class="mb-2 px-4 py-3 rounded bg-indigo-100 border border-indigo-300 text-indigo-900 text-sm"
>
mb-2 px-4 py-3 rounded bg-indigo-100 border border-indigo-300
text-indigo-900 text-sm
</div>
</div>
</body>
</html>
  1. Save the changes.

  2. Open your browser and navigate to: http://localhost:3000/css-frameworks and click on Tailwind. Take a screenshot and save it as public-css-frameworks-tailwind.png.

  3. Tailwind does not have built-in components in a traditional way, however what they have are ui-blocks: https://tailwindcss.com/plus/ui-blocks. Customise a ui-block of your choice and add the code on a file named: tailwind-ui-block.html inside the folder: Express-Static-App/public/css-frameworks.

  4. Save the changes.

  5. Open your browser and navigate to: http://localhost:3000/css-frameworks/tailwind-ui-blocks.html. Take a screenshot and save it as public-css-frameworks-tailwind-ui-blocks.png.

Using sakura.css and normalize.css

  1. Open VSCode and create a folder named app.

  2. Download the files sakura.css and normalize.css and save them to the app folder. Make sure to rename them to sakura.css and normalize.css.

  3. Copy public.png, public-css-frameworks.png, public-css-frameworks-bootstrap.png, public-css-frameworks-bootstrap-component.png, public-css-frameworks-bulma.png, public-css-frameworks-bulma-component.png, public-css-frameworks-tailwind.png and public-css-frameworks-tailwind-ui-blocks.png to the app folder.

  4. In the app folder create a file named: lab-1-4.html and add following the HTML code:

<!--
Developer:
Purpose:
-->

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- Update title -->
<title></title>
<!-- Reset styles using normalize -->
<link rel="stylesheet" href="./normalize.css" />
<!-- Classless css -->
<link rel="stylesheet" href="./sakura.css" />
</head>
<body>
<!-- Enter the HTML codes to display the captured screenshots -->
</body>
</html>
  1. For each screenshot implement the HTML codes to display the title, short description, and screenshot image.

Submission

  1. Create a folder named submit.
Delete node_modules

Delete the node_modules folder on any app that you are submitting.

  1. Copy the Express-Static-App and app folders to the submit folder.

  2. Create a zip file of the submit folder.

  3. Navigate back to where the lab was originally downloaded, there should be a Submissions section (see below) where the zip file can be uploaded.

submission