Herramientas de usuario

Herramientas del sitio


wiki2:nodejs:patterns

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
wiki2:nodejs:patterns [2017/05/11 10:58]
alfred
wiki2:nodejs:patterns [2020/05/09 09:25] (actual)
Línea 88: Línea 88:
 }); });
 </​code>​ </​code>​
 +
 +Dependency injection is a software design pattern in which one or more dependencies (or services) are injected, or passed by reference, into a dependent object.
 +
 +Dependency injection is really helpful when it comes to testing. You can easily mock your modules'​ dependencies using this pattern.
 +<​code>​
 +var db = require('​db'​);​
 +// do some init here, or connect
 +db.init();
 +
 +var userModel = require('​User'​)({
 +  db: db
 +});
 +
 +userModel.create(function (err, user) {
 +  ​
 +});
 +</​code>​
 +<​code>​
 +var test = require('​tape'​);​
 +var userModel = require('​User'​);​
 +
 +test('​it creates a user with id', function (t) {
 +  var user = {
 +    id: 1
 +  };
 +  var fakeDb = {
 +    query: function (done) {
 +      done(null, user);
 +    }
 +  }
 +  ​
 +  userModel({
 +    db: fakeDb
 +  }).create(function (err, user) {
 +    t.equal(user.id,​ 1, 'User id should match'​);​
 +    t.end();
 +  })
 +  ​
 +});
 +</​code>​
 +<​code>​
 +function userModel (options) {
 +  var db;
 +  ​
 +  if (!options.db) {
 +    throw new Error('​Options.db is required'​);​
 +  }
 +  ​
 +  db = options.db;
 +  ​
 +  return {
 +    create: function (done) {
 +      db.query('​INSERT ...', done);
 +    }
 +  }
 +}
 +
 +module.exports = userModel;
 +</​code>​
 +In the example above we have two different dbs. In the index.js file we have the "​real"​ db module, while in the second we simply create a fake one. This way we made it really easy to inject fake dependencies into the modules we want to test.
 +
  
 ===== Middleware / Pipeline ===== ===== Middleware / Pipeline =====
Línea 122: Línea 183:
 </​code>​ </​code>​
  
-===== Modules ​=====+===== Module patterns ​=====
 Your code uses ''​require''​ to include modules. Modules use ''​exports''​ to make things available. Your code uses ''​require''​ to include modules. Modules use ''​exports''​ to make things available.
-==== 1. Define a goal ====+ 
 +Named exports - one module, many exported things. Anonymous exports - simpler client interface. 
 +==== Define a goal ====
  
 <​code>​ <​code>​
Línea 133: Línea 196:
    
 </​code>​ </​code>​
-code>+<code>
     // app.js     // app.js
     require('​./​foo.js'​);​     require('​./​foo.js'​);​
Línea 139: Línea 202:
 </​code>​ </​code>​
  
-==== 2. Export an anonymous function ====+==== Export an anonymous function ====
 <​code>​ <​code>​
  
Línea 153: Línea 216:
  </​code>​  </​code>​
  
-==== 3. Export a named function ====+==== Export a named function ====
 <​code>​ <​code>​
  
Línea 168: Línea 231:
  </​code>​  </​code>​
  
-==== 4. Export an anonymous object ====+==== Export an anonymous object ====
 <​code>​ <​code>​
  
Línea 207: Línea 270:
    
 </​code>​ </​code>​
 +
 +==== Export an anonymous prototype ====
 +<​code>​
 +
 +    // doo.js
 +    var Doo = function () {};
 +
 +    Doo.prototype.log = function () {
 +        console.log('​doo!'​);​
 +    }
 +
 +    module.exports = Doo;
 + </​code>​
 +<​code>​
 +
 +    // app.js
 +    var Doo = require('​./​doo.js'​);​
 +    var doo = new Doo();
 +    doo.log();
 + </​code>​
 +
 +==== Export a named prototype ====
 +<​code>​
 +// qux.js
 +    var Qux = function () {};
 +
 +    Qux.prototype.log = function () {
 +      console.log('​baz!'​);​
 +    };
 +
 +    exports.Qux = Qux;
 + 
 +</​code>​
 +<​code> ​
 +    // app.js
 +    var Qux = require('​./​qux.js'​).Qux;​
 +    var qux = new Qux();
 +    qux.log();
 +</​code>​
 +
 +===== Callback convention =====
 +Modules should expose an error-first callback interface.
 +
 +The next example checks, if an Error happened during the execution. You should always check for them.
 +
 +<​code>​
 +function readJSON(filePath,​ callback) {  ​
 +  fs.readFile(filePath,​ function(err,​ data) {
 +    var parsedJson;
 +
 +    // Handle error
 +    if (err) {
 +       ​return callback(err);​
 +    }
 +
 +    // Parse JSON
 +    try {
 +      parsedJson = JSON.parse(data);​
 +    } catch (exception) {
 +      return callback(exception);​
 +    }
 +
 +    // Everything is ok
 +    return callback(null,​ parsedJson);​
 +  });
 +}
 +</​code>​
 +
 +===== Some good practices =====
 +
 +
 +Try to avoid ''​this''​ and ''​new''​. Node involves passing around lots of callbacks, and heavy use of higher-level functions to manage control flow. Using a functional style will save you a lot of trouble. Of course, there are some cases, when prototypes can be more efficient, but if possible, try to avoid them.
 +
 +Start a new project with npm init. The init command helps you create the application'​s package.json file. It sets some defaults, which can be later modified. Start writing your fancy new application should begin with:
 +<​code>​
 +mkdir my-awesome-new-project  ​
 +cd my-awesome-new-project  ​
 +npm init  ​
 +</​code>​
 +
 +Specify a start and test script. In your package.json file you can set scripts under the scripts section. By default, npm init generates two, ''​start''​ and ''​test''​. These can be run with ''​npm start''​ and ''​npm test''​. Also, as a bonus point: you can define custom scripts here and can be invoked with ''​ npm run-script <​SCRIPT_NAME>''​. Note, that NPM will set up $PATH to look in ''​node_modules/​.bin''​ for executables. This helps avoid global installs of NPM modules.
 +
 +Production/​staging deployments should be done with environment variables. The most common way to do this is to set the NODE_ENV variable to either production or staging. Depending on your environment variable, you can load your configuration,​ with modules like ''​nconf''​. Of course, you can use other environment variables in your Node.js applications with ''​process.env'',​ which is an object that contains the user environment.
 +
 +You can use JSCS, which is a code style checker for JS, you can add it:
 +<​code>​
 +npm install jscs --save-dev  ​
 +</​code>​
 +The very next step you have to make is to enable it from the package.json file by adding a custom script:
 +<​code>​
 +scripts: {  ​
 +    "​jscs":​ "jscs index.js"​
 +}
 +</​code>​
 +
 +Prefer JS over JSON for configuration files. Something like this:
 +<​code>​
 +var url = require('​url'​);​
 +var config = module.exports = {};
 +var redisToGoConfig;​
 +
 +config.server = {
 +  host: '​0.0.0.0',​
 +  port: process.env.PORT || 3000
 +};
 +
 +// look, a comment in the config file! 
 +// would be tricky in a JSON ;)
 +config.redis = {
 +  host: '​localhost',​
 +  port: 6379,
 +  options: {
 +
 +  }
 +};
 +
 +if (process.env.REDISTOGO_URL) {
 +  redisToGoConfig = url.parse(process.env.REDISTOGO_URL);​
 +  config.redis.port = redisToGoConfig.port;​
 +  config.redis.host = redisToGoConfig.hostname;​
 +  config.redis.options.auth_pass = redisToGoConfig.auth.split(':'​)[1];​
 +}
 +</​code>​
 +
wiki2/nodejs/patterns.1494500317.txt.gz · Última modificación: 2020/05/09 09:24 (editor externo)