A tech stack is a combination of tools/frameworks/technologies used to build a web applications.
One of the most difficult parts of learning web development is choosing a tech stack. This can be quite a challenge for beginners since there are a lot of options to choose from.
Choosing a tech stack is a crucial part of learning web development, since this decision will have a great impact on your career and salary expectations.
Because of the structure of web applications, a tech stack normally consists of:
As many other things in software development, which tech stack to choose is a debate topic and different developers will have different opinions on which one is right for the job.
For this course, we'll choose a modern and easy to use tech stack that optimizes our salary expectations, quantity and quality of job oportunities.
We'll chose the PERN stack since it's really popular, used by many companies and composed from well documented technologies.
PERN stands for:
For now we'll focus on React and the front end side, since it's possible to write small but functional applications solely using this technology
In a following article we'll talk about the structure of a web application, for now let's talk about the front end
The front end is the part of the application that is visible to the user. The front end runs on the client, the client in the context of web applications refers to the browser that the user is using to view the application.
The front end is limited since all the communication with the user computer is done through the browser.
A front end application can't directly access user files or databases, it can be closed at any time since it lives in the context of a browser tab and can't have any long running processes in the background
The tooling is the software needed to develop your application. We'll use only free, open source and profesionally used software so that you get real world experience.
For a simple front end application, we'll need:
node --version
v17.4.0
npm --version
git --version
git version 2.32.0 (Apple Git-132)
As any professional, you should strive to master your tools. This is an extensive topic since each one has it's own unique set of features.
I recommend that you don't get stuck learning the full depth of each tool, instead, focus on learning the basics and then move onto more advanced topics as you need them.
Each tool have it's own official documentation, which is a great place to start.
For now this are the basics for our tools:
VSCode is a code/text editor, so the basics are related to file managing and text manipulation.
You can open individual files with VSCode but normally we'll work with folders, to open a folder click File > Open folder
The Explorer shows all the files and folders inside the current folder.
A really powerfull feature is the Command palette, this shows a list of all VSCode commands, open it by tapping
F1
Shift + Command + P
All VSCode commands have a name and thus can be searched by name in the command palette, check the Focus on Terminal View command, a handy command to open an integrated terminal right on the editor. We can use this terminal to execute commands, such the the ones we used to verify the installation of other tools
Besides the runtime, Node also includes a REPL, a Node REPL is a simple tool to execute javascript commands, to test it, open the terminal and write
node
You'll see something like
Welcome to Node.js v17.4.0.
Type ".help" for more information.
>
This is a javascript console, you can write javascript commands and see the result, for example, add two numbers:
Welcome to Node.js v17.4.0.
Type ".help" for more information.
>2+3
5
>
Add an array of numbers:
> [1,2,3,4].reduce((a,b) => a + b)
> 10
Alphabetically sort a list of names:
> ["rafa", "naomi", "alex"].sort()
[ 'alex', 'naomi', 'rafa' ]
To learn more about this, check the official node and MDN javascript documentation.
Let's start with a simple static web page, a web page is a document that can be viewed in a web browser.
A static web page is one that always shows the same content, unlike a dynamic web page, which is one that changes content based on user interaction.
Web pages are made of:
A single HTML file can be a valid web page, so let's start by writing an index.html
file with a minimal valid HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first web page</title>
</head>
<body>
Hello there
</body>
</html>
Right click the file in VSCode explorer and click on Copy path to copy the fullpath of the file in the clipboard
Then, we can see the webpage in our browser by pasting the path on the URL bar
Pasting a file path is not a normal way to navigate the web, and it will only work locally from your computer, since other computers can't access your disk drive externally.
To solve this problem, we can use a web server, a web server is a program that runs on a server (in this case your computer) and serves web page files to the browser.
The way that browsers work is by making requests, each request may be answered by a server with a response, this technique of sending and receiving requests/responses is a widely used form of communication called HTTP protocol
We could write our own web server, but it is easier to use a third party web server, such as http-server
This is an NPM package, meaning that is a program that runs on Node, and that can be installed using npm
, or directly executed using npx
NPM is a giant repository of open source packages created and mantained by the community, beware that anyone can upload packages and that they may contain vulnerabilities or even malware, so do your due research and only install trusted / popular packages.
NPM packages can access your file system, network, and other resources, so be careful when installing packages from NPM.
To run the web server execute the following command on the terminal:
npx http-server
You should see something like
Starting up http-server, serving ./
http-server settings:
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none
Available on:
http://127.0.0.1:8080
http://192.168.1.69:8080
Hit CTRL-C to stop the server
Now you can open the same web packge by pasting the given URL on the browser
We see the same web page but now it's being served by a proper web server, depending on your router configuration you could even access this page from anywhere on the Internet (you'll need to configure port forwarding but this is another topic)
Remember that we are learning the PERN stack, where React is used to render the UI, instead of HTML we'll use a syntax called JSX.
JSX is very similar to HTML and React needs extra configuration to be used, so for this basic example we'll stick with pure HTML.
Still, HTML is considered basic knowledge for a web developer and you should know about it even when working with React.
<!-- This is comment and has no effect in the final web page -->
<!-- Some tags may have child elements, such as <div /> -->
<div>
<p>
This is a text paragraph
</p>
<!-- This is a line jump -->
<br />
<p>
Another paragraph
</p>
<b>This text is in bold</b>
<em>This text is in italics</em>
Text can be also a direct child of the div tag
</div>
<!-- Self closing tags have no children elements, such as <input /> -->
<!-- Attributes define properties for the tag,
in this case, value is the text of the input text box -->
<input value="hello" />
You can imagine a div as a transparent box that can contain other elements such as text, images, butons, etc...
The div is the basic building block of web applications since it easy to style and can be used to group elements,
Divs can contain other divs, so usually web applications consists of a lot of divs neasted one inside another
As any other element divs can be styled using CSS or the style
attribute
In a following article we'll see how to use divs to create a full web app layout including headers, footers, side bars / menus and main content
Here is an example of a yellow div with a text inside:
<div style="background: yellow">
Hello, this is a yellow div
</div>
An input is a text box that can be used to enter text, numbers, dates, etc...
An input by itself has little to no use, but you can use Javascript to interact with it, and then use the input value to do something such as save it to a database or send it to a server.
<div>
<input value="You can write here" />
<input placeholder="Your age" type="number" />
</div>
<!-- Note that we are using the alert function to show a message box -->
<button onclick="alert('Hello there')">
Click me!
</button>
A select is a dropdown list that can be used to select a value from a list of options.
Similarly to other elements, you can use Javascript to interact with the selected value
<div>
<label>Pick your favorite food:</label>
<br />
<select>
<option value="1">Tacos</option>
<option value="2">Lasagna</option>
</select>
</div>
The browser dev tools are your best friends for developing web apps, they allow you to inspect HTML elements, debug Javascript code, modify styling on the fly, inspect network traffic and much more.
Give it a try and inspect your own web page with the examples above, to open it use F12
on Windows or Option + Command + J
on Mac
You can inspect any web page, not only your own
Javascript is the programming language of the web, it's the only language that web browsers can execute (besides WASM but that's another story)
Javascript is also the language of NodeJS, so you can learn a single language and use it both on the web and on server programming. Such a time saver!
First lets get familiar with the integrated javascript code editor, click Run to see the code in action.
This is actual executable Javascript code, try changing the message to something different and see what happens.
This is a C-like language, meaning that:
;
{ }
Basic aritmetic operations:
Comparissions:
Try playing with the arithmetic and comparission examples and see what happens, try to predict what the alert message will be before running the code.
Here we have an input named "input_name" in Javascript it's possible to access an input text using the value
property
<input id="input_name" placeholder='Type your name here' />
In the previous example we introduced the concept of variables, they are used to store values. Use const
for defining non-changing variables and let
for changing variables.
Variables have a name and a value. Be careful with naming variables since they are case sensitive.
You can use any name you like but it's recommended to use meaningful names, also, by convention in Javascript we use the cammelCase casing for variables, meaning that they start with lower case and that each word is separated by a capital letter
It's considered a good practice to use const for variable that you know will never change as a hint to you and other developers that this is a known constant, even when let will work just fine.
As a program grows in size it's much easier to reason about something that you're sure will never change.
Programming is hard, this is why we developers use a lot of hints and tips to make our code more readable and maintainable.
Writing simple and easy to read code should always be one of your main priorities.
var can also be used to declare variables, but since let is widely supported in modern browsers and and has more intuitive scoping rules is recommended that you simply never use var.
Let add two more tags to our minimal HTML file to integrate both JS and CSS code.
The style
tag goes inside the head
tag and contains the CSS styling code for the web page.
The script
tag goes inside the body
tag after all other body child tags and contain the JS code for the page.
For simplicity sake we are putting everything (HTML, JS and CSS code) on the same file. This would result in giant and hard to read files even for the simplest web applications, instead, normally developers employ modularization.
Modularization means splitting everything in multiple small files so that the project is easy to understand.
Very large code files are a big red flag and considered a code smell, this means that even when the code may work just fine, the way that the code is written indicates some kind of design problem that may require simplification or refactoring.
Divide-and-conquer is a recurring topic for software developers, you'll find that many problems in software can be splitted into smaller and more manageable ones.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first web page</title>
<style>
/* CSS code goes here */
</style>
</head>
<body>
Hello there
<script>
// JS code goes here, note that this is tag is positioned at the
// end of the body tag
</script>
</body>
</html>
font-family
style applied to the body
element changes the font of the whole page, this is because of style inheritance , this means that according to some rules, styles applied to parent elements get also applied to child elements. input
element has an id="name"
attribute, making it referencable by the document.getElementById("name")
method on our Javascript code button
has an onclick
event handler referencing the sayHello
function, so that this function gets executed when the user clicks the button<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My first web page</title>
<style>
/* Use a prettier font */
body {
font-family: sans-serif;
}
/* Makes the input taller */
input {
height: 30px;
}
/* Change the default button style for a prettier one */
button {
background-color: cornflowerblue;
color: white;
border-radius: 5px;
border: 1px solid blue;
height: 30px;
}
</style>
</head>
<body>
Please write your name here:
<input id="name" />
<button onclick="sayHello()">
Say hello
</button>
<script>
// JS code goes here, note that this is tag is positioned at the
// end of the body tag
function sayHello() {
const name = document.getElementById('name').value;
alert('Hello ' + name);
}
</script>
</body>
</html>
You might run into a cache problem when you update the code.
In order to speed up page loading web browsers store previously loaded resources in the browser cache, this is stored in the client side so that the next time the page is loaded, the browser can load the resources from the cache instead than loading them from the server.
Since reading from the client disk is much faster than from the Internet, this results in significant performance gains but can mess up with your developer experience since the browser might get stuck loading an older cached version of your code instead of the most recent one.
Modern frameworks such as NextJS already handle this automatically, but since our first web page is not using any framework, you might need to empty cache and hard reload to see your latest changes.