Development Basics
Defining consistent npm scripts for running, developing and building a Node.js application across machines.
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.
Recommended Structure
$ tree -L 3
├── app.js
├── package-lock.json
├── package.json
├── public
│ ├── assets
│ │ ├── css
│ │ ├── images
│ │ └── js
│ └── pages
│ ├── about
│ └── frontend
└── util
└── replUtil.jsBenefits
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.
Sticky Footer with CSS
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.