什麼是Express?
Express是Node.js的最佳框架之一。它具有大力的支持和許多有用的功能。那裡有很多很棒的文章,涵蓋了所有基礎知識。但是,這次我想深入研究,並分享我的工作流程以創建一個完整的網站。通常,本文不僅用於Express,而且還將其與其他一些可用於節點開發人員使用的優質工具結合使用。
要遵循本教程,我假設您對節點有些熟悉,並且已將其安裝在系統上。
了解Express中的中間件
Express的核心是連接。這是一個中間件框架,配備了許多有用的東西。如果您想知道什麼是中間件,這是一個快速示例:
const connect = require('connect'),<br> http = require('http');<br><br> const app = connect()<br> .use(function(req,res,ext)<br> console.log(“那是我的第一個中間件”);<br> 下一個();<br> }))<br> .use(function(req,res,ext)<br> console.log(“那是我的第二個中間件”);<br> 下一個();<br> }))<br> .use(function(req,res,ext)<br> console.log(“ end”);<br> res.end(“ Hello World”);<br> });<br><br> http.Createserver(App).Listen(3000);<br>
中間件基本上是一個函數,該函數接受響應對象和響應對象,或通過在第二個中間件中調用Next()方法來調用下一個函數,Body Parser解析請求主體並支持應用程序/JSON,Application/X-WWW-Form-urlCormeded,以及Multipart/form-data。並用cookie名稱鍵入的對象進行req.cookies。
Express Craps實際上連接並添加了一些新功能,例如路由邏輯,這使得該過程更加順暢。這是處理Express中的GET請求的示例:
app.get('/hello.txt',function(req,res){<br> var body ='Hello world';<br> res.setheader('content-type','text/plain');<br> res.setheader(“內容長度”,body.mength);<br> res.end(身體);<br> });<br>
原始碼
我們構建的示例網站的源代碼可在GitHub上使用。請隨意分叉並與之一起玩。這是運行網站的步驟。
- 下載源代碼
- 轉到NPM安裝
- 運行MongoDB守護程序
- 運行NPM安裝。
{<br> “名稱”:“ mywebsite”,<br> “描述”:“我的網站”,<br> “版本”:“ 0.0.1”,<br> “依賴關係”:{<br> “ express”:“ 5.x”<br> }<br> }<br>
框架的代碼將放置在node_modules中,您將能夠創建一個實例。但是,我更喜歡使用命令行工具一個替代選項。通過使用NPX Express-Generator命令:
用法:Express [選項] [DIR]<br><br> 選項:<br><br> - version輸出版本號<br> -e,-ej添加EJS引擎支持<br> - Pug添加哈哈發動機支撐<br> -HBS添加車把引擎支持<br> -h, - 霍根添加hogan.js引擎支持<br> -v,-view <engine>添加視圖<engine>支持(灰塵|<br> - 不使用靜態HTML代替視圖引擎<br> -c,-css <egene>添加樣式表<engine> support> support> sandlus | Compass | sass)(默認為普通CSS)<br> - git添加.gitignore<br> -F, - 非空目錄的力量<br> -h, - 螺旋輸出使用信息<br></engine></egene></engine></engine>
如您所見,只有一些可用的選擇,但是對我來說,它們已經足夠了。通常,我少用作為CSS預處理器和車把作為模板引擎。在此示例中,我們還需要會話支持,因此NPM安裝和NODE_MODULES文件夾將彈出。
我意識到上述方法並不總是合適的。您可能需要將路線處理程序放置在另一個目錄或類似目錄中。但是,正如您將在接下來的幾節中看到的那樣,我將對已經生成的結構進行更改,並且很容易做到。因此,您應該只是想到app.js來使用我們的新文件結構。我們需要刪除這兩行:
const usersrouter = require(“ ./路由/用戶”);<br> ...<br> app.use(“/用戶”,usersrouter);<br>
步驟2。配置
現在,我們需要設置配置。讓我們想像我們的小網站應部署到三個不同的位置:本地服務器,登台服務器和生產服務器。當然,每個環境的設置都不同,我們應該實施一種足夠靈活的機制。如您所知,每個節點腳本都是作為控制台程序運行的。因此,我們可以輕鬆地發送將定義當前環境的命令行參數。我將該部分包裹在單獨的模塊中,以便稍後為其編寫測試。這是/config/index.js文件:
const config = {<br> 當地的: {<br> 模式:“本地”,<br> 端口:3000<br> },,<br> 登台:{<br> 模式:“分期”,<br> 端口:4000<br> },,<br> 生產: {<br> 模式:“生產”,<br> 端口:5000<br> }<br> }<br> Module.exports = function(mode){<br> 返回配置[模式|| process.argv [2] || 'local'] || config.local;<br> }<br>
(現在)只有兩個設置:端口。您可能已經猜到了,該應用程序為不同的服務器使用不同的端口。這就是為什麼我們必須在app.js中更新站點的輸入點的原因。
const config = require('./ config')();<br> process.env.port = config.port;<br>
要在配置之間切換,只需在末尾添加環境即可。例如:
NPM開始登台<br>
將在端口4000運行服務器。
現在,我們將所有設置都放在一個地方,並且很容易管理。
步驟3。創建一個測試框架
我是測試驅動開發(TDD)的忠實擁護者。我將嘗試介紹本文中使用的所有基礎類。當然,對所有內容進行測試都會使這本書的寫作太長,但是總的來說,這就是創建自己的應用程序時應該繼續進行的方式。我最喜歡的測試框架之一是UVU,因為它非常易於使用和快速使用。當然,它可以在NPM註冊表中使用:
npm安裝 - save-dev uvu<br>
然後,在NPM測試中創建一個新腳本,您應該看到以下內容:
config.js<br> •••(3/3)<br><br> 總計:3<br> 通過:3<br> 跳過:0<br> 持續時間:0.81ms<br>
這次,我首先編寫了實施,第二個測試。這並不是TDD做事的方式,而是在接下來的幾個部分中,我將相反。
我強烈建議您花費大量時間寫作測試。沒有什麼比全面測試的應用程序更好的了。
幾年前,我意識到一些非常重要的事情,這可能有助於您製作更好的程序。每次您開始編寫新課程,新模塊或僅僅是新邏輯時,請問自己:
我該如何測試?
這個問題的答案將有助於您更有效地編碼,創建更好的API,並將所有內容放入良好的塊中。您不能為意大利面代碼編寫測試。例如,在上面的配置文件( /config/index.js )中,我添加了發送生產配置的可能性,但是節點腳本是使用NPM安裝MongoDB運行的。
接下來,我們將編寫一個測試,該測試檢查是否運行了MongoDB服務器。這是/tests/mongodb.js文件:
const {test} = require(“ uvu”);<br> const {mongoclient} = require(“ mongodb”);<br><br> test(“ mongodb服務器活動”,async函數(){<br> const client = new mongoclient(“ mongodb://127.0.0.1:27017/fastdelivery”);<br> 等待client.connect();<br> });<br><br> test.run();<br><br>
我們不需要添加MongoDB客戶端的任何連接方法,每當我們必須向數據庫提出請求時,都會接收一個mongoclient對象。因此,我們應該連接到初始服務器創建中的數據庫。為此,由於中間件在每個請求之前自動運行,因此在Req.db屬性中可用。
4。設置一個帶有Express的MVC模式
我們都知道MVC模式。問題是如何適用表達。或多或少,這是解釋的問題。在接下來的幾個步驟中,我將創建模塊,該模塊充當模型,視圖和控制器。
步驟1。模型
該模型將是處理我們應用程序中的數據的方法。它應該可以使用雜種。我們的模型還應該有一種擴展它的方法,因為我們可能需要創建不同類型的模型。例如,我們可能想要一個contactsmodel。因此,我們需要編寫一個新規格, /tests /base.model.js ,以測試這兩個模型功能。並記住,通過在開始編碼實現之前定義這些功能,我們可以保證我們的模塊只能完成我們想要的工作。
const {test} = require(“ uvu”);<br> const sustert = require(“ uvu/servert”);<br> const ModelClass = require(“ ../ models/base”);<br> const dbmockup = {};<br> test(“模塊創建”,異步函數(){<br> const Model =新的ModelClass(DBMOCKUP);<br> assert.ok(model.db);<br> assert.ok(model.setdb);<br> assert.ok(model.Collection);<br> });<br> test.run();<br>
而不是真實的DB對象和我們的數據庫視圖目錄的Getter將更改為基本視圖類。現在,這個小的更改需要另一個更改。我們應該通知明確說明我們的模板文件現在放置在另一個目錄中:
app.set(“ views”,path.join(__ dirname,“模板”));<br>
首先,我將定義我需要的內容,編寫測試,然後編寫實現。我們需要一個匹配以下規則的模塊:
- 它的構造函數應接收響應對象和模板名稱。
- 它應該有一個視圖類。難道不僅以某種方式調用響應對象,例如,提供JSON數據:
const data = {開發人員:“ krasimir tsonev”};<br> response.conttype(“ application/json”);<br>響應send(json.stringify(data));<br>
擁有JSONVIEW類,甚至是測試目錄,而不是每次都這樣做,如果您在路線之後運行'/'(在上面的示例中,實際上是控制器)是一個接受響應的函數,並且是一個接受響應的函數,並且Express(1)命令行工具將是一個名為“舊界限”功能,它是舊的Middledware函數,它是舊的Middledware函數,它是一個舊的Middledware函數,它是optres ofer
- 應該有一種運行方法以及其自己的邏輯。
5。創建FastDelivery網站
好的,我們為MVC體系結構提供了一系列的課程,並且我們已經通過測試介紹了新創建的模塊。現在,我們準備繼續使用假公司FastDelivery的網站。
讓我們想像該站點有兩個部分:前端和管理面板。前端將用於向我們的最終用戶顯示數據庫中寫的信息。管理面板將用於管理該數據。讓我們從管理員(控制)面板開始。
步驟1。控制面板
讓我們首先創建一個簡單的控制器,該控制器將用作管理頁面。這是/routes/admin.js文件:
const basecontroller = require(“ ./ base”),<br> view = require(“ ../ view/base”);<br> Module.exports = new(class adminController擴展了basecontroller {<br> constructor(){<br> 超級(“ admin”);<br> }<br> 運行(req,res,next){<br> if(this.authorize(req)){<br> req.session.fastDelivery = true;<br> req.session.save(function(err){<br> var v =新視圖(res,“ admin”);<br> v.render({<br> 標題:“管理”,<br> 內容:“歡迎來到控制面板”,<br> });<br> });<br> } 別的 {<br> const v =新視圖(res,“ admin-login”);<br> v.render({<br> 標題:“請登錄”,<br> });<br> }<br> }<br> 授權(req){<br> 返回 (<br> (Req.Session &&<br> req.session.fastDelivery &&<br> req.session.fastDelivery === true)||<br> (req.body &&<br> req.body.username === this.username && &&<br> req.body.password === this.password)<br> );<br> }<br> })();<br>
通過為控制器和視圖使用預編寫的基本類,我們可以輕鬆地為控制面板創建入口點。 admin.run方法直接作為中間件。那是因為我們想保留上下文。如果我們這樣做:
app.all('/admin*',admin.run);<br>
admin一詞將指向其他內容。
保護管理面板
以/管理為開頭的每個頁面都應受到保護。為了實現這一目標,我們將使用Express的中間件:Session。它只需將對象附加到稱為admin Controller的請求即可做兩個其他事情:
- 它應該檢查是否有可用的會話。如果沒有,請顯示登錄表單。
- 如果用戶名和密碼匹配,則應接受登錄表格發送的數據並授權用戶。
這是我們可以用來實現這一目標的小輔助功能:
授權(req){<br> 返回 (<br> (Req.Session &&<br> req.session.fastDelivery &&<br> req.session.fastDelivery === true)||<br> (req.body &&<br> req.body.username === this.username && &&<br> req.body.password === this.password)<br> );<br> }<br>
首先,我們有一個聲明,試圖通過會話對象識別用戶。其次,我們檢查是否已提交表格。如果是這樣,則來自表單的數據在BodyParser中間件中可用。然後,我們只檢查用戶名和密碼是否匹配。
現在,這是標題,圖片和類型屬性將確定記錄的所有者。例如,“聯繫人”頁面只需要一個使用Admin Controller的記錄。為了簡化任務,我決定將添加記錄列表和添加/編輯的表格組合起來。如您在下面的屏幕截圖中看到的那樣,該頁面的左側為列表保留,並保留該表單的右側部分。
在一個頁面上擁有所有內容意味著我們必須集中精力在呈現頁面的部分,或更具體地說,是我們發送到模板的數據。這就是為什麼我創建了幾個合併的助手功能,例如:
this.del(req,function(){<br> this.form(req,res,function(formmarkup){<br> this.list(function(listmarkup){<br> v.render({<br> 標題:“管理”,<br> 內容:“歡迎來到控制面板”,<br> 列表:Listmarkup,<br> 表格:formmarkup,<br> });<br> });<br> });<br> });<br> const v =新視圖(res,“ admin”);<br>
它看起來有些醜陋,但它可以按照我的意願起作用。第一個助手是一個操作= delete&id = [記錄的ID],它從集合中刪除了數據。第二個功能稱為列表方法獲取信息並準備HTML表,後來將其發送到模板。可以在本教程的源代碼中找到這三個幫助者的實現。
在這裡,我決定向您展示處理admin.js中的文件上傳的功能:
handerfileupload(req){<br> 如果(!<br> 返回req.body.currentPicture || “”<br> }<br> const data = fs.ReadFileSync(req.files.picture.path);<br> const filename = req.files.picture.name;<br> const uid = crypto.randombytes(10).tostring(“ hex”);<br> const dir = __dirname“ /../public/uploads/” uid;<br> fs.mkdirsync(dir,“ 0777”);<br> fs.WriteFileSync(dir“/”文件名,數據);<br> 返回“/uploads/“ uid”/“ fileName;<br> }<br>
如果提交文件,則節點腳本req.files.picture。在上面的代碼段中,readfilesync,writefilesync。
步驟3。前端
艱苦的工作現在已經完成。管理面板正在工作,我們有一個家庭和四個記錄,其中包含博客的DB對象,但請致電“不同 /blog /:id string”。該路線將匹配req.params.id等URL。換句話說,我們能夠定義動態參數。在我們的情況下,這就是記錄的ID。獲得此信息後,我們可以為每篇文章創建一個唯一的頁面。
第二個有趣的部分是我如何構建服務,職業和聯繫人頁面。顯然,他們僅使用數據庫中的一個記錄。如果我們必須為每個頁面創建一個不同的控制器,那麼我們必須複製/粘貼相同的代碼,只需在其NPM安裝命令中更改類型即可運行以安裝新的依賴項(如果有)。
- 然後應再次運行主腳本。
請記住,節點仍然還很年輕,因此並非所有內容都可以按照您的預期工作,但是一直都有改進。例如,永遠保證您的node.js程序將連續運行。您可以通過發出以下命令來執行此操作:
永遠啟動您的app.js<br>
這也是我在服務器上使用的內容。這是一個不錯的小工具,但它解決了一個大問題。如果您使用永遠的應用程序運行,請簡單地重新啟動應用程序。
現在我不是系統管理員,但是我想分享我的經驗將節點應用與Apache或Nginx集成,因為我認為這是開發工作流程的一部分。
如您所知,Apache通常在端口80上運行,這意味著,如果您打開http:// localhost:80,您將看到Apache Server提供的頁面,並且很可能您的節點腳本在其他端口上收聽。因此,您需要添加一個接受請求並將其發送到正確端口的虛擬主機。例如,假設我想託管我們剛剛在主機文件下的本地Apache服務器上構建的網站。
127.0.0.1 ExpressCompletewebsite.dev<br>
之後,我們必須在Apache Configuration目錄下編輯HTTPD-VHOSTS.CONF文件,然後添加:
#ExpressCompleteWebsite.dev<br> <virtualhost><br> Servername ExprexPleteWebsite.dev<br> Serveralias www.expresscompletewebsite.dev<br> proxyrequest off<br> <br> 訂單拒絕,允許<br> 從所有人那裡允許<br> <br> <br> proxypass http:// localhost:3000/<br> ProxypassReverse http:// localhost:3000/<br> <br> </virtualhost><br>
服務器仍然接受端口80上的請求,但將其轉發到端口3000,該端口正在偵聽。
NGINX設置要容易得多,而且,老實說,它是託管基於node.js的應用程序的更好選擇。您仍然必須在主機文件中添加域名。之後,只需在NGINX安裝下的/啟用 /站點的目錄中創建一個新文件即可。文件的內容看起來像這樣:
伺服器 {<br> 聽80;<br> server_name ExpressCompletewebsite.dev<br> 地點 / {<br> Proxy_pass http://127.0.0.1:3000;<br> proxy_set_header主機$ http_host;<br> }<br> }<br>
請記住,您不能使用上述主機設置同時運行Apache和Nginx。那是因為它們都需要端口80。此外,如果您計劃在生產環境中使用上述代碼段,則可能需要對更好的服務器配置進行一些其他研究。正如我所說,我不是這個領域的專家。
結論
Express是一個很棒的框架,它為您提供了開始構建應用程序的良好起點。如您所見,這是您將如何擴展它以及與之構建的方法的選擇。它通過使用一些出色的中間件來簡化無聊的任務,並將有趣的零件留給開發人員。
雅各布·傑克遜(Jacob Jackson)的貢獻已更新。雅各布(Jacob)是網絡開發人員,技術作家,自由職業者和開源貢獻者。
以上是使用Express建立一個完整的MVC網站的詳細內容。更多資訊請關注PHP中文網其他相關文章!

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

記事本++7.3.1
好用且免費的程式碼編輯器

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),