node.js - شرح - express vpn




ExpressJS كيفية بناء تطبيق؟ (12)

أستخدم إطار ويب ExpressJS لـ NodeJS.

يضع الأشخاص الذين يستخدمون ExpressJS بيئاتهم (التطوير والإنتاج والاختبار ...) app.js وما إلى ذلك على 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);

التكوين / 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());
    });
};

التكوين / routes.js

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

تعمل التعليمة البرمجية الخاصة بي بشكل جيد وأعتقد أن بنية الدلائل جميلة. ومع ذلك ، كان يجب تكييف الكود ، ولست متأكدًا من أنه جيد / جميل.

هل من الأفضل استخدام تركيبة الدلائل وتهيئة التعليمة البرمجية أو ببساطة استخدام ملف واحد (app.js)؟

شكرا على النصائح الخاصة بك!


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) قم بتوصيل وحدة في 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/
...
  • أفضل للاختبار
  • الأفضل للحصول على نطاق واسع
  • فصل يعتمد من الوحدة
  • التجميع حسب الوظيفة (أو الوحدات)

says/show on Vimeo interesting idea how modularize express application - Modular web applications with Node.js and Express . Powerful and simple.


أحب استخدام "تطبيق" عالمي ، بدلاً من تصدير دالة إلخ


تم طرح سؤالي في أبريل 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);
};

كل وحدة مسار هو مستقل .



حسنًا ، لقد كان هذا بعض الوقت ، وهذا سؤال شائع ، لذا فقد تقدمت لإنشاء مستودع github بسقالة مع شفرة جافا سكريبت و README طويل حول الطريقة التي أرغب بها في تصميم تطبيق express.js متوسط ​​الحجم.

focusaurus/express_code_structure هو الريبو مع أحدث رمز لهذا. سحب الطلبات الترحيب.

إليك لقطة من README لأن لا يعجبك فقط إجابات الارتباط. سأقوم بإجراء بعض التحديثات لأن هذا هو مشروع جديد سأستمر في تحديثه ، ولكن في نهاية المطاف سيكون ريبو جيثوب هو المكان الجديد لهذه المعلومات.

هيكل الرمز السريع

هذا المشروع هو مثال على كيفية تنظيم تطبيق ويب express.js متوسطة الحجم.

الحالي على الأقل صريح v4.14 ديسمبر 2016

ما حجم الطلب؟

تطبيقات الويب ليست متماثلة ، ولا يوجد ، في رأيي ، بنية كود واحدة يجب تطبيقها على جميع تطبيقات express.js.

إذا كان طلبك صغيرًا ، فلن تحتاج إلى بنية دليل عميقة كما هو موضح هنا. فقط ابق الأمر بسيطًا واحصل على عدد قليل من ملفات .js في جذر .js تكون قد انتهيت. فويلا.

إذا كان تطبيقك ضخمًا ، فستحتاج في وقت ما إلى تقسيمه إلى حزم npm مميزة. بشكل عام ، يبدو أن طريقة node.js تفضل العديد من الحزم الصغيرة ، على الأقل بالنسبة للمكتبات ، ويجب أن تبني التطبيق الخاص بك باستخدام العديد من حزم npm حيث يبدأ ذلك في المعقول وتبرير النفقات العامة. عندما ينمو تطبيقك ويصبح جزء من الشفرة قابلا لإعادة الاستخدام بشكل واضح خارج التطبيق الخاص بك أو هو نظام فرعي واضح ، قم بنقله إلى مستودع git الخاص به واجعله في حزمة npm المستقلة.

لذلك فإن تركيز هذا المشروع هو توضيح هيكل عملي لتطبيق متوسط ​​الحجم.

ما هو العمارة العامة الخاصة بك

هناك العديد من الطرق لبناء تطبيق على شبكة الإنترنت ، مثل

  • الخادم الجانب MVC a la Ruby on Rails
  • نمط تطبيق صفحة واحدة a la MongoDB / Express / Angular / Node (MEAN)
  • موقع الويب الأساسي مع بعض النماذج
  • النماذج / العمليات / المشاهدات / نمط الأحداث a la MVC is dead، it's time to MOVE on
  • وغيرها الكثير على حد سواء الحالية والتاريخية

كل من هذه تناسبها بشكل جيد في بنية دليل مختلفة. لأغراض هذا المثال ، إنها مجرد سقالات وليست تطبيقًا يعمل بشكل كامل ، ولكن أفترض بنقاط العمارة الرئيسية التالية:

  • يحتوي الموقع على بعض الصفحات / النماذج الثابتة التقليدية
  • تم تطوير جزء "التطبيق" من الموقع كنمط تطبيق صفحة واحدة
  • يعرض التطبيق واجهة برمجة تطبيقات نمط REST / JSON إلى المستعرض
  • التطبيق نماذج مجال عمل بسيطة ، في هذه الحالة ، انها تطبيق بيع السيارات

وماذا عن روبي على القضبان؟

سيكون موضوعًا طوال هذا المشروع أن العديد من الأفكار المتجسدة في Ruby on Rails وقرارات "الاتفاقية عبر التهيئة" التي اعتمدتها ، على الرغم من قبولها واستخدامها على نطاق واسع ، ليست مفيدة جدًا في بعض الأحيان وأحيانًا ما تكون عكس ما هو هذا المستودع يوصي.

النقطة الأساسية هنا هي أن هناك مبادئ أساسية لتنظيم المدونة ، وبناءً على تلك المبادئ ، فإن معاهدات روبي أون ريلز منطقية (في الغالب) لمجتمع روبي أون ريلز. ومع ذلك ، فإن هذه الاتفاقيات لا تفوّت على هذه النقطة. وبمجرد تخطي المبادئ الأساسية ، ستكون جميع مشاريعك منظمة تنظيما جيدا وواضحة: برامج نصية ، وألعاب ، وتطبيقات الجوال ، ومشاريع الشركات ، وحتى دليل منزلك.

بالنسبة لمجتمع Rails ، فإنهم يريدون أن يكون لديهم مفتاح تبديل Rails واحد من التطبيق إلى التطبيق إلى التطبيق ويكون مألوفًا ومريحًا معه في كل مرة. وهذا أمر منطقي إذا كنت 37 إشارة أو مختبرات محورية ، ولها فوائد. في عالم جافا سكريبت من جانب الخادم ، فإن الروح الشاملة هي مجرد شيء أكثر غرابة في الغرب ، ولا نواجه مشكلة في ذلك. هذه هي الطريقة التي لفة. نحن معتادون على ذلك. حتى داخل express.js ، فهو قريب من سيناترا ، وليس القضبان ، واتخاذ القلادات من القضبان عادة لا يساعد أي شيء. كنت حتى أقول المبادئ على الاتفاقية على التكوين .

المبادئ الأساسية والدوافع

  • كن قابلاً عقليًا
    • يمكن للدماغ فقط التعامل والتفكير في عدد صغير من الأشياء ذات الصلة في وقت واحد. هذا هو السبب في أننا نستخدم الدلائل. إنه يساعدنا على التعامل مع التعقيد من خلال التركيز على أجزاء صغيرة.
  • تكون مناسبة للحجم
    • لا تقم بإنشاء "دلائل Mansion" حيث يوجد ملف واحد فقط كل الدلائل وحدها 3 أسفل. يمكنك أن ترى هذا يحدث في أفضل الممارسات Ansible Best التي تخجل المشاريع الصغيرة في إنشاء 10+ دلائل لحفظ 10+ ملفات عندما يكون دليل واحد مع 3 ملفات أكثر ملاءمة. أنت لا تقود حافلة للعمل (ما لم تكن سائق حافلة ، ولكن حتى عند القيادة الخاصة بك لا تعمل الحافلة AT للعمل) ، لذلك لا تقم بإنشاء هياكل نظام ملفات لا يتم تبريرها بواسطة الملفات الفعلية الموجودة بداخلها .
  • كن معياريًا لكن عمليًا
    • يفضل مجتمع العقدة بشكل عام الوحدات الصغيرة. يجب أن يتم استخراج أي شيء يمكن فصله تمامًا عن تطبيقك في وحدة نمطية إما للاستخدام الداخلي أو نشره علنيًا على npm. ومع ذلك ، بالنسبة للتطبيقات متوسطة الحجم التي هي النطاق هنا ، يمكن أن يزيد الحمل فوق ذلك tedium إلى سير عملك دون قيمة متناسبة. لذا بالنسبة للوقت الذي يكون فيه لديك بعض التعليمات البرمجية التي يتم أخذها في الاعتبار ولكن لا يكفي لتبرير وحدة npm منفصلة تمامًا ، فكر فقط في " وحدة نمطية " مع توقع أنه عندما يعبر بعض عتبة الحجم ، سيتم استخراجه.
    • بعض الأشخاص مثل @hij1nx حتى تتضمن دليل app/node_modules ولديهم ملفات package.json في الدلائل وحدة نمطية لتسهيل هذا التحول والعمل بمثابة تذكير.
  • يكون من السهل تحديد موقع الرمز
    • نظرًا لميزة الإنشاء أو الخطأ المطلوب إصلاحه ، فإن هدفنا هو ألا يواجه مطور البرامج صعوبات في تحديد مصدر الملفات المعنية.
    • الأسماء ذات مغزى ودقة
    • يتم إزالة رمز cruphty بالكامل ، لا تترك في ملف اليتيم أو علق للتو
  • كن سهل الاستخدام
    • جميع التعليمات البرمجية المصدر للحزب الأول موجودة في دليل app حتى تتمكن من تشغيل cd / find / grep / xargs / ag / ack / etc وعدم تشتيت انتباهك عن طريق طرف ثالث
  • استخدم تسمية بسيطة وواضحة
    • يبدو الآن أن npm تتطلب أسماء الحزم الصغيرة. أجد هذا في معظمه رهيب لكن يجب أن أتبع القطيع ، لذا يجب أن تستخدم أسماء الملفات حالة kebab-case حتى وإن كان اسم المتغير لذلك في JavaScript يجب أن يكون camelCase لأن - هو علامة ناقص في JavaScript.
    • يتطابق اسم المتغير مع الاسم الأساسي لمسار الوحدة ، ولكن مع تحويل kebab-case إلى camelCase
  • مجموعة عن طريق اقتران ، وليس عن طريق وظيفة
    • هذا هو الخروج الرئيسي من اتفاقية روبي أون ريلز من app/views app/controllers app/models ، وما إلى ذلك
    • تتم إضافة الميزات إلى مجموعة كاملة ، لذلك أريد التركيز على مجموعة كاملة من الملفات ذات الصلة بميزتي. عندما أقوم بإضافة حقل رقم هاتف إلى نموذج المستخدم ، لا يهمني أي وحدة تحكم غير وحدة تحكم المستخدم ، ولا يهمني أي طراز بخلاف طراز المستخدم.
    • لذا بدلاً من تحرير 6 ملفات موجودة في الدليل الخاص بهم وتجاهل العديد من الملفات الأخرى في هذه الأدلة ، يتم تنظيم هذا المخزون بحيث يتم تخزين جميع الملفات التي أحتاجها لإنشاء ميزة
    • من طبيعة MVC ، يقترن عرض المستخدم إلى وحدة تحكم المستخدم التي تقترن بنموذج المستخدم. لذلك عندما أغير نموذج المستخدم ، فغالبًا ما تتغير هذه الملفات الثلاثة معًا ، ولكن يتم فصل وحدة التحكم في الصفقات أو وحدة التحكم في العميل وبالتالي لا يتم تضمينها. وينطبق الشيء نفسه على تصميمات غير MVC عادةً أيضًا.
    • MVC أو MOVE لا يمكن فك تشفير نمط من حيث الكود الذي لا يزال يتم فيه تشجيع الوحدة النمطية ، ولكن نشر ملفات MVC إلى دلائل الأخوة هو مجرد مزعج.
    • وبالتالي ، تحتوي كل ملف من مساراتي على جزء من المسارات التي يمتلكها. routes.rb ملف routes.rb غرار القضبان مفيدًا إذا كنت تريد عرضًا عامًا لجميع المسارات في التطبيق ، ولكن عند إنشاء الميزات وإصلاح الأخطاء ، فإنك تهتم فقط بالطرق ذات الصلة بالقطعة التي تقوم بتغييرها.
  • اختبارات المتجر بجانب الرمز
    • هذا مجرد مثال على "المجموعة بالاقتران" ، لكني أردت أن أصفها على وجه التحديد. لقد قمت بكتابة العديد من المشاريع حيث تعيش الاختبارات تحت نظام ملفات موازٍ يسمى "الاختبارات" ، والآن بعد أن بدأت في وضع اختباراتي في نفس الدليل مثل رمزها المقابل ، لن أعود أبداً. هذا هو أكثر وحدات وأكثر سهولة في العمل مع المحررين في النص ويخفف الكثير من "../../ .." مسار هراء. إذا كنت في شك ، جربه على عدد قليل من المشاريع وقررت بنفسك. لن أفعل أي شيء بعد هذا لإقناعك أنه أفضل.
  • الحد من اقتران المتقاطع مع الأحداث
    • من السهل التفكير في "حسنًا ، عندما يتم إنشاء صفقة جديدة ، أريد إرسال رسالة بريد إلكتروني إلى جميع مندوبي المبيعات" ، ثم وضع الشفرة لإرسال الرسائل الإلكترونية في المسار الذي ينشئ صفقات.
    • ومع ذلك ، فإن هذا الاقتران سيحول تطبيقك في النهاية إلى كرة طينية عملاقة.
    • بدلاً من ذلك ، يجب على DealModel فقط إطلاق حدث "إنشاء" وأن يكون غير مدرك تمامًا لما قد يفعله النظام استجابةً لذلك.
    • عندما تقوم بالتدوين بهذه الطريقة ، يصبح من الممكن وضع كل التعليمات البرمجية app/users في app/users لأنه لا يوجد عش للفأر لمنطق العمل المتقارن في كل مكان يلوث نقاء قاعدة كود المستخدم.
  • تدفق الكود هو متبع
    • لا تفعل الأشياء السحرية. لا تقم بالامتحان التلقائي للملفات من الدلائل السحرية في نظام الملفات. لا تكون قضبان. يبدأ التطبيق على app/server.js:1 ويمكنك رؤية كل شيء يتم تحميله app/server.js:1 خلال اتباع الشفرة.
    • لا تجعل DSLs لمساراتك. لا تتعمد التحايل عندما لا يُطلب منك ذلك.
    • إذا كان تطبيقك كبيرًا إلى حد كبير ، magicRESTRouter.route(somecontroller, {except: 'POST'}) هو فوز كبير بالنسبة لك عبر 3 app.get أساسية ، app.put ، app.del ، مكالمات ، من المحتمل أنك تبني تطبيق مترابط كبير جدًا على العمل بفاعلية. احصل على فرصة رائعة لربح BIG ، وليس لتحويل 3 خطوط بسيطة إلى خط واحد معقد.
  • استخدم أسماء الملفات ذات الكباب الأقل

    • يتجنب هذا التنسيق مشكلات حساسية حالة ملفات النظام عبر الأنظمة الأساسية
    • يحظر npm الأحرف الكبيرة في أسماء الحزم الجديدة ، وهذا يعمل جيدًا مع ذلك

      تفاصيل express.js

  • لا تستخدم app.configure . انها تقريبا غير مجدية تماما وأنت فقط لا تحتاج إليها. هو في الكثير من النمطي بسبب copypasta الطائش.

  • ترتيب البضاعة والرحلات في المسائل الصريحة !!!
    • تقريبا كل مشكلة توجيه أراها على هو خارج الوسيطة اكسبرس من أجل
    • بشكل عام ، أنت تريد تفكيك مساراتك ولا تعتمد على الطلب كثيرًا
    • لا تستخدم app.use بالكامل إذا كنت تحتاج فقط إلى تلك البرامج الوسيطة app.use (أنا أبحث عنك ، body-parser )
    • تأكد من أن كل ما قيل وفعلت لديك بالضبط هذا الترتيب:
      1. أي الوسيطة تطبيق واسع للغاية
      2. جميع الطرق الخاصة بك وطرق middlewares متنوعة
      3. ثم معالجات الخطأ
  • للأسف ، كونك مستوحاة من سيناترا ، express.js في الغالب يفترض أن جميع server.js ستكون في server.js وسوف يكون من الواضح كيف يتم طلبها. بالنسبة للتطبيق ذي الحجم المتوسط ​​، فإن تقسيم الأشياء إلى وحدات منفصلة للطرق أمر رائع ، لكنه يعرض مخاطر الوسيطة غير المصنفة

خدعة سيملينك التطبيق

هناك العديد من الطرق التي تم تحديدها ومناقشتها مطوَّلاً من قبل المجتمع في البيانات الأساسية الأفضل () التي تتطلبها () مسارات Node.js. قد أقرر قريبًا أن أفضّل إما "التعامل مع الكثير من ../../../ .." أو استخدام requiredFrom modlue. ومع ذلك ، في الوقت الحالي ، كنت أستخدم خدعة الارتباط الرمزي المفصلة أدناه.

لذلك ، هناك طريقة واحدة لتجنب المشروع البيني تتطلب مسارات نسبي مزعجة مثل require("../../../config") هو استخدام الحيلة التالية:

  • إنشاء رابط رمزي ضمن node_modules لتطبيقك
    • cd node_modules && ln -nsf ../app
  • إضافة فقط symode node_modules / app نفسه ، وليس مجلد node_modules بأكمله ، إلى git
    • 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 ، يجب عليك الالتزام بمسارات الدليل الأصلي.

ترتيب

عموما الوحدات النمطية رمز والفئات أن نتوقع سوى كائن options جافا سكريبت الأساسية تمريرها. فقط app/server.js يجب تحميل الوحدة النمطية app/config.js . ومن هناك ، يمكن تجميع كائنات options الصغيرة لتكوين الأنظمة الفرعية حسب الحاجة ، ولكن اقتران كل نظام فرعي بوحدة تهيئة عالمية كبيرة مليئة بالمعلومات الإضافية هو اقتران سيئ.

حاول مركزة إنشاء اتصالات DB وتمريرها إلى أنظمة فرعية بدلاً من تمرير معلمات الاتصال وجعل الأنظمة الفرعية تقوم بالاتصالات الصادرة نفسها.

NODE_ENV

هذه فكرة مغرية أخرى ولكنها رهيبة من القضبان. يجب أن يكون هناك مكان واحد بالضبط في تطبيقك ، app/config.js الذي NODE_ENV متغير بيئة NODE_ENV . يجب أن يأخذ كل شيء خيارًا صريحًا كوسيطة منشئ فئة أو معلمة تكوين الوحدة.

إذا كان لدى وحدة البريد الإلكتروني خيارًا حول كيفية تسليم رسائل البريد الإلكتروني (SMTP ، أو تسجيل الدخول إلى stdout ، أو وضعه في قائمة الانتظار ، إلخ) ، فيجب أن يأخذ خيارًا مثل {deliver: 'stdout'} ولكن يجب ألا يتحقق NODE_ENV .

اختبارات

أحتفظ الآن بملفات الاختبار الخاصة بي في نفس الدليل مثل التعليمات البرمجية المطابقة لها واستخدم اصطلاحات تسمية ملحق اسم الملف لتمييز الاختبارات من رمز الإنتاج.

  • لدى foo.js الوحدة "foo"
  • يحتوي foo.tape.js على الاختبارات القائمة على عقدة foo ويعيش في نفس dir
  • يمكن استخدام foo.btape.js للاختبارات التي يجب تنفيذها في بيئة المتصفح

أنا استخدم نظام الملفات find . -name '*.tape.js' find . -name '*.tape.js' الأمر للوصول إلى جميع اختباراتي حسب الضرورة.

كيفية تنظيم التعليمات البرمجية داخل كل ملف الوحدة النمطية .js

يدور نطاق هذا المشروع في الغالب حول مكان الملفات والأدلة ، ولا أريد إضافة نطاق آخر ، ولكنني أذكر فقط أنني أقوم بتنظيم الكود الخاص بي إلى 3 أقسام متميزة.

  1. يتطلب فتح كتلة CommonJS إجراء مكالمات إلى اعتماديات الولاية
  2. كتلة التعليمات البرمجية الأساسية من نقية جافا سكريبت. لا تلوث CommonJS هنا. لا تشير إلى الصادرات أو الوحدة النمطية أو تتطلب.
  3. كتلة مغلقة من CommonJS لإعداد الصادرات

قد تكون هذه المصالح:

https://github.com/flatiron/nconf

تكوين node.js الهرمي مع الملفات ، متغيرات البيئة ، وسيطات سطر الأوامر ، ودمج الكائن الذري.


لقد حان الآن عام 2015 وبعد تطوير البنية لمدة 3 سنوات وفي المشاريع الصغيرة والكبيرة. استنتاج؟

لا تفعل MVC كبيرة واحدة ، ولكن فصلها في وحدات

وبالتالي...

لماذا ا؟

  • عادة ما يعمل واحد على وحدة واحدة (مثل المنتجات) ، والتي يمكنك تغييرها بشكل مستقل.

  • أنت قادر على إعادة استخدام الوحدات

  • كنت قادرا على اختبار ذلك بشكل منفصل

  • كنت قادرا على استبداله بشكل منفصل

  • لديهم واجهات واضحة (مستقرة)

    -أحدث ، إذا كان هناك العديد من المطورين تعمل ، يساعد فصل الوحدة النمطية

مشروع nodebootstrap له نهج مماثل nodebootstrap النهائية. ( github )

كيف تبدو هذه البنية؟

  1. وحدات صغيرة محمولة ، تحتوي كل منها على MVC منفصل

  2. كل وحدة لديها package.json

  3. اختبار كجزء من الهيكل (في كل وحدة)

  4. التكوين العالمي والمكتبات والخدمات

  5. وحدة التحكم المتكاملة ، المجموعة ، إلى الأبد

Folderoverview (راجع مجلد lib لوحدات):


لقد كتبت مقالا بالضبط حول هذه المسألة. وهي تستفيد أساسًا من مسار routeRegistrar الذي يتكرر عبر الملفات في المجلد /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);

ما يلي هو إجابة بيتر Lyons حرفيا ، استدار إلى الفانيليا 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}"
};

هذا الصديق للتحرير sysadmin. ثم عندما أحتاج إلى شيء ، مثل معلومات اتصال DB ، فإنه سيصدره

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

طرق / تحكم

أحب ترك مساراتي مع وحدات التحكم الخاصة بي وتنظيمها في دليل فرعي app/controllers . ثم يمكنني تحميلها والسماح لهم بإضافة أي طرق يحتاجون إليها.

في ملفي app/server.js javascript ، أقوم بما يلي:

[
  '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

ملفات ثابتة

الذهاب في دليل فرعي عام.

جيثب / Semver / الآلية الوقائية الوطنية

ضع ملف markdown README.md في الجذر git repo ل github.

ضع ملف package.json مع رقم إصدار دلالي في جذر git repo لـ NPM.


http://locomotivejs.org/ provides a way to structure an app built with Node.js and Express.

From the website:

"Locomotive is a web framework for Node.js. Locomotive supports MVC patterns, RESTful routes, and convention over configuration, while integrating seamlessly with any database and template engine. Locomotive builds on Express, preserving the power and simplicity you've come to expect from Node."


I am giving MVC style folder structure please find bellow .

We used bellow folder structure for our big and medium web applications .

 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

I have created one npm module for generation express mvc folder structurer.

Please find the bellow https://www.npmjs.com/package/express-mvc-generator

Just simple steps to generate and use this modules .

i) install module npm install express-mvc-generator -g

ii) check options express -h

iii) Generate express mvc structure express myapp

iv) Install dependencies: npm install :

v)Open your config/database.js , Please configure your mongo db.

vi)Run the application node app or nodemon app

vii)Check URL http://localhost:8042/signup OR http://yourip:8042/signup


I recently embraced modules as independent mini-apps.

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

Now for any module routing (#.js), views (*.ejs), js, css and assets are next to each other. submodule routing is set up in the parent #.js with two additional lines

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

This way even subsubmodules are possible.

Don't forget to set view to the src directory

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






express