NPM Scripts

Defining Scripts

For development purposes, we might want to define a global way of running our application, so that we can have a consistent way of running, developing and building our application, regardless of the machine or developer.

{
  "type": "module",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "dependencies": {
    "express": "5.2.1"
  }
}

Running Scripts

The scripts can be run by running the following in the terminal:

npm run <name-of-script>

We do this because it gives a standardized, project-local way of running commands.

Environment Variables

What Are Environment Variables

Sometimes we need to set values that is set outside the application, that are used to configure behavior, without changing the code, but is still read at runtime. For this, we can use environment variables, to for example set a port or database URL per environment.

Accessing Environment Variables in Node.js

In Node.js, every environment variable can be accessed by the global process.env object.

// Read the PORT variable, fall back to 8080 if not set
const PORT = process.env.PORT || 8080;

app.listen(PORT, (error) => {
  if (error) {
    console.log('Error starting the server');
    return;
  }
  console.log('Server is running on port', PORT);
});

Security and Configuration Benefits

Another important use case for environment variables, are for security. We can want to hardcode API Keys, usernames, passwords and the like.

Surely we can hardcode the port number, however, you don't know if a fellow developer is running a different port for development than you, so this way it can be customized per developer.

NODE_ENV

Development vs Production

NODE_ENV is a way for us to locally tell an application which environment it is running on. Libraries such as Express use it internally to enable optimisations in productions mode.

Setting Environment Variables

We can set these environment variables through the bash terminal with:

NODE_ENV=production

Or we can use package.json, like we showed earlier. This way we can run different types of environments, making it easier to run production, testing or development.

{
  "scripts": {
    "start": "NODE_ENV=production node app.js",
    "dev": "NODE_ENV=development node --watch app.js"
  }
}

Semantic HTML

What Is Semantic HTML

Semantic HTML means using elements that carry meaning about the content they contain and not just how it looks. It matters for accessibility, because a <div> says nothing about what it contains, whereas a <nav> or <code> does.

Accessibility and Navigation

Assistive technology like screen readers use headings as signposts for navigation in content. So you should never skip a level in headings and always use them logically.

Example Structure

<header>
  <!-- Site logo, navigation, top bar -->
</header>

<main>
  <!-- Primary content of the page -->
  <section>
    <h2>Section Title</h2>
    <p>Section content...</p>
  </section>
</main>

<footer>
  <!-- Copyright, links, secondary info -->
</footer>

Better Project Structure

Evolution of Project Architecture

When our application grows, it usually also grows in file amounts, meaning we need to keep a close eye on our project architecture.

Page-Specific vs Global Assets

Up until now, we have used a page-specific architecture, where each page gets a folder, and that folder contains the HTML, JS CSS, and images associated with that page.

But when the amount pages grows and when we start using JS files across the whole site, it is better to create a folder called assets, containing global CSS, JS and images.

 $ tree -L 3
├── app.js
├── package-lock.json
├── package.json
├── public
   ├── assets
   ├── css
   ├── images
   └── js
   └── pages
       ├── about
       └── frontend
└── util
    └── replUtil.js

Benefits

The outcome of this, is that we can manage and overlook our architecture much more easily, resulting in quicker navigation and less "where-did-i-put-my-hammer" type of situations.

The Problem

On pages with no or little content, a footer will default to sitting in the middle of the page. Of course, this looks incredibly untidy, but there is a fix:

The Solution

body {
    min-height: 95vh;
    display: flex;
    flex-direction: column;
}

main {
    flex: 1;
}

Result

Now, the footer will always sit at the bottom of the page, regardless of the amount of content that sits above it. This is a simple, but very powerful trick to give your page a polished look.

CDN vs Local

What is CDN

Sometimes, we need to import static content to our application, like libraries, JavaScript files and CSS. This can be done with CDN, which is a group of servers that are spread out across many locations. They store duplicate copies of the data, so that the servers can fulfill requests based on the location of the end-user.

Example Usage

We use a CDN on this documentation page, to showcase code snippets.

Like this one

We can use this because of highlight.js, which we import at the top as a CDN, but also as a script tag at the bottom of the page. This ensures the library is loaded before hljs.highlightAll() is called.

<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>

Downsides of CDN

However, there are downsides to using CDN's. For example, if CDN goes down, your website will malfunction - it may also reduce performance, because it needs to establish a connection with a third-party website.