node CommandWe can execute Node.js programs in the terminal by typing the node command, followed by the file name.
The example command runs app.js, assuming there is a file with that name in the current working directory.
node app.js
Node.js comes with REPL, an abbreviation for read–eval–print loop. REPL contains three different states:
After these states are finished, the REPL loops through these states repeatedly. REPL is useful as it gives back immediate feedback which can be used to perform calculations and develop code.
$ nodeWelcome to Node.js v22.19.0.> console.log("HI")HI
The Node.js environment has a global object that contains every Node-specific global property. The global object can be accessed by executing console.log(global), or simply global in the terminal with the REPL running. In order to see just the keys, use Object.keys(global) instead.
Since global is an object, new properties can be assigned to it via global.name_of_property = 'value_of_property'.
// access global within a scriptconsole.log(global);// add a new property to globalglobal.car = 'DeLorean';
A process is the instance of a computer program that is being executed. Node has a global process object with useful properties. One of these properties is .env, which stores and controls information about the environment.
console.log(process.env.PWD); // Prints: /path/where/terminal/command/executedif (process.env.NODE_ENV === 'development') {startDevelopmentServer();console.log('Testing! Testing! Does everything work?');} else if (process.env.NODE_ENV === 'production') {startProductionServer();}
process.argv is a property that holds an array of the command-line values that were provided when the current process was initiated. The first element in the array is the absolute path to the Node installation, followed by the path to the file that was executed, and then any additional command-line arguments provided.
// Command line values: node web.js testing several featuresconsole.log(process.argv[2]); // 'testing' will be printed
process.memoryUsage()process.memoryUsage() is a method that can be used to return information on the CPU demands of the current process. Here, “heap” refers to a pool of computer memory, rather than the data structure of the same name.
Using process.memoryUsage() will return an object in a format like the example given.
In Node.js, files are called modules. Modularity is a technique where a single program has distinct parts, each providing a single piece of the overall functionality, like pieces of a puzzle coming together to complete a picture. require() is a function used to import one module into another.
const baseball = require('./babeRuth.js')
Node has several modules included within the environment to efficiently perform common tasks. These are known as the core modules. The core modules are defined within Node.js’s source and are located in the lib/ folder. A core module can be accessed by passing a string with the name of the module into the require() function.
const util = require('util');
In Node.js files are considered modules. Modules that are created locally are called local modules. These local modules are held in an object called module. This object has a property called exports which allows a module to be accessed in a different module.
// type.js// by using the export property we can use this module in another filemodule.exports = class key {constructor(car) {this.car = car;}};// qwerty.js// by requiring the type.js file we can we use the module in the type.js filelet Dog = require('./type.js');
NPM stands for node-package-manager. An NPM is essentially a collection of code from other developers that we can use. When Node is installed the npm command-line tool is downloaded as well. This command-line tool enables us to interact with the registry via our terminal.
events ModuleNode.js has an EventEmitter class that can be accessed by importing the events core module. Each event emitter instance has an .on() method that assigns a listener callback function to a named event. EventEmitter also has an .emit() method, which announces that a named event has occurred.
// Require in the 'events' core modulelet events = require('events');// Create an instance of the EventEmitter classlet myEmitter = new events.EventEmitter();let showNewUser = (data) => {console.log(`participant: ${data}.`);};// Assign the showNewUser function as the listener callback for 'new user' eventsmyEmitter.on('new user', showNewUser)// Emit a 'new user' eventmyEmitter.emit('new user', 'Lily Pad') // Prints: participant: Lily Pad.
Node.js is a non-blocking, asynchronous environment. The event loop in Node.js enables asynchronous actions to be handled in a non-blocking way. Node.js provides APIs which allow operations to be put in a queue, waiting to be executed after the previous operation finishes. If synchronous tasks never end, operations waiting in the event-queue will never execute.
let endgame = () => {console.log('I am inevitable')};// endgame will run after 1000mssetTimeout(endgame, 1000);
error ModuleMany asynchronous Node.js APIs assume that the provided callback function will have an error passed as the first argument, followed by the resulting data of a (successful) operation. If the asynchronous task results in an error, the error will be passed in as the first argument to the callback function, with no second argument. If no error was thrown, then the first argument will be undefined, and the resulting data of the operation will be passed as the second argument.
Input is data that is given to the computer, while output is any data or feedback that a computer provides. In Node, we can get input from a user using the stdin.on() method on the process object. We are able to use this because process.stdin is an instance of EventEmitter. To give an output, we can use the stdout.write() method on the process object as well. This is because console.log() is actually a thin wrapper on stdout.write().
// recieve an inputprocess.stdin.on('data', onDataCallback);// produce an outputprocess.stdout.write(data);
fs ModuleThe file system controls how data on a computer is stored and retrieved. Node.js provides the fs core module, which allows interaction with the file system. Each method provided through the module has synchronous and asynchronous versions to allow for flexibility. One method available in the module is .readFile(), which reads data from the provided file.
const fs = require('fs');// First argument is the file path// The second argument is the file’s character encoding// The third argument is an error-first callback functionfs.readFile('./file.txt', 'utf-8', callbackFunction);
Node was designed with back end development needs as a top priority. One of these needs is the ability to create web servers. A web server is a computer process that listens for requests from clients and returns responses. A Node core module designed to meet these needs is the http module. This module has functions that simplify receiving and responding to requests.
const http = require('http');
http.createServer() is a method that returns an instance of an http.server. The method .listen() in http.server tells the server to “listen” for incoming connections. We give http.createServer() a callback function also known as the requestListener, which will be triggered once the server is listening and receives a request. The requestlistener requests a request object and a response object.
// required in the http core module.const http = require('http');let requestListener = (request, response) => {// code to be filled in depending on server};// assigning return valueconst server = http.createServer(requestListener);// assigning server portserver.listen(3000);
In most cases, data is not processed all at once, but rather piece by piece, which we call a stream. Streaming data is preferred as it doesn’t require tons of RAM and doesn’t need to have all the data on hand to begin processing it. To read files line by line, we can use the .createInterface() method from the readline core module in conjunction with fs.createReadStream(). We can create a writeable stream by using the fs.createWriteStream() method, and write to the stream using .write().
const fs = require('fs');const readline = require('readline');// Readable streamreadline.createInterface({input: fs.createReadStream('text.txt')});// Writable Streamconst writableStream = fs.createWriteStream('output.txt');writableStream.write('data');writableStream.close();
HTML Front-EndThe front-end refers to the part of web apps visible to users, handled in their browsers. This includes elements like HTML for structure, CSS for styling, and JavaScript for functionality. Meanwhile, the back-end handles the server-side processes, managing data and responding to requests.
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Front-End Development</title><style>body {font-family: Arial, sans-serif;background-color: #f4f4f9;}</style></head><body><h1>Hello, World!</h1><p>This is a simple HTML page demonstrating front-end basics.</p><button onclick="alert('Hello, Front-End!')">Click me!</button></body></html>
A web server listens for client requests over a network and returns responses. Typically, these servers use the HTTP protocol to send requested resources like HTML pages, images, or files. Understanding these basic functions of a web server helps in designing efficient network communication.
```python# Simple HTTP server in Pythonimport http.serverimport socketserverPORT = 8000Handler = http.server.SimpleHTTPRequestHandlerwith socketserver.TCPServer(("", PORT), Handler) as httpd:print(f"Serving at port {PORT}")httpd.serve_forever()```
The back-end of web applications handles server-side logic, processing requests and managing data interactions. This ensures dynamic responses are generated for clients effectively. Node.js is often used for this purpose, working seamlessly with databases like MongoDB or MySQL.
const http = require('http');const server = http.createServer((req, res) => {if (req.url === '/') {res.write('You have reached the server-side logic page');res.end();}});server.listen(3000);console.log('Listening on port 3000...');
Database ManagementDatabases store and manage data for web apps efficiently. Relational databases organize data into tables, facilitating easy access and manipulation using queries. Non-relational databases store data differently, like key-value pairs or documents, offering flexibility for unstructured data.
--Example of a relational database query:SELECT * FROM users WHERE status = 'active';--Example of non-relational database entry using JSON-like format:{"key": "user123","value": {"name": "John Doe","status": "active"}}
A web API enables communication between a client interface and a server by following a specific set of rules. Through a process called the HTTP request-response cycle, clients can retrieve, update, or manipulate data on the server side. This interaction is essential for dynamic web applications that rely on external data.
GET /api/data HTTP/1.1Host: example.comAccept: application/jsonHTTP/1.1 200 OKContent-Type: application/json{"data": [{"id": 1, "name": "John Doe"},{"id": 2, "name": "Jane Smith"}]}
Python AuthenticationAuthentication ensures only legitimate users can access specific features in an application by verifying their identity, often using credentials, like usernames and passwords.
from getpass import getpass# Placeholder user credentials for demonstrationUSERNAME = "user123"PASSWORD = "securepass"username_input = input("Enter your username: ")password_input = getpass("Enter your password: ")if username_input == USERNAME and password_input == PASSWORD:print("Access granted.")else:print("Access denied.")
Authorization ConceptsAuthorization is critical for controlling access. Once a user proves their identity, authorization determines what they can do. It’s like having different keys for different doors based on your role!
// Example of authorization checkconst user = {role: 'admin',permissions: ['view-dashboard', 'edit-user'],};function authorize(action) {if (user.permissions.includes(action)) {return `Access granted for ${action}`;} else {return `Access denied for ${action}`;}}console.log(authorize('edit-user')); // Outputs: Access granted for edit-userconsole.log(authorize('delete-user')); // Outputs: Access denied for delete-user
Tech Stack OverviewA technology stack is an essential part of web development. It combines programming languages, frameworks, databases, and tools to create a cohesive environment for building web applications. Understanding how each component interacts can enhance productivity and efficiency.