构建node.js中所需库的最佳实践

End*_*ion 21 design-patterns require node.js

我有几个包含辅助函数的实用程序库,我想加载它们,以便可以从控制器中使用它们,我想知道在节点中编写实用程序库的最佳实践是什么.

我有点困惑,因为有几种方法可以做到这一点,我不确定什么是最好/更合适/更可靠.这里有两个选项,但我想知道它们是否是最好的(例如我见过使用的片段module.exports = exports = function(){}等)

//option1.js


"use strict";

module.exports =  function(){

     exports.test1 =  function(){ console.log('hi I'm test1')};
     exports.test2 =  function(){ console.log('hi I'm test2')};
     return exports;
};
Run Code Online (Sandbox Code Playgroud)

//option2.js

"use strict";

module.exports =  {

     test1 : function(){ console.log('soy test1')},
     test2 :  function(){ console.log('soy test2')}

};
Run Code Online (Sandbox Code Playgroud)

//test_controller.js

/* Requiring helpers in different ways */
var option1 = require('./option1.js')();
var option2 = require('./option2.js');
Run Code Online (Sandbox Code Playgroud)

Pet*_*ons 40

我想到我的文件有3个部分:

第1节:CommonJS依赖关系

var lib1 = require("lib1");
var lib2 = require("lib2");
Run Code Online (Sandbox Code Playgroud)

您不需要任何其他包装函数.所有节点模块都由一个函数中的node.js 自动包装,这样做没有任何好处,只会增加混乱

第2节:纯JavaScript代码

如果需要,这应该几乎完全具有支持变量或顶级模块代码的功能.

var MY_CONST = 42;

function helper1() {
    //excellent code here
}

function helper2() {
    //excellent code here
}
Run Code Online (Sandbox Code Playgroud)

保持第2节纯JS.不要在这个中间的"纯粹"部分使用commonJS习语.不要使用module,exports,require等,这只是我个人的方针为JS本身是稳定的,但包装中的模块仍是下了很大的变化,它是更好地保持CommonJS的位是多余的,可能会改变从独立有趣的代码.ECMAScript 6模块最有可能在几年内取代CommonJS,因此通过保留第2部分纯ECMAScript 5并制作"CommonJS Sandwich™"(因为我喜欢称之为)来使自己更容易.

第3节:CommonJS出口

exports.helper1 = helper1;
exports.helper2 = helper2;
Run Code Online (Sandbox Code Playgroud)
  • 将所有导出放在最后还可以让您快速了解您的公共API是什么,并防止由于粗心的复制/粘贴而意外导出属性.
  • 我更喜欢上面的exports.foo = foo;语法而不是分配module.exports给新的对象文字.我发现这避免了对象文字的最后一个属性的尾随逗号问题.
  • 用你的requireexports陈述做任何事情几乎肯定是不必要的,不必要的光滑或魔术.在你进步之前,不要在这里做任何事情.(即便如此,如果你不是TJ Holowaychuk,你可能只是愚蠢)

我应该出口什么

单一功能(@substack风格)

function degreesToRadians(degrees) {}

module.exports = degreesToRadians;
Run Code Online (Sandbox Code Playgroud)

保持小而简单.

功能的对象

如果您的模块是一组辅助函数,则应将包含这些函数的对象导出为属性

var foo = require("foo");

function doubleFoo(value) {
  return foo(value) * 2;
}

function tripleFoo(value) {
  return foo(value) * 3;
}

exports.doubleFoo = doubleFoo;
exports.tripleFoo = tripleFoo;
Run Code Online (Sandbox Code Playgroud)

构造函数

如果您的模块是面向对象使用的类设计,请导出构造函数

function GoCart() {
  this.wheels = 4;
}

GoCart.prototype.drive = function drive() {
  //vroom vroom
}

module.exports = GoCart;
Run Code Online (Sandbox Code Playgroud)

工厂/配置关闭功能

一旦你掌握了上述两种模式(真的!)并且有信心导出一个工厂函数,它可以选择并可能做一些其他动态的东西,那就去吧,但如果有疑问,坚持使用前两个更简单的选择.

//do-stuff.js
function doStuff(howFast, what) {
   return "I am doing " + what + " at speed " + howFast;
}

function setup(options) {
  //The object returned by this will have closure access to options
  //for its entire lifetime
  return {doStuff: doStuff.bind(null, options.howFast)};
}

module.exports = setup;
Run Code Online (Sandbox Code Playgroud)

所以你可以使用它

var doStuff = require("./do-stuff")({howFast: "blazing speed"});
console.log(doStuff.doStuff("jogging"));
//"I am doing jogging at speed blazing speed"
Run Code Online (Sandbox Code Playgroud)