我有几个包含辅助函数的实用程序库,我想加载它们,以便它们可以从控制器中使用,我想知道 在节点中编写实用程序库的最佳实践是什么。
我有点困惑,因为有几种方法可以做到这一点,我不确定什么是最好/更合适/更可靠。这里有两个选项,但我想知道它们是否是最好的(例如我见过使用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;
};
// option2.js
"use strict";
module.exports = {
test1 : function(){ console.log('soy test1')},
test2 : function(){ console.log('soy test2')}
};
// test_controller.js
/* Requiring helpers in different ways */
var option1 = require('./option1.js')();
var option2 = require('./option2.js');
答案 0 :(得分:40)
我认为我的文件有3个部分:
var lib1 = require("lib1");
var lib2 = require("lib2");
您不需要任何其他包装函数。函数中的node.js所有节点模块都是automatically wrapped,这样做没有任何好处,只会增加混乱
如果需要,这几乎应该只有一些支持变量或顶级模块代码。
var MY_CONST = 42;
function helper1() {
//excellent code here
}
function helper2() {
//excellent code here
}
保持第2节纯JS。不要在这个中间的“纯粹”部分使用commonJS习语。不要使用module
,exports
,require
等。这只是我的个人指导,因为JS本身是稳定的,但是包装到模块中仍然有很多变化,而且它更好保持CommonJS位是无关的,并且可能与有趣的代码位分开。 ECMAScript 6模块最有可能在几年内取代CommonJS,因此通过保留第2部分纯ECMAScript 5并制作“CommonJS Sandwich™”(我喜欢称之为)来使自己更容易。
exports.helper1 = helper1;
exports.helper2 = helper2;
exports.foo = foo;
语法,而不是将module.exports
分配给新的对象文字。我发现这避免了对象文字的最后一个属性的尾随逗号问题。require
或exports
语句执行任何其他操作几乎肯定是不必要的,不必要的光滑或魔法。在你进步之前,不要在这里做任何事情。 (即便如此,如果你不是TJ Holowaychuk,你可能只是愚蠢)function degreesToRadians(degrees) {}
module.exports = degreesToRadians;
保持简洁。
如果您的模块是一组辅助函数,则应将包含这些函数的对象导出为属性
var foo = require("foo");
function doubleFoo(value) {
return foo(value) * 2;
}
function tripleFoo(value) {
return foo(value) * 3;
}
exports.doubleFoo = doubleFoo;
exports.tripleFoo = tripleFoo;
如果您的模块是面向对象使用的类设计,请导出构造函数
function GoCart() {
this.wheels = 4;
}
GoCart.prototype.drive = function drive() {
//vroom vroom
}
module.exports = GoCart;
一旦你掌握了上述两种模式(真的!)并且有信心导出一个带有选项的工厂功能,也许会做一些其他动态的东西,那就去吧,但如果有疑问,坚持前两个,更简单的选择
//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;
所以你可以像
一样使用它var doStuff = require("./do-stuff")({howFast: "blazing speed"});
console.log(doStuff.doStuff("jogging"));
//"I am doing jogging at speed blazing speed"
答案 1 :(得分:2)
对于无状态实用程序库, option2.js 是可行的方法,因为每次module.exports
都不需要执行require
中的代码,当您致电require('./option1.js')()
以使用 option1.js 时会发生什么。
另一方面,如果您的模块暴露了创建保持状态的对象的构造函数,那么您将需要 option1.js 。例如,
person.js:
module.exports = function(firstName,lastName){
this.firstName = firstName;
this.lastName = lastName;
};
然后使用它:
var Person = require("./person");
var person1 = new Person("Foo","Bar");
var person2 = new Person("Joe","Shmoe");
option1.js 的另一个优点(如上所示)是它允许您将参数传递到模块中。