express 路由中間件
表達 (Express)
When it comes to build web applications using Node.js, creating a server can take a lot of time. Over the years Node.js has matured enough due to the support from community. Using Node.js as a backend for web applications and websites help the developers to start working on their application or product quickly.
在使用Node.js構建Web應用程序時,創建服務器可能需要很多時間。 多年來,由于社區的支持,Node.js已經足夠成熟。 使用Node.js作為Web應用程序和網站的后端可以幫助開發人員快速開始開發其應用程序或產品。
In this tutorial, we are going to look into Express which is a Node.js framework for web development that comes with features like routing and rendering and support for REST APIs.
在本教程中,我們將研究Express,這是一個用于Web開發的Node.js框架,具有路由和渲染等功能以及對REST API的支持。
什么是快遞? (What is Express?)
Express is the most popular Node.js framework because it requires minimum setup to start an application or an API and is fast, and unopinionated at the same time. In other words, it does not enforces its own philosophy that a application or API should be built in a specific way, unlike Rails and Django. Its flexibility can be calculated by the number of npm
modules available which makes it pluggable at the same time. If you have basic knowledge of HTML, CSS, and JavaScript and how Node.js works in general, in no time you will be able to get started with Express.
Express是最流行的Node.js框架,因為它需要最少的設置來啟動應用程序或API,并且速度快且同時不受限制。 換句話說,與Rails和Django不同,它沒有實施自己的哲學,即應以特定方式構建應用程序或API。 它的靈活性可以通過可用的npm
模塊數量來計算,這使得它可以同時插入。 如果您具有HTML,CSS和JavaScript的基本知識以及Node.js的一般工作原理,那么您很快就可以開始使用Express。
Express was developed by TJ Holowaychuk and is now maintained by Node.js foundation and open source developers. To get started with the development using Express, you need to have Node.js and npm installed. You can install Node.js on your local machine and along with it comes the command line utility npm
that will help us to install plugins or as called dependencies later on in our project.
Express由TJ Holowaychuk開發,現在由Node.js基金會和開源開發人員維護。 要開始使用Express進行開發,您需要安裝Node.js和npm。 您可以在本地計算機上安裝Node.js ,并附帶命令行實用程序npm
,它將幫助我們稍后在項目中安裝插件或稱為依賴項。
To check if everything is installed correctly, please open your terminal and type:
要檢查所有內容是否正確安裝,請打開終端并輸入:
node --version
v5.0.0
npm --version
3.5.2
If you are getting the version number instead of an error that means you have installed Node.js and npm successfully.
如果獲取的是版本號而不是錯誤,則表示您已成功安裝Node.js和npm。
為什么要使用Express? (Why use Express?)
Before we start with mechanism of using Express as the backend framework, let us first explore why we should consider it using or the reasons of its popularity.
在開始使用Express作為后端框架的機制之前,讓我們首先探討為什么應該考慮使用Express或其流行的原因。
- Express lets you build single page, multi-page, and hybrid web and mobile applications. Other common backend use is to provide an API for a client (whether web or mobile). Express使您可以構建單頁,多頁以及混合的Web和移動應用程序。 后端的其他常見用法是為客戶端(無論是Web還是移動設備)提供API。
- It comes with a default template engine, Jade which helps to facilitate the flow of data into a website structure and does support other template engines. 它帶有一個默認的模板引擎Jade,它有助于促進數據流到網站結構中,并且確實支持其他模板引擎。
- It supports MVC (Model-View-Controller), a very common architecture to design web applications. 它支持MVC(模型-視圖-控制器),這是設計Web應用程序的非常常見的體系結構。
- It is cross-platform and is not limited to any particular operating system. 它是跨平臺的,不限于任何特定的操作系統。
- It leverages upon Node.js single threaded and asynchronous model. 它利用Node.js單線程和異步模型。
Whenever we create a project using npm
, our project must have a package.json
file.
每當我們使用npm
創建項目時,我們的項目都必須具有package.json
文件。
創建package.json (Creating package.json)
A JSON (JavaScript Object Notation) file is contains every information about any Express project. The number of modules installed, the name of the project, the version, and other meta information. To add Express as a module in our project, first we need to create a project directory and then create a package.json file.
JSON(JavaScript對象表示法)文件包含有關任何Express項目的所有信息。 安裝的模塊數量,項目名稱,版本和其他元信息。 要將Express作為模塊添加到我們的項目中,首先我們需要創建一個項目目錄,然后創建一個package.json文件。
mkdir express-app-example
cd express-app-example
npm init --yes
This will generate a package.json
file in the root of the project directory. To install any module from npm
we need to have package.json
file exist in that directory.
這將在項目目錄的根目錄中生成一個package.json
文件。 要從npm
安裝任何模塊,我們需要在該目錄中存在package.json
文件。
{"name": "express-web-app","version": "0.1.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"license": "MIT"
}
安裝Express (Installing Express)
Now we have package.json
file, we can install Express by running the command:
現在我們有了package.json
文件,我們可以通過運行以下命令來安裝Express:
npm install --save express
We can confirm that Express has correctly installed by two ways. First, there will be new section in package.json
file named dependencies
under which our Express exists:
我們可以通過兩種方式確認Express是否已正確安裝。 首先, package.json
文件中將有一個名為dependencies
新部分,我們的Express存在于此部分:
{"name": "express-web-app","version": "0.1.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"license": "MIT","dependencies": {"express": "4.16.0"}
}
Second way is that a new folder called node_modules
suddenly appeared in the root of our project directory. This folder stores the packages we install locally in our project.
第二種方法是在我們的項目目錄的根目錄中突然出現一個名為node_modules
的新文件夾。 此文件夾存儲我們在項目中本地安裝的軟件包。
使用Express構建服務器 (Building a Server with Express)
To use our installed package for Express framework and create a simple server application, we will create the file, index.js
, at the root of our project’s directory.
要將安裝的軟件包用于Express框架并創建一個簡單的服務器應用程序,我們將在項目目錄的根目錄下創建index.js
文件。
const express = require('express');
const app = express();app.get('/', (req, res) => res.send('Hello World!'));app.listen(3000, () => console.log('Example app listening on port 3000!'));
To start the server, go to your terminal and type:
要啟動服務器,請轉到終端并輸入:
node index.js
This will start the server. This bare-minimum application will listen on port 3000. We make a request through our browser on http://localhost:3000
and our server will respond with Hello World
to which the browser is the client and the message will be shown there.
這將啟動服務器。 這個最簡單的應用程序將在端口3000上進行偵聽。我們通過位于http://localhost:3000
上的瀏覽器發出請求,并且服務器將以瀏覽器為客戶端的Hello World
進行響應,并在此處顯示消息。
The first line of our code is using the require
function to include the express
module. This is how we include and use a package installed from npm in any JavaScript file in our project. Before we start using Express, we need to define an instance of it which handles the request and response from the server to the client. In our case, it is the variable app
.
我們代碼的第一行使用require
函數來包含express
模塊。 這就是我們在項目中的任何JavaScript文件中包含和使用從npm安裝的軟件包的方式。 在開始使用Express之前,我們需要定義一個實例來處理從服務器到客戶端的請求和響應。 在我們的例子中,它是變量app
。
app.get()
is a function that tells the server what to do when a get
request at the given route is called. It has a callback function (req, res)
that listen to the incoming request req
object and respond accordingly using res
response object. Both req
and res
are made available to us by the Express framework.
app.get()
是一個函數,它告訴服務器在給定路由處調用get
請求時該怎么做。 它具有一個回調函數(req, res)
,該函數偵聽傳入的請求req
對象,并使用res
響應對象相應地進行響應。 Express框架向我們提供了req
和res
。
The req
object represents the HTTP request and has properties for the request query string, parameters, body, and HTTP headers. The res object represents the HTTP response that an Express app sends when it gets an HTTP request. In our case, we are sending a text Hello World
whenever a request is made to the route /
.
req
對象代表HTTP請求,并具有請求查詢字符串,參數,正文和HTTP標頭的屬性。 res對象表示Express應用在收到HTTP請求時發送的HTTP響應。 在本例中,每當對路徑/
發出請求時,我們都會發送文本Hello World
。
Lastly, app.listen()
is the function that starts a port and host, in our case the localhost
for the connections to listen to incoming requests from a client. We can define the port number such as 3000
.
最后, app.listen()
是啟動端口和主機的函數,在本例中為連接的localhost
主機,以偵聽來自客戶端的傳入請求。 我們可以定義端口號,例如3000
。
快速應用程序剖析 (Anatomy of an Express Application)
A typical structure of an Express server file will most likely contain the following parts:
Express服務器文件的典型結構很可能包含以下部分:
Dependencies
依存關系
Importing the dependencies such as the express itself. These dependencies are installed using npm
like we did in the previous example.
導入依賴項,例如快遞本身。 這些依賴關系是使用npm
來安裝的,就像在上一個示例中一樣。
Instantiations
實例化
These are the statements to create an object. To use express, we have to instantiate the app
variable from it.
這些是創建對象的語句。 要使用express,我們必須從中實例化app
變量。
Configurations
構型
These statements are the custom application based settings that are defined after the instantiations or defined in a separate file (more on this when discuss the project structure) and required in our main server file.
這些語句是基于自定義應用程序的設置,這些設置是在實例化之后定義的,或者在單獨的文件中定義的(在討論項目結構時會對此進行詳細說明),并且在我們的主服務器文件中需要。
Middleware
中間件
These functions determine the flow of request-response cycle. They are executred after every incoming request. We can also define custom middleware functions. We have section on them below.
這些功能確定請求-響應周期的流程。 它們在每個傳入請求之后執行。 我們還可以定義自定義中間件功能。 我們下面有關于它們的部分。
Routes
路線
They are the endpoints defined in our server that helps to perform operations for a particular client request.
它們是我們服務器中定義的端點,可幫助執行特定客戶端請求的操作。
Bootstrapping Server
引導服務器
The last that gets executed in an Express server is the app.listen()
function which starts our server.
在Express服務器中執行的最后一個命令是啟動我們服務器的app.listen()
函數。
We will now start disussing sections that we haven’t previously discussed about.
現在,我們將開始討論以前沒有討論過的部分。
路由 (Routing)
Routing refers to how an server side application responds to a client request to a particular endpoint. This endpoint consists of a URI (a path such as /
or /books
) and an HTTP method such as GET, POST, PUT, DELETE, etc.
路由是指服務器端應用程序如何響應特定端點的客戶端請求。 該端點由URI(例如/
或/books
類的路徑)和HTTP方法(例如GET,POST,PUT,DELETE等)組成。
Routes can be either good old web pages or REST API endpoints. In both cases the syntax is similar syntax for a route can be defined as:
路由可以是良好的舊網頁或REST API端點。 在這兩種情況下,路由的相似語法可以定義為:
app.METHOD(PATH, HANDLER);
Routers are helpful in separating concerns such as different endpoints and keep relevant portions of the source code together. They help in building maintainable code. All routes are defined before the function call of app.listen()
. In a typical Express application, app.listen()
will be last function to execute.
路由器有助于分離諸如不同端點之類的問題,并將源代碼的相關部分保持在一起。 它們有助于構建可維護的代碼。 所有路由都在app.listen()
函數調用之前定義。 在典型的Express應用程序中, app.listen()
將是最后執行的函數。
路由方式 (Routing Methods)
HTTP is a standard protocol for a client and a server to communicate over. It provides different methods for a client to make request. Each route has at least on hanlder function or a callback. This callback function determines what will be the response from server for that particular route. For example, a route of app.get()
is used to handle GET requests and in return send simple message as a response.
HTTP是客戶端和服務器之間進行通信的標準協議。 它為客戶端提出請求提供了不同的方法。 每個路由至少都具有hanlder函數或回調。 該回調函數確定來自服務器的特定路由響應。 例如, app.get()
的路由用于處理GET請求,并作為響應發送簡單消息。
// GET method route
app.get('/', (req, res) => res.send('Hello World!'));
路由路徑 (Routing Paths)
A routing path is a combination of a request method to define the endpoints at which requests can be made by a client. Route paths can be strings, string patterns, or regular expressions.
路由路徑是請求方法的組合,用于定義客戶端可以在其上發出請求的端點。 路由路徑可以是字符串,字符串模式或正則表達式。
Let us define two more endpoints in our server based application.
讓我們在基于服務器的應用程序中定義另外兩個端點。
app.get('/home', (req, res) => {res.send('Home Page');
});
app.get('/about', (req, res) => {res.send('About');
});
Consider the above code as a bare minimum website which has two endpoints, /home
and /about
. If a client makes a request for home page, it will only response with Home Page
and on /about
it will send the response: About Page
. We are using the res.send
function to send the string back to the client if any one of the two routes defined is selected.
將上面的代碼視為具有兩個端點/home
和/about
。 如果客戶請求首頁,則只會用Home Page
響應,并且在/about
上會發送響應: About Page
。 如果選擇了兩個定義的路由中的任何一個,我們將使用res.send
函數將字符串發送回客戶端。
路由參數 (Routing Parameters)
Route parameters are named URL segments that are used to capture the values specified at their position in the URL. req.params
object is used in this case because it has access to all the parameters passed in the url.
路由參數被命名為URL段,用于捕獲URL中在其位置處指定的值。 在這種情況下,使用req.params
對象是因為它可以訪問url中傳遞的所有參數。
app.get('/books/:bookId', (req, res) => {res.send(req.params);
});
The request URL from client in above source code will be http://localhost:3000/books/23
. The name of route parameters must be made up of characters ([A-Za-z0-9_]). A very general use case of a routing parameter in our application is to have 404 route.
上面源代碼中來自客戶端的請求URL將為http://localhost:3000/books/23
。 路徑參數的名稱必須由字符([A-Za-z0-9_])組成。 在我們的應用程序中,路由參數的一個非常普遍的用例是擁有404路由。
// For invalid routes
app.get('*', (req, res) => {res.send('404! This is an invalid URL.');
});
If we now start the server from command line using node index.js
and try visiting the URL: http://localhost:3000/abcd
. In response, we will get the 404 message.
如果現在使用node index.js
從命令行啟動服務器,然后嘗試訪問URL: http://localhost:3000/abcd
。 作為響應,我們將收到404消息。
中間件功能 (Middleware Functions)
Middleware functions are those functions that have access to the request object (req
), the response object (res
), and the next
function in the application’s request-response cycle. The objective of these functions is to modify request and response objects for tasks like parsing request bodies, adding response headers, make other changes to request-response cycle, end the request-response cycle and call the next middleware function.
中間件功能是可以訪問請求對象( req
),響應對象( res
)和應用程序的請求-響應周期中的next
功能的那些功能。 這些功能的目的是為諸如解析請求正文,添加響應頭,對請求-響應周期進行其他更改,結束請求-響應周期并調用下一個中間件功能之類的任務修改請求和響應對象。
The next
function is a function in the Express router which is used to execute the other middleware functions succeeding the current middleware. If a middleware function does include next()
that means the request-response cycle is ended there. The name of the function next()
here is totally arbitary and you can name it whatever you like but is important to stick to best practices and try to follow a few conventions, especially if you are working with other developers.
next
功能是Express路由器中的功能,用于執行當前中間件之后的其他中間件功能。 如果中間件函數確實包括next()
,則意味著請求-響應周期在那里結束。 函數next()
的名稱完全是任意的,您可以隨意命名,但是遵循最佳實踐并遵循一些約定很重要,特別是在與其他開發人員合作時。
Also, when writing a custom middleware do not forget to add next()
function to it. If you do not mention next()
the request-response cycle will hang in middle of nowhere and you servr might cause the client to time out.
同樣,在編寫自定義中間件時,請不要忘記向其添加next()
函數。 如果不提及next()
則請求-響應周期將掛在虛無處,并且您的servr可能會導致客戶端超時。
Let use create a custom middleware function to grasp the understanding of this concept. Take this code for example:
讓我們使用創建自定義的中間件功能來理解這個概念。 以下面的代碼為例:
const express = require('express');
const app = express();// Simple request time logger
app.use((req, res, next) => {console.log("A new request received at " + Date.now());// This function call tells that more processing is// required for the current request and is in the next middlewarefunction/route handler.next();
});app.get('/home', (req, res) => {res.send('Home Page');
});app.get('/about', (req, res) => {res.send('About Page');
});app.listen(3000, () => console.log('Example app listening on port 3000!'));
To setup any middleware, whether a custom or available as an npm module, we use app.use()
function. It as one optional parameter path and one mandatory parameter callback. In our case, we are not using the optional paramaeter path.
要設置任何中間件,無論是自定義的還是作為npm模塊可用,我們都使用app.use()
函數。 它作為一個可選參數路徑和一個強制參數回調。 在我們的情況下,我們沒有使用可選的參數路??徑。
app.use((req, res, next) => {console.log('A new request received at ' + Date.now());next();
});
The above middleware function is called for every request made by the client. When running the server you will notice, for the every browser request on the endpoint /
, you will be prompt with a message in your terminal:
客戶端發出的每個請求都會調用上述中間件函數。 運行服務器時,您會注意到,對于端點/
上的每個瀏覽器請求,您都會在終端上看到一條消息提示:
A new request received at 1467267512545
Middleware functions can be used for a specific route. See the example below:
中間件功能可用于特定路由。 請參閱以下示例:
const express = require('express');
const app = express();//Simple request time logger for a specific route
app.use('/home', (req, res, next) => {console.log('A new request received at ' + Date.now());next();
});app.get('/home', (req, res) => {res.send('Home Page');
});app.get('/about', (req, res) => {res.send('About Page');
});app.listen(3000, () => console.log('Example app listening on port 3000!'));
This time, you will only see a similar prompt when the client request the endpoint /home
since the route is mentioned in app.use()
. Nothing will be shown in the terminal when the client requests endpoint /about
.
這次,當客戶端請求端點/home
時,您只會看到類似的提示,因為在app.use()
提到了路由。 當客戶端請求端點/about
時,終端中將不會顯示任何/about
。
Order of middleware functions is important since they define when to call which middleware function. In our above example, if we define the route app.get('/home')...
before the middleware app.use('/home')...
, the middleware function will not be invoked.
中間件功能的順序很重要,因為它們定義了何時調用哪個中間件功能。 在上面的示例中,如果我們在中間件app.use('/home')...
之前定義路由app.get('/home')...
app.use('/home')...
,則不會調用中間件功能。
第三方中間件功能 (Third Party Middleware Functions)
Middleware functions are useful pattern that allows developers to reuse code within their applications and even share it with others in the form of NPM modules. The essential definition of middleware is a function with three arguments: request (or req), response (res), and next which we observer in the previous section.
中間件功能是一種有用的模式,它允許開發人員在其應用程序內重用代碼,甚至以NPM模塊的形式與他人共享代碼。 中間件的基本定義是具有三個參數的函數:請求(或req),響應(res)和下一個,我們在上一節中進行了觀察。
Often in our Express based server application, we will be using third party middleware functions. These functions are provided by Express itself. They are like plugins that can be installed using npm and this is why Express is flexible.
通常,在基于Express的服務器應用程序中,我們將使用第三方中間件功能。 這些功能由Express本身提供。 它們就像可以使用npm安裝的插件,這就是Express靈活的原因。
Some of the most commonly used middleware functions in an Express appication are:
Express應用程序中最常用的中間件功能包括:
bodyParser (bodyParser)
It allows developers to process incoming data, such as body payload. The payload is just the data we are receiving from the client to be processed on. Most useful with POST methods. It is installed using:
它允許開發人員處理傳入的數據,例如主體有效載荷。 有效負載只是我們從客戶端接收到的要處理的數據。 對POST方法最有用。 它使用以下方法安裝:
npm install --save body-parser
Usage:
用法:
const bodyParser = require('body-parser');// To parse URL encoded data
app.use(bodyParser.urlencoded({ extended: false }));// To parse json data
app.use(bodyParser.json());
It is probably one of the most used third-party middleware function in any Express applicaiton.
它可能是任何Express應用程序中最常用的第三方中間件功能之一。
cookieParser (cookieParser)
It parses Cookie header and populate req.cookies
with an object keyed by cookie names. To install it,
它解析Cookie頭,并用由cookie名稱作為鍵的對象填充req.cookies
。 要安裝它,
$ npm install --save cookie-parser
const cookieParser = require('cookie-parser');
app.use(cookieParser());
會議 (session)
This middleware function creates a session middleware with given options. A session is often used in applications such as login/signup.
該中間件功能創建具有給定選項的會話中間件。 會話通常用在諸如登錄/注冊之類的應用程序中。
$ npm install --save session
app.use(session({secret: 'arbitary-string',resave: false,saveUninitialized: true,cookie: { secure: true }})
);
摩根 (morgan)
The morgan middleware keeps track of all the requests and other important information depending on the output format specified.
摩根中間件會根據指定的輸出格式來跟蹤所有請求和其他重要信息。
npm install --save morgan
const logger = require('morgan');
// ... Configurations
app.use(logger('common'));
common
is a predefined format case which you can use in the application. There are other predefined formats such as tiny and dev, but you can define you own custom format too using the string parameters that are available to us by morgan.
common
是可以在應用程序中使用的預定義格式情況。 還有其他預定義格式,例如tiny和dev,但是您也可以使用morgan可用的字符串參數來定義自己的自定義格式。
A list of most used middleware functions is available at this link.
此鏈接提供了最常用的中間件功能列表。
提供靜態文件 (Serving Static Files)
To serve static files such as CSS stylesheets, images, etc. Express provides a built in middleware function express.static
. Static files are those files that a client downloads from a server.
為了提供諸如CSS樣式表,圖像等靜態文件,Express提供了內置的中間件功能express.static
。 靜態文件是客戶端從服務器下載的那些文件。
It is the only middleware function that comes with Express framework and we can use it directly in our application. All other middlewares are third party.
它是Express框架隨附的唯一中間件功能,我們可以在應用程序中直接使用它。 所有其他中間件都是第三方。
By default, Express does not allow to serve static files. We have to use this middleware function. A common practice in the development of a web application is to store all static files under the ‘public’ directory in the root of a project. We can serve this folder to serve static files include by writing in our index.js
file:
默認情況下,Express不允許提供靜態文件。 我們必須使用此中間件功能。 Web應用程序開發中的常見做法是將所有靜態文件存儲在項目根目錄的“ public”目錄下。 通過編寫index.js
文件,我們可以為該文件夾提供靜態文件,包括:
app.use(express.static('public'));
Now, the static files in our public directory will be loaded.
現在,我們公共目錄中的靜態文件將被加載。
http://localhost:3000/css/style.css
http://localhost:3000/images/logo.png
http://localhost:3000/images/bg.png
http://localhost:3000/index.html
多個靜態目錄 (Multiple Static Directories)
To use multiple static assets directories, call the express.static
middleware function multiple times:
要使用多個靜態資產目錄,請多次調用express.static
中間件函數:
app.use(express.static('public'));
app.use(express.static('files'));
虛擬路徑前綴 (Virtual Path Prefix)
A fix path prefix can also be provided as the first argument to the express.static
middleware function. This is known as a Virtual Path Prefix since the actual path does not exist in project.
修復路徑前綴也可以作為express.static
中間件功能的第一個參數提供。 由于實際路徑在項目中不存在,因此稱為虛擬路徑前綴 。
app.use('/static', express.static('public'));
If we now try to load the files:
如果現在嘗試加載文件:
http://localhost:3000/static/css/style.css
http://localhost:3000/static/images/logo.png
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/index.html
This technique comes in handy when providing multiple directories to serve static files. The prefixes are used to help distinguish between the multiple directories.
當提供多個目錄來服務靜態文件時,此技術非常有用。 前綴用于幫助區分多個目錄。
模板引擎 (Template Engines)
Template engines are libraries that allow us to use different template languages. A template language is a special set of instructions (syntax and control structures) that instructs the engine how to process data. Using a template engine is easy with Express. The popular template engines such as Pug, EJS, Swig, and Handlebars are compatible with Express. However, Express comes with a default template engine, Jade, which is the first released version of Pug.
模板引擎是允許我們使用不同模板語言的庫。 模板語言是一組特殊的指令(語法和控制結構),它們指示引擎如何處理數據。 通過Express,可以輕松使用模板引擎。 流行的模板引擎(例如Pug,EJS,Swig和Handlebars)與Express兼容。 但是,Express帶有默認模板引擎Jade,它是Pug的第一個發行版本。
To demonstrate how to use a Template Engine, we will be using Pug. It is a powerful template engine that provide features such as filters, includes, interpolation, etc. To use it, we have to first install as a module in our project using npm
.
為了演示如何使用模板引擎,我們將使用Pug。 它是一個功能強大的模板引擎,提供諸如過濾器,包含,插值等功能。要使用它,我們首先必須使用npm
作為模塊安裝在我們的項目中。
npm install --save pug
This command will install the pug and to verify that installed correctly, just take a look at the package.json
file. To use it with our application first we have to set it as the template engine and create a new directory ‘./views’ where we will store all the files related to our template engine.
該命令將安裝哈巴狗,并驗證是否已正確安裝,只需查看package.json
文件即可。 要首先將其與我們的應用程序一起使用,我們必須將其設置為模板引擎,并創建一個新目錄'./views',我們將在其中存儲與模板引擎相關的所有文件。
app.set('view engine', 'pug');
app.set('views', './views');
Since we are using app.set()
which indicates configuration within our server file, we must place them before we define any route or a middleware function.
由于我們使用的app.set()
表示服務器文件中的配置,因此在定義任何路由或中間件功能之前,必須先將它們放置。
In the views
direcotry, create file called index.pug
.
在views
,創建名為index.pug
文件。
doctype htmlhtmlheadtite="Hello from Pug"bodyp.greetings Hello World!
To run this page, we will add the following route to our application.
要運行此頁面,我們將以下路線添加到我們的應用程序中。
app.get('/hello', (req, res) => {res.render('index');
});
Since we have already set Pug as our template engine, in res.render
we do not have to provide .pug
extension. This function renders the code in any .pug
file to HTML for the client to display. The browsers can only render HTML files. If you start the server now, and visit the route http://localhost:3000/hello
you will see the output Hello World
rendered correctly.
由于我們已經將Pug設置為模板引擎,因此在res.render
我們不必提供.pug
擴展名。 此函數將任何.pug
文件中的代碼呈現為HTML,以供客戶端顯示。 瀏覽器只能呈現HTML文件。 如果現在啟動服務器,并訪問路由http://localhost:3000/hello
您將看到正確呈現的輸出Hello World
。
In Pug, you must notice that we do not have to write closing tags to elements as we do in HTML. The above code will be rendered into HTML as:
在Pug中,您必須注意,我們不必像在HTML中那樣向元素編寫結束標記。 上面的代碼將呈現為HTML:
<!DOCTYPE html>
<html><head><title>Hello from Pug</title></head><body><p class = "greetings">Hello World!</p></body>
</html>
The advantage of using a Template Engine over raw HTML files is that they provide support for performing tasks over data. HTML cannot render data directly. Frameworks like Angular and React share this behaviour with template engines.
與原始HTML文件相比,使用模板引擎的優勢在于它們為通過數據執行任務提供了支持。 HTML無法直接呈現數據。 諸如Angular和React之類的框架與模板引擎共享此行為。
You can also pass values to template engine directly from the route handler function.
您也可以直接從路由處理程序函數將值傳遞給模板引擎。
app.get('/', (req, res) => {res.render('index', { title: 'Hello from Pug', message: 'Hello World!' });
});
For above case, our index.pug
file will be written as:
對于上述情況,我們的index.pug
文件將寫為:
doctype htmlhtmlheadtitle= titlebodyh1= message
The output will be the same as previous case.
輸出將與以前的情況相同。
Express App的項目結構 (Project Structure of an Express App)
Since Express does not enforces much on the developer using it, sometimes it can get a bit overwhelming to what project structure one should follow. It does not has a defined structure officially but most common use case that any Node.js based application follows is to separate different tasks in different modules. This means to have separate JavaScript files.
由于Express對使用它的開發人員的要求并不高,因此有時它可能會使您應該遵循的項目結構有些不知所措。 它沒有正式定義的結構,但是任何基于Node.js的應用程序遵循的最常見用例是在不同模塊中分離不同任務。 這意味著要有單獨JavaScript文件。
Let us go through a typical strucutre of an Express based web application.
讓我們看一下基于Express的Web應用程序的典型結構。
project-root/node_modules/ // This is where the packages installed are storedconfig/db.js // Database connection and configurationcredentials.js // Passwords/API keys for external services used by your appconfig.js // Environment variablesmodels/ // For mongoose schemasbooks.jsthings.jsroutes/ // All routes for different entities in different filesbooks.jsthings.jsviews/index.pug404.pug...public/ // All static filesimages/css/javascript/app.jsroutes.js // Require all routes in this and then require this file inapp.jspackage.json
This is pattern is commonly known as MVC, model-view-controller. Simply because our database model, the UI of the application and the controllers (in our case, routes) are written and stored in separate files. This design pattern that makes any web application easy to scale if you want to introduce more routes or static files in the future and the code is maintainable.
這種模式通常稱為MVC,即模型視圖控制器。 僅僅是因為我們的數據庫模型,應用程序的UI和控制器(在我們的情況下是路由)被編寫并存儲在單獨的文件中。 如果您將來想引入更多路由或靜態文件并且代碼是可維護的,則這種設計模式使任何Web應用程序都易于擴展。
翻譯自: https://www.freecodecamp.org/news/express-explained-with-examples-installation-routing-middleware-and-more/
express 路由中間件