ExpressJS จะจัดโครงสร้างแอปพลิเคชันอย่างไร


527

ฉันใช้กรอบงานเว็บ ExpressJS สำหรับ NodeJS

คนที่ใช้ ExpressJS ใส่สภาพแวดล้อมของพวกเขา (การพัฒนา, การผลิต, การทดสอบ ... ), เส้นทาง ฯลฯ app.jsบน ฉันคิดว่ามันไม่ใช่วิธีที่สวยงามเพราะเมื่อคุณมีแอปพลิเคชันขนาดใหญ่ app.js ใหญ่เกินไป!

ฉันต้องการมีโครงสร้างไดเรกทอรีนี้:

| my-application
| -- app.js
| -- config/
     | -- environment.js
     | -- routes.js

นี่คือรหัสของฉัน:

app.js

var express = require('express');
var app = module.exports = express.createServer();

require('./config/environment.js')(app, express);
require('./config/routes.js')(app);

app.listen(3000);

config / environment.js

module.exports = function(app, express){
    app.configure(function() {
    app.use(express.logger());
    });

    app.configure('development', function() {
    app.use(express.errorHandler({
        dumpExceptions: true,
        showStack: true
    }));
    });

    app.configure('production', function() {
    app.use(express.errorHandler());
    });
};

config / routes.js

module.exports = function(app) {
    app.get('/', function(req, res) {
    res.send('Hello world !');
    });
};

รหัสของฉันทำงานได้ดีและฉันคิดว่าโครงสร้างของไดเรกทอรีนั้นสวยงาม อย่างไรก็ตามรหัสต้องถูกดัดแปลงและฉันไม่แน่ใจว่ามันดี / สวยงาม

มันจะดีกว่าถ้าใช้โครงสร้างไดเรกทอรีของฉันและปรับรหัสหรือใช้ไฟล์เดียว (app.js)?

ขอบคุณสำหรับคำแนะนำของคุณ!


ปัญหาด้านประสิทธิภาพของการทำเช่นนี้ยังคงซุ่มอยู่รอบ ๆ ? ฉันจำได้ว่าอ่านที่ไหนสักแห่ง (อาจเป็นกลุ่มด่วน) ว่าเมื่อคุณแยกทุกอย่างเช่นนี้คุณจะสูญเสียการแสดงไปมากมาย สิ่งที่ต้องการ reqs / วินาทีของคุณจะลดลงตามจำนวนที่เห็นได้ชัดราวกับว่ามันเป็นบั๊ก
AntelopeSalad

2
มันมาจากกลุ่ม Express Google นี่คือลิงค์: groups.google.com/group/express-js/browse_thread/thread/…
AntelopeSalad

52
Nope นี้ไม่เป็นความจริงมาก
tjholowaychuk

คำตอบ:


306

ตกลงมันได้รับในขณะนี้และเป็นคำถามที่นิยมดังนั้นผมจึงได้ไปข้างหน้าหายไปและสร้างพื้นที่เก็บข้อมูล GitHub นั่งร้านที่มีรหัส JavaScript และ README นานเกี่ยวกับวิธีที่ผมชอบที่จะจัดโครงสร้างขนาดกลางแอพลิเคชัน express.js

focusaurus / express_code_structureเป็น repo กับรหัสล่าสุดนี้ ร้องขอดึงต้อนรับ

นี่เป็นภาพรวมของ README เนื่องจาก stackoverflow ไม่ชอบคำตอบแค่ลิงก์ ฉันจะทำการอัปเดตบางอย่างเนื่องจากเป็นโครงการใหม่ที่ฉันจะทำการอัปเดตต่อไป แต่ในที่สุด gitub repo จะเป็นสถานที่ที่ทันสมัยสำหรับข้อมูลนี้


โครงสร้างรหัสด่วน

โปรเจ็กต์นี้เป็นตัวอย่างของวิธีจัดระเบียบเว็บแอปพลิเคชัน express.js ขนาดกลาง

ปัจจุบันเป็นอย่างน้อย v4.14 ธันวาคม 2559

สถานะการสร้าง

js มาตรฐานสไตล์

ใบสมัครของคุณใหญ่แค่ไหน?

แอปพลิเคชันบนเว็บนั้นไม่เหมือนกันทั้งหมดและในความคิดของฉันมีโครงสร้างรหัสเดียวที่ควรใช้กับแอปพลิเคชัน express.js ทั้งหมด

หากแอปพลิเคชันของคุณมีขนาดเล็กคุณไม่จำเป็นต้องมีโครงสร้างไดเรกทอรีแบบลึกดังตัวอย่างที่นี่ เพียงแค่ให้มันง่ายและติดกำมือของ.jsไฟล์ในรากของพื้นที่เก็บข้อมูลของคุณและคุณทำเสร็จแล้ว voila

หากใบสมัครของคุณมีขนาดใหญ่ในบางจุดคุณจำเป็นต้องแยกมันออกเป็นแพ็กเกจ npm ที่แตกต่างกัน โดยทั่วไปแล้ววิธีการ node.js ดูเหมือนจะให้ความสำคัญกับแพ็กเกจขนาดเล็กจำนวนมากอย่างน้อยก็สำหรับไลบรารี่และคุณควรสร้างแอพพลิเคชั่นของคุณโดยใช้แพ็กเกจ npm หลายอันซึ่งเริ่มมีเหตุผลและสมเหตุสมผล ดังนั้นเมื่อแอปพลิเคชันของคุณโตขึ้นและบางส่วนของรหัสจะสามารถนำกลับมาใช้ใหม่ได้อย่างชัดเจนนอกแอปพลิเคชันของคุณหรือเป็นระบบย่อยที่ชัดเจนให้ย้ายไปยังที่เก็บ git ของตัวเองและทำให้มันเป็นแพคเกจ

ดังนั้นจุดเน้นของโครงการนี้คือการแสดงโครงสร้างที่ใช้การได้สำหรับแอปพลิเคชันขนาดกลาง

สถาปัตยกรรมโดยรวมของคุณคืออะไร

มีหลายวิธีในการสร้างเว็บแอปพลิเคชันเช่น

  • ฝั่งเซิร์ฟเวอร์ MVC และ Ruby บน Rails
  • แอปพลิเคชันหน้าเดียวสไตล์ a la MongoDB / Express / Angular / Node (MEAN)
  • เว็บไซต์พื้นฐานที่มีบางรูปแบบ
  • สไตล์รุ่น / การดำเนินงาน / อ่าน / กิจกรรมลาMVC ตายมันถึงเวลาที่จะไป
  • และอื่น ๆ อีกมากมายทั้งในปัจจุบันและในอดีต

แต่ละสิ่งเหล่านี้เหมาะสมอย่างยิ่งในโครงสร้างไดเรกทอรีที่แตกต่างกัน สำหรับวัตถุประสงค์ของตัวอย่างนี้เป็นเพียงนั่งร้านและไม่ได้เป็น app ทำงานอย่างเต็มที่ แต่ฉันสมมติว่าจุดสถาปัตยกรรมที่สำคัญดังต่อไปนี้:

  • ไซต์มีหน้า / แม่แบบดั้งเดิมบางส่วน
  • "การประยุกต์ใช้" ส่วนหนึ่งของเว็บไซต์ที่มีการพัฒนาเป็นรูปแบบหน้าเดียวแอพลิเคชัน
  • แอปพลิเคชั่นเปิดเผย REST / JSON style API ไปยังเบราว์เซอร์
  • รุ่นแอปโดเมนธุรกิจง่ายในกรณีนี้มันเป็นโปรแกรมตัวแทนจำหน่ายรถยนต์

และสิ่งที่เกี่ยว Ruby on Rails?

มันจะเป็นธีมของโครงการนี้ที่ความคิดหลายอย่างรวมอยู่ใน Ruby on Rails และการตัดสินใจ "อนุสัญญาการตั้งค่าคอนฟิก" ที่พวกเขานำมาใช้แม้ว่าจะได้รับการยอมรับและใช้กันอย่างแพร่หลาย แต่ก็ไม่ค่อยมีประโยชน์จริง ๆ แนะนำ

จุดหลักของที่นี่คือที่มีหลักการพื้นฐานในการจัดระเบียบรหัสและบนพื้นฐานของหลักการเหล่านั้น Ruby on Rails ประชุมให้ความรู้สึก (ส่วนใหญ่) สำหรับ Ruby on Rails ชุมชน อย่างไรก็ตามเพียงแค่คิดถึงการประชุมที่คิดถึงจุดนั้น เมื่อคุณค้นหาหลักการพื้นฐานโครงการของคุณทั้งหมดจะได้รับการจัดระเบียบและชัดเจน: เชลล์สคริปต์เกมแอพมือถือโครงการขององค์กรหรือแม้แต่โฮมไดเร็กตอรี่ของคุณ

สำหรับชุมชน Rails พวกเขาต้องการให้ผู้พัฒนา Rails สลับจากแอพหนึ่งเป็นแอพเป็นแอพและคุ้นเคยกับมันในแต่ละครั้ง นี่เป็นเหตุผลที่ดีถ้าคุณเป็น 37 สัญญาณหรือ Pivotal Labs และมีประโยชน์ ในโลกฝั่งเซิร์ฟเวอร์ JavaScript ที่ร๊อคโดยรวมเป็นเพียงสิ่งที่ตะวันตกทางป่ามากขึ้นไปและเราไม่ได้จริงๆมีปัญหากับที่ นั่นคือวิธีการที่เราม้วน. เราคุ้นเคยกับมัน แม้แต่ภายใน express.js มันเป็นญาติสนิทของ Sinatra ไม่ใช่ Rails และการประชุมจาก Rails มักไม่ช่วยอะไรเลย ผมก็จะบอกว่าหลักการมากกว่าการประชุมมากกว่าการกำหนดค่า

หลักการและแรงจูงใจพื้นฐาน

  • สามารถจัดการจิตใจ
    • สมองเท่านั้นที่สามารถจัดการกับการคิดเกี่ยวกับจำนวนเล็ก ๆ ของสิ่งที่เกี่ยวข้องกันในครั้งเดียว นั่นเป็นเหตุผลที่เราใช้ไดเรกทอรี มันช่วยให้เราจัดการกับความซับซ้อนโดยมุ่งเน้นที่ส่วนเล็ก ๆ
  • เหมาะสมกับขนาด
    • อย่าสร้าง "แมนชั่นไดเรกทอรี" ที่มีเพียง 1 ไฟล์ทั้งหมด 3 ไดเรกทอรีเดียวลง คุณสามารถเห็นสิ่งนี้เกิดขึ้นในAnsible Best Practicesที่ทำให้โครงการเล็ก ๆ กลายเป็น 10+ ไดเรกทอรีเพื่อเก็บไฟล์ 10+ เมื่อ 1 ไดเรกทอรีที่มี 3 ไฟล์จะเหมาะสมกว่า คุณไม่ได้ขับรถไปทำงาน (นอกเสียจากว่าคุณเป็นคนขับรถบัส แต่ถึงอย่างนั้นการขับรถบัสของคุณไม่ทำงาน) ดังนั้นอย่าสร้างโครงสร้างระบบไฟล์ที่ไม่ได้เป็นธรรมโดยไฟล์จริงที่อยู่ภายในพวกเขา .
  • เป็นแบบแยกส่วน แต่ในทางปฏิบัติ
    • ชุมชนโหนดโดยรวมชอบโมดูลขนาดเล็ก ทุกสิ่งที่สามารถแยกออกได้อย่างหมดจดจากแอปของคุณควรถูกแยกออกเป็นโมดูลทั้งเพื่อใช้ภายในหรือเผยแพร่ต่อสาธารณะในเวลา 23.00 น. อย่างไรก็ตามสำหรับการใช้งานขนาดกลางที่มีขอบเขตที่นี่ค่าใช้จ่ายของการนี้สามารถเพิ่มความน่าเบื่อเวิร์กโฟลว์ของคุณโดยไม่คุ้มค่าความ ดังนั้นในช่วงเวลาที่คุณมีรหัสบางส่วนที่แยกออก แต่ไม่เพียงพอที่จะพิสูจน์โมดูล npm ที่แยกจากกันอย่างสมบูรณ์เพียงแค่พิจารณาว่าเป็น " โปรโต - โมดูล " ด้วยความคาดหวังว่าเมื่อมันข้ามขีด จำกัด ขนาดบางมันจะถูกดึงออกมา
    • ผู้ใช้บางคนเช่น@ hij1nxจะรวมapp/node_modulesไดเรกทอรีและมีpackage.jsonไฟล์ในไดเรกทอรีโปรโตโมดูลเพื่อช่วยให้การเปลี่ยนแปลงนั้นและทำหน้าที่เป็นตัวเตือน
  • ง่ายต่อการค้นหารหัส
    • ได้รับคุณสมบัติในการสร้างหรือแก้ไขข้อผิดพลาดเป้าหมายของเราคือผู้พัฒนาไม่ต้องดิ้นรนหาไฟล์ต้นฉบับที่เกี่ยวข้อง
    • ชื่อมีความหมายและถูกต้อง
    • รหัส crufty จะถูกลบออกได้อย่างเต็มที่ไม่ได้ใส่ไปรอบ ๆ ในไฟล์เด็กกำพร้าหรือเพียงแค่ออกความเห็น
  • เป็นมิตรกับการค้นหา
    • รหัสที่มาของบุคคลทั้งหมดอยู่ในappไดเรกทอรีเพื่อให้คุณสามารถcdมีเรียกหา / grep / xargs / AG / แอ๊ / ฯลฯ และไม่ฟุ้งซ่านโดยการแข่งขันของบุคคลที่สาม
  • ใช้การตั้งชื่อที่ง่ายและชัดเจน
    • ตอนนี้ NPM ดูเหมือนจะต้องใช้ชื่อแพคเกจตัวพิมพ์เล็กทั้งหมด ฉันพบว่าส่วนใหญ่น่ากลัว แต่ฉันต้องทำตามฝูงดังนั้นชื่อไฟล์ควรใช้kebab-caseแม้ว่าชื่อตัวแปรใน JavaScript จะต้องเป็นcamelCaseเพราะ-เป็นเครื่องหมายลบใน JavaScript
    • ชื่อตัวแปรตรงกับชื่อฐานของเส้นทางโมดูล แต่kebab-caseเปลี่ยนเป็นcamelCase
  • จัดกลุ่มตามข้อต่อไม่ใช่ตามฟังก์ชั่น
    • นี่คือการเดินทางที่สำคัญจาก Ruby on Rails ประชุมของapp/views, app/controllers, app/modelsฯลฯ
    • เพิ่มฟีเจอร์ลงในสแต็กแบบเต็มดังนั้นฉันต้องการมุ่งเน้นไปที่สแต็คไฟล์แบบเต็มที่เกี่ยวข้องกับคุณสมบัติของฉัน เมื่อฉันเพิ่มฟิลด์หมายเลขโทรศัพท์ลงในรุ่นผู้ใช้ฉันไม่สนใจเกี่ยวกับคอนโทรลเลอร์อื่นนอกเหนือจากคอนโทรลเลอร์ของผู้ใช้และฉันไม่สนใจรุ่นอื่นใดนอกเหนือจากรุ่นผู้ใช้
    • ดังนั้นแทนที่จะแก้ไขไฟล์ 6 ไฟล์ที่อยู่ในไดเรกทอรีของตัวเองและไม่สนใจไฟล์อื่น ๆ ในไดเรกทอรีเหล่านั้นที่เก็บนี้มีการจัดระเบียบเพื่อให้ไฟล์ทั้งหมดที่ฉันต้องการในการสร้างสถานที่นั้นมีการจัดวาง
    • โดยธรรมชาติของ MVC มุมมองของผู้ใช้เป็นคู่กับตัวควบคุมผู้ใช้ซึ่งเป็นคู่กับรูปแบบการใช้ ดังนั้นเมื่อผมเปลี่ยนรูปแบบของผู้ใช้เหล่านั้น 3 ไฟล์มักจะมีการเปลี่ยนแปลงด้วยกัน แต่ข้อเสนอที่ตัวควบคุมหรือคอนโทรลเลอร์ของลูกค้าจะถูกแยกและไม่เกี่ยวข้องกับ เช่นเดียวกันกับการออกแบบที่ไม่ใช่ MVC เช่นกัน
    • การถอดรหัสสไตล์ MVC หรือ MOVE ในแง่ของรหัสที่ไปในโมดูลที่ยังคงได้รับการสนับสนุน แต่การกระจายไฟล์ MVC ออกไปในไดเรกทอรีพี่น้องเป็นเพียงน่ารำคาญ
    • ดังนั้นแต่ละไฟล์เส้นทางของฉันมีส่วนหนึ่งของเส้นทางที่เป็นเจ้าของ routes.rbไฟล์สไตล์รางจะมีประโยชน์ถ้าคุณต้องการภาพรวมของเส้นทางทั้งหมดในแอพ แต่เมื่อสร้างคุณสมบัติและแก้ไขข้อบกพร่องแล้วคุณจะสนใจเฉพาะเส้นทางที่เกี่ยวข้องกับชิ้นส่วนที่คุณกำลังเปลี่ยน
  • ทดสอบร้านค้าถัดจากรหัส
    • นี่เป็นเพียงตัวอย่างของ "กลุ่มโดยการแต่งงานกัน" แต่ฉันต้องการเรียกมันออกมาโดยเฉพาะ ฉันได้เขียนหลายโครงการที่การทดสอบอาศัยอยู่ภายใต้ระบบไฟล์ขนานที่เรียกว่า "การทดสอบ" และตอนนี้ฉันเริ่มวางการทดสอบของฉันในไดเรกทอรีเดียวกันกับรหัสที่สอดคล้องกันฉันจะไม่กลับไป นี่เป็นมอดูลาร์ที่มากขึ้นและง่ายต่อการใช้งานใน text editor และบรรเทาจำนวนเส้นทางไร้สาระ "../../ .. " หากคุณมีข้อสงสัยลองใช้กับโปรเจ็กต์สองสามตัวแล้วตัดสินใจด้วยตัวเอง ฉันจะไม่ทำอะไรนอกเหนือจากนี้เพื่อโน้มน้าวคุณว่าดีกว่า
  • ลดการมีเพศสัมพันธ์ข้ามด้วยกิจกรรม
    • มันง่ายที่จะคิดว่า "ตกลงเมื่อใดก็ตามที่มีการสร้างดีลใหม่ฉันต้องการส่งอีเมลไปยังพนักงานขายทุกคน" แล้วใส่รหัสเพื่อส่งอีเมลเหล่านั้นในเส้นทางที่สร้างดีล
    • อย่างไรก็ตามการมีเพศสัมพันธ์นี้ในที่สุดจะทำให้แอปของคุณกลายเป็นลูกโคลนขนาดใหญ่
    • แต่ DealModel ควรเริ่มต้นเหตุการณ์ "สร้าง" และไม่รู้ตัวเลยว่าระบบอาจทำอะไรเพื่อตอบสนองต่อเหตุการณ์นั้น
    • เมื่อคุณรหัสวิธีนี้มันจะกลายเป็นมากขึ้นเป็นไปได้ที่จะนำทั้งหมดของผู้ใช้รหัสที่เกี่ยวข้องเข้ามาapp/usersเพราะมีไม่รังหนูของตรรกะทางธุรกิจควบคู่ไปทั่วทุกสถานที่ก่อให้เกิดมลพิษความบริสุทธิ์ของฐานรหัสผู้ใช้
  • การไหลของรหัสสามารถติดตามได้
    • อย่าทำสิ่งมหัศจรรย์ อย่าโหลดไฟล์จากไดเรกทอรีมายากลในระบบไฟล์โดยอัตโนมัติ อย่าเป็น Rails แอปพลิเคเริ่มต้นที่app/server.js:1และคุณสามารถเห็นทุกอย่างที่มันโหลดและดำเนินการโดยทำตามรหัส
    • อย่าสร้าง DSL สำหรับเส้นทางของคุณ อย่าทำอย่าง metaprogramming โง่เมื่อมันไม่ได้เรียกร้องให้
    • ถ้า app ของคุณมีขนาดใหญ่เพื่อที่ทำmagicRESTRouter.route(somecontroller, {except: 'POST'})คือการชนะที่ยิ่งใหญ่สำหรับคุณมากกว่า 3 ขั้นพื้นฐานapp.get, app.put, app.delโทร, คุณอาจสร้างแอปพลิเคเสาหินที่มีขนาดใหญ่เกินไปที่จะมีประสิทธิภาพในการทำงาน รับแฟนซีสำหรับชัยชนะที่ยิ่งใหญ่ไม่ได้สำหรับการแปลง 3 เส้นที่เรียบง่ายถึง 1 เส้นที่ซับซ้อน
  • ใช้ต่ำกว่าสะเต๊ะกรณีที่ชื่อไฟล์

    • รูปแบบนี้หลีกเลี่ยงปัญหาเรื่องความไวของระบบไฟล์ในทุกแพลตฟอร์ม
    • npm ห้ามพิมพ์ใหญ่ในชื่อแพ็คเกจใหม่และสิ่งนี้ใช้ได้ดีกับสิ่งนั้น

      express.js เฉพาะ

  • app.configureอย่าใช้ มันไร้ประโยชน์เกือบทั้งหมดและคุณไม่ต้องการมัน มันอยู่ในจำนวนมากสำเร็จรูปเนื่องจาก copypasta ไม่สนใจ

  • คำสั่งของ MIDDLEWARE และเส้นทางในเรื่องด่วน !!!
    • เกือบทุกปัญหาการกำหนดเส้นทางที่ฉันเห็นใน stackoverflow เป็นมิดเดิลแวร์ด่วนนอกลำดับ
    • โดยทั่วไปแล้วคุณต้องการเส้นทางแยกและไม่ได้อาศัยในการสั่งซื้อที่มาก
    • อย่าใช้app.useกับแอปพลิเคชันทั้งหมดของคุณหากคุณต้องการมิดเดิลแวร์นั้นสำหรับ 2 เส้นทางเท่านั้น (ฉันกำลังมองคุณอยู่body-parser)
    • ตรวจสอบให้แน่ใจเมื่อทุกคนพูดและทำตามคำสั่งนี้ของคุณ:
      1. มิดเดิลแวร์ทั่วทั้งแอปพลิเคชันที่สำคัญสุด ๆ
      2. เส้นทางทั้งหมดของคุณและมิดเดิลแวร์ของเส้นทางที่หลากหลาย
      3. ตัวจัดการข้อผิดพลาดแล้ว
  • น่าเศร้าที่การได้รับแรงบันดาลใจจากซินาตร้า express.js ส่วนใหญ่ถือว่าเส้นทางทั้งหมดของคุณจะอยู่ในserver.jsและจะมีความชัดเจนว่าพวกเขาได้รับคำสั่ง สำหรับแอปพลิเคชันขนาดกลางการแยกสิ่งต่าง ๆ ออกเป็นโมดูลเส้นทางแยกเป็นสิ่งที่ดี แต่มันจะแนะนำอันตรายของมิดเดิลแวร์ที่ล้าสมัย

เคล็ดลับของแอป symlink

มีหลายวิธีที่ระบุไว้และพูดคุยกันที่ความยาวโดยชุมชนในกระทู้ที่ดีท้องถิ่น Better ต้องการ () เส้นทางสำหรับ Node.js ฉันอาจตัดสินใจที่จะชอบ "แค่จัดการกับ .. /../../ .. " จำนวนมากหรือใช้requireFrom modlue อย่างไรก็ตามในขณะนี้ฉันใช้เคล็ดลับ symlink โดยละเอียดด้านล่าง

ดังนั้นวิธีหนึ่งที่จะหลีกเลี่ยงการภายในโครงการต้องมีเส้นทางญาติที่น่ารำคาญเหมือนrequire("../../../config")คือการใช้เคล็ดลับต่อไปนี้:

  • สร้าง symlink ภายใต้ node_modules สำหรับแอปของคุณ
    • cd node_modules && ln -nsf ../app
  • เพิ่มเพียง node_modules / app symlink เองไม่ใช่โฟลเดอร์ node_modules ทั้งหมดเพื่อคอมไพล์
    • git add -f node_modules / app
    • ใช่คุณควรมี "node_modules" ใน.gitignoreไฟล์ของคุณ
    • ไม่คุณไม่ควรใส่ "node_modules" ในที่เก็บ git ของคุณ บางคนจะแนะนำให้คุณทำเช่นนี้ พวกเขาไม่ถูกต้อง
  • ตอนนี้คุณสามารถต้องการโมดูลภายในโครงการโดยใช้คำนำหน้านี้
    • var config = require("app/config");
    • var DealModel = require("app/deals/deal-model");
  • โดยทั่วไปนี้ทำให้ภายในโครงการต้องทำงานมากคล้าย ๆ กับต้องสำหรับโมดูล NPM ภายนอก
  • ขออภัยผู้ใช้ Windows คุณต้องติดกับพาเรนต์ของไดเรกทอรีหลัก

องค์ประกอบ

โดยทั่วไปโมดูลรหัสและการเรียนที่คาดหวังเพียง JavaScript พื้นฐานoptionsวัตถุผ่านใน. เท่านั้นapp/server.jsควรโหลดapp/config.jsโมดูล จากนั้นสามารถสังเคราะห์optionsวัตถุขนาดเล็กเพื่อกำหนดค่าระบบย่อยได้ตามต้องการ แต่การเชื่อมระบบย่อยทุกระบบเข้ากับโมดูลการกำหนดค่าระดับโลกขนาดใหญ่ที่เต็มไปด้วยข้อมูลเพิ่มเติมคือการเชื่อมต่อที่ไม่ดี

พยายามรวบรวมการสร้างการเชื่อมต่อฐานข้อมูลและส่งสิ่งเหล่านั้นไปยังระบบย่อยซึ่งตรงข้ามกับการส่งผ่านพารามิเตอร์การเชื่อมต่อและการให้ระบบย่อยทำการเชื่อมต่อขาออกด้วยตนเอง

NODE_ENV

นี่เป็นอีกหนึ่งความคิดที่น่าหลงใหล แต่น่ากลัวที่นำมาจาก Rails ควรมีที่เดียวในแอปของคุณapp/config.jsซึ่งจะดูที่NODE_ENVตัวแปรสภาพแวดล้อม ทุกอย่างอื่นควรใช้ตัวเลือกที่ชัดเจนเป็นอาร์กิวเมนต์ตัวสร้างคลาสหรือพารามิเตอร์การกำหนดค่าโมดูล

ถ้าโมดูลอีเมลมีตัวเลือกเป็นวิธีการส่งอีเมล (ไม่ SMTP, เข้าสู่ระบบที่ stdout ใส่ในคิว ฯลฯ ) จึงควรใช้ตัวเลือกเหมือนแต่ควรอย่างยิ่งที่ได้ตรวจสอบ{deliver: 'stdout'}NODE_ENV

การทดสอบ

ตอนนี้ฉันเก็บไฟล์ทดสอบของฉันไว้ในไดเรกทอรีเดียวกับรหัสที่เกี่ยวข้องและใช้ข้อตกลงการตั้งชื่อนามสกุลไฟล์เพื่อแยกความแตกต่างการทดสอบจากรหัสการผลิต

  • foo.js มีรหัสของโมดูล "foo"
  • foo.tape.js มีการทดสอบตามโหนดสำหรับ foo และอาศัยอยู่ใน dir เดียวกัน
  • foo.btape.js สามารถใช้สำหรับการทดสอบที่ต้องดำเนินการในสภาพแวดล้อมของเบราว์เซอร์

ฉันใช้ระบบไฟล์ globs และfind . -name '*.tape.js'คำสั่งเพื่อเข้าถึงการทดสอบทั้งหมดของฉันตามความจำเป็น

วิธีจัดระเบียบรหัสภายในแต่ละ.jsไฟล์โมดูล

ขอบเขตของโครงการนี้ส่วนใหญ่จะเกี่ยวกับที่ที่ไฟล์และไดเรกทอรีไปและฉันไม่ต้องการเพิ่มขอบเขตอื่น ๆ อีกมากมาย แต่ฉันจะพูดถึงว่าฉันจัดระเบียบรหัสของฉันเป็น 3 ส่วนที่แตกต่างกัน

  1. การเปิดบล็อกของ CommonJS ต้องมีการเรียกไปยังสถานะการพึ่งพา
  2. รหัสบล็อกหลักของ pure-JavaScript ไม่มีมลพิษของ CommonJS ในที่นี้ อย่าอ้างอิงการส่งออกโมดูลหรือจำเป็นต้องใช้
  3. การปิดบล็อกของ CommonJS เพื่อตั้งค่าการส่งออก

1
ฉันควรใช้อะไรแทน bodyParser ถ้าฉันมีเส้นทางเพียงไม่กี่เส้นทางที่ใช้มัน
Ilan Frumer

3
ฉันพบสิ่งที่ฉันกำลังมองหาที่นี่: stackoverflow.com/questions/12418372/…
Ilan Frumer

1
@wlingke ตรวจสอบgist.github.com/branneman/8048520สำหรับการอภิปรายอย่างละเอียดเกี่ยวกับวิธีการที่มีอยู่สำหรับปัญหานั้น
Peter Lyons

@peterLyons ขอบคุณที่แชร์สิ่งนี้ หลังจากอ่านผ่านฉันคิดว่าฉันจะเขียนสคริปต์เริ่มต้น ขอบคุณ!
wlingke

2
กับเรื่องที่เกี่ยวกับเคล็ดลับการตรวจสอบ symlinkมีนี้โมดูลเล็ก ๆ น้อย ๆ ซึ่งจะทำให้ปัญหาทั้งหมดที่หายไป
เฮย์โกคอร์ยูน

157

อัปเดต (2013-10-29) : โปรดดูคำตอบอื่น ๆ ของฉันเช่นกันซึ่งมี JavaScript แทน CoffeeScript ตามความต้องการที่เป็นที่นิยมรวมถึง repo github ที่สร้างขึ้นใหม่และ README รายละเอียดคำแนะนำล่าสุดของฉันในหัวข้อนี้

การกำหนดค่า

คุณกำลังทำอะไรอยู่ ฉันชอบตั้งค่าเนมสเปซของตัวเองในconfig.coffeeไฟล์ระดับบนสุดด้วยเนมสเปซที่ซ้อนกันเช่นนี้

#Set the current environment to true in the env object
currentEnv = process.env.NODE_ENV or 'development'
exports.appName = "MyApp"
exports.env =
  production: false
  staging: false
  test: false
  development: false
exports.env[currentEnv] = true
exports.log =
  path: __dirname + "/var/log/app_#{currentEnv}.log"
exports.server =
  port: 9600
  #In staging and production, listen loopback. nginx listens on the network.
  ip: '127.0.0.1'
if currentEnv not in ['production', 'staging']
  exports.enableTests = true
  #Listen on all IPs in dev/test (for testing from other machines)
  exports.server.ip = '0.0.0.0'
exports.db =
  URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"

นี่เป็นมิตรสำหรับการแก้ไขดูแลระบบ จากนั้นเมื่อฉันต้องการบางสิ่งเช่นข้อมูลการเชื่อมต่อฐานข้อมูล

require('./config').db.URL

เส้นทาง / ควบคุม

ฉันชอบออกจากเส้นทางของฉันกับตัวควบคุมของฉันและจัดระเบียบพวกเขาในapp/controllersไดเรกทอรีย่อย จากนั้นฉันสามารถโหลดมันและปล่อยให้พวกเขาเพิ่มเส้นทางใดก็ได้ที่พวกเขาต้องการ

ในapp/server.coffeeไฟล์ coffeescript ของฉันฉัน:

[
  'api'
  'authorization'
  'authentication'
  'domains'
  'users'
  'stylesheets'
  'javascripts'
  'tests'
  'sales'
].map (controllerName) ->
  controller = require './controllers/' + controllerName
  controller.setup app

ดังนั้นฉันมีไฟล์เช่น:

app/controllers/api.coffee
app/controllers/authorization.coffee
app/controllers/authentication.coffee
app/controllers/domains.coffee

และเช่นในตัวควบคุมโดเมนของฉันฉันมีsetupฟังก์ชั่นเช่นนี้

exports.setup = (app) ->
  controller = new exports.DomainController
  route = '/domains'
  app.post route, controller.create
  app.put route, api.needId
  app.delete route, api.needId
  route = '/domains/:id'
  app.put route, controller.loadDomain, controller.update
  app.del route, controller.loadDomain, exports.delete
  app.get route, controller.loadDomain, (req, res) ->
    res.sendJSON req.domain, status.OK

เข้าชม

การใส่มุมมองapp/viewsกลายเป็นสถานที่ตามธรรมเนียม ฉันวางมันออกเช่นนี้

app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade

ไฟล์คงที่

ไปในpublicไดเรกทอรีย่อย

Github / Semver / NPM

ใส่ไฟล์มาร์กอัป README.md ที่ราก git repo ของคุณสำหรับ github

วางไฟล์ package.json ด้วยหมายเลขเวอร์ชัน semanticในรูต git repo ของคุณสำหรับ NPM


1
เฮ้ปีเตอร์! ฉันชอบวิธีนี้ที่คุณจะทำ ฉันทำงานเกี่ยวกับการสร้างโครงการด่วนและฉันต้องการทำสิ่งที่ถูกต้องมากกว่าแค่แฮ็คมันและวางมันไว้ จะยอดเยี่ยมถ้าคุณมี repo ตัวอย่างบน github และ / หรือโพสต์บล็อกในนั้น
suVasH .....

4
repo นี้มีรูปแบบมากมายที่คุณสามารถใช้เป็นข้อมูลอ้างอิงได้: github.com/focusaurus/peterlyons.com
Peter Lyons

75
สคริปต์ Coffee ทำให้อ่านยาก: / โอกาสใดที่จะได้รับการแก้ไข JS วานิลลา? ขอบคุณ
toasted_flakes

1
ขอบคุณสำหรับคำตอบนี้ ฉันแค่พยายามปิดใจฉัน คุณเข้าถึงตัวควบคุมอื่น ๆ ภายในอื่นได้อย่างไร (เช่นในฟังก์ชั่นการตั้งค่าเช่นด้านบนapp.put route, api.needId
chmanie

@PeterLyons: เฮ้ชายฉันเห็นซอร์สโค้ดของคุณ แต่ไม่รู้ว่าจะทำอย่างไรในโหมด build ฉันได้ติดตั้งGoและรวมbinไฟล์ไว้ในโครงสร้างแล้ว คุณเรียกใช้goไฟล์นั้นได้binอย่างไร
user2002495

51

ต่อไปนี้คือคำตอบทุกคำตอบของ Peter Lyons ซึ่งส่งต่อไปยัง Vanilla JS จาก Coffeescript ตามที่ผู้อื่นหลายคนร้องขอ คำตอบของปีเตอร์สามารถทำได้มากและทุกคนที่ลงคะแนนในคำตอบของฉันควรลงคะแนนให้เขาเช่นกัน


การกำหนดค่า

คุณกำลังทำอะไรอยู่ ฉันชอบตั้งค่าเนมสเปซของตัวเองในconfig.jsไฟล์ระดับบนสุดด้วยเนมสเปซที่ซ้อนกันเช่นนี้

// Set the current environment to true in the env object
var currentEnv = process.env.NODE_ENV || 'development';
exports.appName = "MyApp";
exports.env = {
  production: false,
  staging: false,
  test: false,
  development: false
};  
exports.env[currentEnv] = true;
exports.log = {
  path: __dirname + "/var/log/app_#{currentEnv}.log"
};  
exports.server = {
  port: 9600,
  // In staging and production, listen loopback. nginx listens on the network.
  ip: '127.0.0.1'
};  
if (currentEnv != 'production' && currentEnv != 'staging') {
  exports.enableTests = true;
  // Listen on all IPs in dev/test (for testing from other machines)
  exports.server.ip = '0.0.0.0';
};
exports.db {
  URL: "mongodb://localhost:27017/#{exports.appName.toLowerCase()}_#{currentEnv}"
};

นี่เป็นมิตรสำหรับการแก้ไขดูแลระบบ จากนั้นเมื่อฉันต้องการบางสิ่งเช่นข้อมูลการเชื่อมต่อฐานข้อมูล

require('./config').db.URL

เส้นทาง / ควบคุม

ฉันชอบออกจากเส้นทางของฉันกับตัวควบคุมของฉันและจัดระเบียบพวกเขาในapp/controllersไดเรกทอรีย่อย จากนั้นฉันสามารถโหลดมันและปล่อยให้พวกเขาเพิ่มเส้นทางใดก็ได้ที่พวกเขาต้องการ

ในapp/server.jsไฟล์จาวาสคริปต์ของฉันฉัน:

[
  'api',
  'authorization',
  'authentication',
  'domains',
  'users',
  'stylesheets',
  'javascripts',
  'tests',
  'sales'
].map(function(controllerName){
  var controller = require('./controllers/' + controllerName);
  controller.setup(app);
});

ดังนั้นฉันมีไฟล์เช่น:

app/controllers/api.js
app/controllers/authorization.js
app/controllers/authentication.js
app/controllers/domains.js

และเช่นในตัวควบคุมโดเมนของฉันฉันมีsetupฟังก์ชั่นเช่นนี้

exports.setup = function(app) {
  var controller = new exports.DomainController();
  var route = '/domains';
  app.post(route, controller.create);
  app.put(route, api.needId);
  app.delete(route, api.needId);
  route = '/domains/:id';
  app.put(route, controller.loadDomain, controller.update);
  app.del(route, controller.loadDomain, function(req, res){
    res.sendJSON(req.domain, status.OK);
  });
}

เข้าชม

การใส่มุมมองapp/viewsกลายเป็นสถานที่ตามธรรมเนียม ฉันวางมันออกเช่นนี้

app/views/layout.jade
app/views/about.jade
app/views/user/EditUser.jade
app/views/domain/EditDomain.jade

ไฟล์คงที่

ไปในpublicไดเรกทอรีย่อย

Github / Semver / NPM

ใส่ไฟล์มาร์กอัป README.md ที่ราก git repo ของคุณสำหรับ github

วางไฟล์ package.json ด้วยหมายเลขเวอร์ชัน semanticในรูต git repo ของคุณสำหรับ NPM


43

คำถามของฉันถูกนำมาใช้ในเดือนเมษายน 2011 มันเงียบเก่า ในช่วงเวลานี้ฉันสามารถปรับปรุงประสบการณ์ของฉันด้วย Express.js และวิธีสร้างแอปพลิเคชันที่เขียนโดยใช้ไลบรารีนี้ ดังนั้นฉันแบ่งปันประสบการณ์ของฉันที่นี่

นี่คือโครงสร้างไดเรกทอรีของฉัน:

├── app.js   // main entry
├── config   // The configuration of my applications (logger, global config, ...)
├── models   // The model data (e.g. Mongoose model)
├── public   // The public directory (client-side code)
├── routes   // The route definitions and implementations
├── services // The standalone services (Database service, Email service, ...)
└── views    // The view rendered by the server to the client (e.g. Jade, EJS, ...)

App.js

เป้าหมายของapp.jsไฟล์คือบู๊ตแอ็พพลิเคชัน expressjs โหลดโมดูลการกำหนดค่าโมดูลตัวบันทึกรอการเชื่อมต่อฐานข้อมูล ... และเรียกใช้เซิร์ฟเวอร์ด่วน

'use strict';
require('./config');
var database = require('./services/database');
var express = require('express');
var app = express();
module.exports = app;

function main() {
  var http = require('http');

  // Configure the application.
  app.configure(function () {
    // ... ... ...
  });
  app.configure('production', function () {
    // ... ... ...
  });
  app.configure('development', function () {
    // ... ... ...
  });

  var server = http.createServer(app);

  // Load all routes.
  require('./routes')(app);

  // Listen on http port.
  server.listen(3000);
}

database.connect(function (err) {
  if (err) { 
    // ...
  }
  main();
});

เส้นทาง /

ไดเรกทอรีเส้นทางมีindex.jsไฟล์ เป้าหมายของมันคือการแนะนำเวทย์มนตร์ในการโหลดไฟล์อื่น ๆ ทั้งหมดในroutes/ไดเรกทอรี นี่คือการใช้งาน:

/**
 * This module loads dynamically all routes modules located in the routes/
 * directory.
 */
'use strict';
var fs = require('fs');
var path = require('path');

module.exports = function (app) {
  fs.readdirSync('./routes').forEach(function (file) {
    // Avoid to read this current file.
    if (file === path.basename(__filename)) { return; }

    // Load the route file.
    require('./' + file)(app);
  });
};

ด้วยโมดูลนั้นการสร้างนิยามเส้นทางใหม่และการนำไปใช้งานนั้นง่ายมาก ตัวอย่างเช่นhello.js:

function hello(req, res) {
  res.send('Hello world');
}

module.exports = function (app) {
  app.get('/api/hello_world', hello);
};

โมดูลแต่ละเส้นทางเป็นแบบสแตนด์อโลน


คุณใช้ตัวสร้างเพื่อสร้างโครงสร้างนี้หรือไม่?
Ashish

18

ฉันชอบที่จะใช้ "แอพ" ทั่วโลกแทนที่จะส่งออกฟังก์ชั่น ฯลฯ


ฉันเลือกที่จะรับคำแนะนำจากผู้สร้าง :) BTW คุณช่วยบอกรหัสให้เราหน่อยได้ไหม?
จุติ

ถูกตัอง. ในแอพนี้ที่คุณเห็น - github.com/visionmedia/sc
Screenshot

17

ฉันคิดว่ามันเป็นวิธีที่ยอดเยี่ยมที่จะทำ ไม่ จำกัด เฉพาะการแสดง แต่ฉันได้เห็นหลายโครงการ node.js ใน github ทำสิ่งเดียวกัน พวกเขาใช้พารามิเตอร์การกำหนดค่า + โมดูลที่เล็กกว่า (ในบางกรณี URI ทุกอัน) จะแยกออกเป็นไฟล์ต่าง ๆ

ฉันอยากจะแนะนำให้ดำเนินการผ่านโครงการที่เฉพาะเจาะจงเกี่ยวกับ GitHub เพื่อรับความคิด IMO วิธีที่คุณกำลังทำถูกต้อง


16

ตอนนี้เป็นสิ้นปี 2558และหลังจากการพัฒนาโครงสร้างของฉันเป็นเวลา 3 ปีและในโครงการขนาดเล็กและขนาดใหญ่ สรุป?

อย่าทำ MVC ขนาดใหญ่ แต่แยกเป็นโมดูล

ดังนั้น...

ทำไม?

  • โดยปกติจะใช้งานได้ในโมดูลเดียว (เช่นผลิตภัณฑ์) ซึ่งคุณสามารถเปลี่ยนได้อย่างอิสระ

  • คุณสามารถนำโมดูลกลับมาใช้ใหม่ได้

  • คุณสามารถทดสอบมันแยกกัน

  • คุณสามารถแทนที่มันได้อย่างชัดเจน

  • มีอินเตอร์เฟสที่ชัดเจน (เสถียร)

    - ล่าสุดหากมีนักพัฒนาหลายคนทำงานการแยกโมดูลช่วย

nodebootstrapโครงการมีวิธีการคล้ายกับโครงสร้างสุดท้ายของผม ( github )

โครงสร้างนี้มีลักษณะอย่างไร

  1. โมดูลขนาดเล็กที่ถูก capsulesแต่ละโมดูลจะมี MVC แยกกัน

  2. แต่ละโมดูลมีแพ็คเกจ.json

  3. การทดสอบเป็นส่วนหนึ่งของโครงสร้าง (ในแต่ละโมดูล)

  4. การกำหนดค่าระดับโลก , ไลบรารีและบริการ

  5. Integrated Docker, Cluster, Forever

Folderoverview (ดูโฟลเดอร์ lib สำหรับโมดูล):

โครงสร้าง nodebootstrap


3
มันจะมีประโยชน์ถ้าคุณสามารถอัปเดตภาพรวมของโฟลเดอร์โดยที่แต่ละโมดูลนั้นขยายเช่นกันตัวอย่างของวิธีที่คุณจะจัดโครงสร้างเหล่านั้นเช่นกัน
youngrrrr

8

ฉันกำลังให้โครงสร้างโฟลเดอร์สไตล์ MVC โปรดค้นหาร้อง

เราใช้โครงสร้างโฟลเดอร์ร้องสำหรับเว็บแอปพลิเคชันขนาดใหญ่และขนาดกลางของเรา

 myapp   
|
|
|____app
|      |____controllers
|      |    |____home.js
|      |
|      |____models
|      |     |___home.js
|      |
|      |____views
|           |___404.ejs
|           |___error.ejs
|           |___index.ejs
|           |___login.ejs
|           |___signup.ejs
|   
|
|_____config
|     |___auth.js
|     |___constants.js
|     |___database.js
|     |___passport.js
|     |___routes.js
|
|
|____lib
|    |___email.js
|
|____node_modules
|
|
|____public.js
|    |____css
|    |    |__style.css
|    |    
|    |____js
|    |    |__script.js
|    |
|    |____img
|    |    |__img.jpg
|    |
|    |
|    |____uploads
|         |__img.jpg
|      
|   
|
|_____app.js
|
|
|
|_____package.json

ฉันได้สร้างหนึ่งโมดูล npm สำหรับการสร้างโครงสร้างโฟลเดอร์ด่วน mvc

กรุณาค้นหาร้อง https://www.npmjs.com/package/express-mvc-generator

เพียงขั้นตอนง่ายๆในการสร้างและใช้โมดูลนี้

i) ติดตั้งโมดูล npm install express-mvc-generator -g

ii) ตัวเลือกการตรวจสอบ express -h

iii) สร้างโครงสร้าง mvc แบบด่วน express myapp

iv) ติดตั้งการพึ่งพาnpm install::

v) เปิด config / database.js ของคุณกรุณากำหนดค่า mongo db ของคุณ

vi) เรียกใช้แอปพลิเคชันnode appหรือnodemon app

vii) ตรวจสอบ URL http: // localhost: 8042 / สมัครสมาชิกหรือhttp: // yourip: 8042 / สมัครสมาชิก


7

เป็นเวลาพอสมควรแล้วที่คำตอบสุดท้ายของคำถามนี้และ Express ได้เปิดตัวเวอร์ชัน 4 ซึ่งเพิ่มสิ่งที่มีประโยชน์เล็กน้อยสำหรับการจัดโครงสร้างแอปของคุณ

ด้านล่างนี้เป็นโพสต์บล็อกที่ทันสมัยเกี่ยวกับวิธีปฏิบัติที่ดีที่สุดในการจัดโครงสร้างแอป Express ของคุณ http://www.terlici.com/2014/08/25/best-practices-express-structure.html

นอกจากนี้ยังมีพื้นที่เก็บข้อมูล GitHub ใช้คำแนะนำในบทความ เป็นรุ่นล่าสุดเสมอกับ Express เวอร์ชันล่าสุด
https://github.com/terlici/base-express


7

ฉันไม่คิดว่ามันเป็นวิธีที่ดีในการเพิ่มเส้นทางเพื่อกำหนดค่า โครงสร้างที่ดีขึ้นอาจเป็นดังนี้:

application/
| - app.js
| - config.js
| - public/ (assets - js, css, images)
| - views/ (all your views files)
| - libraries/ (you can also call it modules/ or routes/)
    | - users.js
    | - products.js
    | - etc...

ดังนั้น products.js และ users.js จะมีเส้นทางทั้งหมดของคุณทั้งหมดจะตรรกะภายใน


6

ดีฉันวางเส้นทางของฉันเป็นไฟล์ json ที่ฉันอ่านที่จุดเริ่มต้นและใน for-loop ใน app.js ตั้งค่าเส้นทาง route.json รวมถึงมุมมองที่ควรเรียกใช้และคีย์สำหรับค่าที่จะส่งไปยังเส้นทาง
สิ่งนี้ใช้ได้กับกรณีง่าย ๆ มากมาย แต่ฉันต้องสร้างเส้นทางบางอย่างสำหรับกรณีพิเศษด้วยตนเอง


6

ฉันได้เขียนโพสต์เกี่ยวกับเรื่องนี้อย่างแน่นอน มันเป็นพื้นทำให้การใช้งานrouteRegistrarที่ iterates ผ่านไฟล์ในโฟลเดอร์เรียกฟังก์ชั่น/controllers initฟังก์ชั่นinitใช้appตัวแปรด่วนเป็นพารามิเตอร์เพื่อให้คุณสามารถลงทะเบียนเส้นทางของคุณในแบบที่คุณต้องการ

var fs = require("fs");
var express = require("express");
var app = express();

var controllersFolderPath = __dirname + "/controllers/";
fs.readdirSync(controllersFolderPath).forEach(function(controllerName){
    if(controllerName.indexOf("Controller.js") !== -1){
        var controller = require(controllersFolderPath + controllerName);
        controller.init(app);
    }
});

app.listen(3000);

5

สิ่งนี้อาจเป็นที่สนใจ:

https://github.com/flatiron/nconf

การกำหนดค่าลำดับชั้น node.js พร้อมไฟล์ตัวแปรสภาพแวดล้อมอาร์กิวเมนต์บรรทัดคำสั่งและการรวมวัตถุอะตอมมิก


4

1) ระบบไฟล์โครงการ Express ของคุณอาจจะชอบ:

/ ...
/lib
/node_modules
/public
/views
      app.js
      config.json
      package.json

app.js - แอพคอนเทนเนอร์ทั่วโลกของคุณ

2) ไฟล์หลักโมดูล (lib / mymodule / index.js):

var express = require('express');    
var app = module.exports = express();
// and load module dependencies ...  

// this place to set module settings
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');

// then do module staff    
app.get('/mymodule/route/',function(req,res){ res.send('module works!') });

3) เชื่อมต่อโมดูลใน main app.js

...
var mymodule = require('mymodule');
app.use(mymodule);

4) ตรรกะตัวอย่าง

lib/login
lib/db
lib/config
lib/users
lib/verify
lib/
   /api/ 
   ...
lib/
   /admin/
      /users/
      /settings/
      /groups/
...
  • ดีที่สุดสำหรับการทดสอบ
  • ดีที่สุดสำหรับขนาด
  • แยกขึ้นอยู่กับโมดูล
  • การจัดกลุ่มเส้นทางตามหน้าที่ (หรือโมดูล)

TJกล่าวแสดง / ความคิดที่น่าสนใจ Vimeo วิธี modularize แสดงการประยุกต์ใช้ - การใช้งานเว็บ Modular กับ Node.js และเอ็กซ์เพรส ทรงพลังและเรียบง่าย


4

http://locomotivejs.org/เป็นวิธีสร้างโครงสร้างแอปที่สร้างขึ้นด้วย Node.js และ Express

จากเว็บไซต์:

"Locomotive เป็นเว็บเฟรมเวิร์กสำหรับ Node.js. Locomotive สนับสนุนรูปแบบ MVC เส้นทาง RESTful และการประชุมเกี่ยวกับการกำหนดค่าในขณะที่ทำงานร่วมกับฐานข้อมูลและแม่แบบเครื่องยนต์ได้อย่างราบรื่น Locomotive สร้างบน Express รักษาพลังและความเรียบง่ายที่คุณคาดหวัง จากโหนด "


3

ฉันเพิ่งนำโมดูลมาเป็นมินิแอพอิสระ

|-- src
  |--module1
  |--module2
     |--www
       |--img
       |--js
       |--css
     |--#.js
     |--index.ejs
  |--module3
  |--www
     |--bower_components
     |--img
     |--js
     |--css
  |--#.js
  |--header.ejs
  |--index.ejs
  |--footer.ejs

ตอนนี้สำหรับการกำหนดเส้นทางโมดูล (# .js), มุมมอง (* .ejs), js, css และเนื้อหาอยู่ติดกัน การกำหนดเส้นทาง submodule ถูกตั้งค่าใน parent # .js ด้วยสองบรรทัดเพิ่มเติม

router.use('/module2', opt_middleware_check, require('./module2/#'));
router.use(express.static(path.join(__dirname, 'www')));

วิธีนี้แม้จะเป็นโมดูลย่อยที่เป็นไปได้

อย่าลืมตั้งค่ามุมมองเป็นไดเร็กทอรี src

app.set('views', path.join(__dirname, 'src'));

ลิงก์ไปยัง GitHub ที่มีโครงสร้างดังกล่าวสนใจที่จะดูว่ามีการโหลดเส้นทางมุมมองและโมเดลอย่างไร
Muhammad Umer

ฉันคิดว่าทุกอย่างถูกอธิบาย เส้นทางเป็นเพียงเส้นทางด่วนคลาสสิก มุมมองจำเป็นต้องโหลดคำนำหน้าด้วยชื่อโมดูลโมเดลต้องโหลดโดยการอ้างอิงพา ธ สัมพัทธ์
zevero

ในบรรทัดสุดท้ายของฉันฉันตั้งค่ามุมมองไปยังไดเรกทอรี src ดังนั้นจากที่นี่เป็นต้นไปมุมมองทั้งหมดสามารถเข้าถึงได้โดยสัมพันธ์กับไดเรกทอรี src ไม่มีอะไรแฟนซี
zevero

1

นี่คือลักษณะโครงสร้างไดเรกทอรีโครงการเอ็กซ์เพรสของฉันส่วนใหญ่

ฉันมักจะทำexpress dirnameเพื่อเริ่มต้นโครงการให้อภัยความเกียจคร้านของฉัน แต่มันมีความยืดหยุ่นและขยายได้มาก ป.ล. - คุณต้องรับexpress-generatorสิ่งนั้น (สำหรับผู้ที่กำลังมองหามันsudo npm install -g express-generatorsudo เพราะคุณกำลังติดตั้งทั่วโลก)

|-- bin
    |-- www //what we start with "forever"
|-- bower_components
|-- models
    |-- database.js
    |-- model1.js //not this exact name ofcourse.
    |-- .
|-- node_modules
|-- public
    |-- images
    |-- javascripts
        |-- controllers
        |-- directives
        |-- services
        |-- app.js
        |-- init.js //contains config and used for initializing everything, I work with angular a lot.
    |-- stylesheets
|-- routes
    |-- some
    |-- hierarchy
    .
    .
|-- views
    |-- partials
    |-- content
|-- .env
|-- .env.template
|-- app.js
|-- README.md

คุณต้องสงสัยว่าทำไมไฟล์. env เพราะพวกเขาทำงาน! ฉันใช้dotenvโมดูลในโครงการของฉัน (เร็ว ๆ นี้) และใช้งานได้! ปรากฏในงบ 2 เหล่านี้ในapp.jsหรือwww

var dotenv = require('dotenv');
dotenv.config({path: path.join(__dirname + "/.env")});

และอีกหนึ่งบรรทัดที่จะตั้งค่าอย่างรวดเร็ว/bower_componentsเพื่อให้บริการเนื้อหาคงที่ภายใต้ทรัพยากร/ext

app.use('/ext', express.static(path.join(__dirname, 'bower_components')));

อาจเหมาะสำหรับผู้ที่ต้องการใช้ Express และ Angular ด้วยกันหรือเพียงแค่แสดงออกโดยไม่มีjavascriptsลำดับชั้นของหลักสูตรนั้น


1

โครงสร้างของฉันด่วน 4. https://github.com/odirleiborgert/borgert-express-boilerplate

แพคเกจ

View engine: twig
Security: helmet
Flash: express-flash
Session: express-session
Encrypt: bcryptjs
Modules: express-load
Database: MongoDB
    ORM: Mongoose
    Mongoose Paginate
    Mongoose Validator
Logs: winston + winston-daily-rotate-file
Nodemon
CSS: stylus
Eslint + Husky

โครงสร้าง

|-- app
    |-- controllers
    |-- helpers
    |-- middlewares
    |-- models
    |-- routes
    |-- services
|-- bin
|-- logs
|-- node_modules
|-- public
    |-- components
    |-- images
    |-- javascripts
    |-- stylesheets
|-- views
|-- .env
|-- .env-example
|-- app.js
|-- README.md

0

วิธีง่ายๆในการจัดโครงสร้างแอป ur express:

  • ใน main.js คำสั่งต่อไปนี้ควรได้รับการปรับปรุง

    แอปทั้งหมดชุดควรเป็นอันดับแรก

    app.useทั้งหมดควรเป็นที่สอง

    ตามด้วย apis อื่น ๆ ที่มีฟังก์ชั่นหรือเส้นทางดำเนินการต่อในไฟล์อื่น ๆ

    Exapmle

    app.use ("/ รหัสผ่าน", passwordApi);

    app.use ("/ user", userApi);

    app.post ("/ โทเค็น", passport.createToken);

    app.post ("/ logout", passport.logout)


0

วิธีที่ดีที่สุดในการจัดทำโครงสร้าง MVC สำหรับโครงการ ExpressJs ด้วยมือจับ & Passportjs

- app
      -config 
        -passport-setup.js
      -controllers
      -middleware
      -models
      -routes
      -service
    -bin
      -www
      -configuration.js
      -passport.js
    -node_modules
    -views
     -handlebars page
    -env
    -.gitignore
    -package.json
    -package-lock.json

โปรดตรวจสอบ @ sandro-munda
Manishkumar Bhavnani
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.