المعرفة:: NodeJS
الحالة::مؤرشفة
المراجع:: The Complete Node.js Developer Course 3rd Edition, coggro’s Notes
- Express is a fast, unopinionated, minimalist web framework for Node.js.
npm install express
Getting Started
- The simplest Express app you can create.
// const express = require('express')
// import express
import express from "express";
// call express to start server
const app = express();
const port = 3000;
// .get takes route and fx for what to do
// args are req object and res object
app.get("/", (req, res) => {
// Send something back to user
res.send("Hello World!");
});
// Set the server to listen on a prescribed port
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
- This app starts a server and listens on port 3000 for connections and responds with “Hello World!” for requests to the root URL (
/
) or route. For every other path, it will respond with a 404 Not Found. - nodemon can be used to restart the server on changes.
send()
can send text, HTML, or JSON object or array.
res.send(`<h1>Weather</h1>`);
res.send({
name: `Corey`,
age: 31,
});
Serving static files
- If we are using [[./, JavaScript Modules#Native JavaScript (ES6) Modules]|ES6 Modules]] instead of CommonJS Modules we will have to apply this workaround.
- Node’s
path.join()
is used to get the full absolute path to the public folder/public/
.
import { join } from "path";
// .. is one dir up
console.log(`joined path`, path.join(__dirname, `..`, `/public`));
- Finally, we set express’s
app.use()
to serve static files.
const publicDirectoryPath = path.join(__dirname, "../public");
app.use(express.static(publicDirectoryPath));
Dynamic Pages with Templating
- Handlebars template engine will be used to serve dynamic content (on npm).
- We need to install hbs - handlebars for express package.
npm i hbs
- Next, we can set
hbs
as view engine of express.
app.set(`view engine`, `hbs`);
- By default, views are expected to be found in
/views/
directory. - Instead of using
res.send()
, we need to useres.render(viewName)
to render our views. res.render()
also accepts a second argument which is the dynamic values to pass to the view.
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="/styles/styles.css" />
</head>
<body>
<h1>{{ title }}</h1>
<p>{{ name }}</p>
<script src="/scripts/script.js"></script>
</body>
</html>
app.get("", (req, res) => {
// first arg is view to render
// second arg is dynamic values to pass
res.render(`index`, {
title: `Weather App`,
name: `Andrew Mead`,
});
});
Customizing Views and Partials Directories
- We can change the location and name of the views directory.
const viewsPath = path.join(__dirname, '../templates/views');
app.set('views', viewsPath);
- Also, we can do the same for partials directory.
import hbs from "hbs";
const partialsPath = path.join(__dirname, '../templates/partials');
hbs.registerPartials(partialsPath);
Partials and Advanced Templating
- Partials are small parts of markup than can exist in different templates, e.g. headers or footers.
- It can help unifying the website look without having much duplicated markup.
- Partials can load in on other pages using
{{>partial}}
syntax. - Nodemon won’t load the changes automatically unless we adjust our nodemon command to
nodemon src/app.js -e js,hbs
. - We can reference variables in the partial just like we do in normal templates.
<!-- <h1>Static Header.hbs Text</h1> -->
<h1>{{title}}</h1>
<div>
<a href="/">Weather</a>
<a href="/about">About</a>
<a href="/help">Help</a>
</div>
<body>
{{>header}}
<p>{{ name }}</p>
</body>
Setting up 404 Pages
- Set up
app.get("*", …)
as the last route in the app.- Express looks for matches in order listed. First, it looks for static pages, then at our routes, including our final wildcard route.
- We can add sub-routes, too.
- Something like this will work above the full wildcard:
app.get(`/help/*`, (req, res) => {
res.send(`Help article not found`);
});
app.get(`*`, (req, res) => {
res.send(`Page not found`);
});
Query Strings
- A way to send data from browser to the server and get it easily using
req.qurey
.
// http://localhost:3000/products?search=games&rating=5
app.get("/products", (req, res) => {
console.log(req.query); // {search: "games", rating: "5"}
});
- Express doesn’t provide a way to force requiring a query, instead we can use simple if statement.
app.get(`/products`, (req, res) => {
if (!req.query.search) {
return res.send({
error: `You must provide a search term`,
});
}
res.send({
products: [],
});
});
- We can also send back query data normally in response.
app.get(`/weather`, (req, res) => {
if (!req.query.address) {
return res.send({
error: `You must provide a location.`,
});
}
res.send({
forecast: `The weather forecast is that there will be weather whether or not you can weather it.`,
location: req.query.address,
});
});