Node.Toptal Developers的最佳实践和技巧

Share

该资源包含Node的集合.js best practices and Node.由Toptal网络成员提供的小贴士.

该资源包含Node的集合.js tips and best practices provided by our Toptal Network members. As such, this page will be updated on a regular basis to include additional information and cover emerging Node.js techniques. 这是一个社区驱动的项目, 所以我们也鼓励你们做出贡献, 我们期待着你们的反馈.

Check out the Toptal resource pages 以获取有关Node的更多信息.js. There is a Node.js job description, common Node.js mistakes, and Node.js interview questions.

如何正确使用承诺

Promises are wonderful - they enable developers to avoid cascading callbacks and make the code way clearer.

However, 当你面对承诺时, you should avoid as much as possible creating new promises for each new request and managing them yourself.

让我们检查下面的代码:

var makeRequest = function(options){
    var deferred = Q.defer();
    request.调用(options, function(err, result){
        if(err){
            return deferred.reject(err);
        }
        deferred.resolve(result);
    });
    return deferred.promise;
};

var getRequest =函数(url){
    var deferred = Q.defer();
    var options = {
        method: "GET",
        url: url
    };
    makeRequest(options)
        .then(function(result){
            deferred.resolve(result);
        })
        .catch(function(error){
            deferred.reject(error);
        })
    ;
    return deferred.promise;
};

var getMyAccount = function(accountId){
    var deferred = Q.defer();
    getRequest(' /账户/ ' + accountId)
        .then(function(result){
            deferred.resolve(result);
        })
        .catch(function(error){
            deferred.reject(error);
        })
    ;
    return deferred.promise;
};

这里的问题是在每个函数中都创建了一个新的承诺, 但它是根据另一个次级承诺决议来解决的. This development practice makes unnecessary code, more difficult to read and less efficient. We should refactor it into the following, more promise-friendly, version:

var makeRequest = function(options){
    var deferred = Q.defer();
    request.调用(options, function(err, result){
        if(err){
            return deferred.reject(err);
        }
        deferred.resolve(result);
    });
    return deferred.promise;
};

var getRequest =函数(url){
    var options = {
        method: "GET",
        url: url
    };
    返回makeRequest(选项);
};

var getMyAccount = function(accountId){
    返回getRequest(' /账户/ ' + accountId);
};

第二个版本避免在每个级别上创建新的承诺, thus reducing the overhead, 产生错误或处理错误的可能性, and is much more readable. And it works the same.

Contributors

Pierre Killy

Freelance Node.js Developer

Sweden

从八岁开始写代码, Pierre's love of technology has led him to earn a master's degree in computer science. From pure engineering to building processes for CI and CD on heavy-loaded infrastructure at Viadeo (100+ production servers), 他以首席技术官的身份联合创立了一家初创公司. Pierre is a dedicated, enthusiastic leader, a creative solution-maker and a web engineering expert with more than a decade of experience.

Show More

从Toptal获取最新的开发人员更新.

订阅意味着同意我们的 privacy policy

使用覆盖工具跟踪可能死的代码

What is dead code? 简单地说,它是永远不会执行的代码.

死亡或未使用的代码往好里说是一种痛苦,往坏里说是问题. 它需要努力维护, including unit tests, 使您的代码库更大,更难以处理, 尤其是对于你雇佣的新工程师. Even worse, you can sometimes have dead code that is highly complex (or that introduces significant complexity to the overall system) and, 如果你没有意识到它已经死了, you may end up “standing on your head” to get other code to work properly with it. And all this for nothing.

Fortunately, there are dead code identification tools that exist out there that can help. The problem, though, is that they statically analyze your code and try to understand which code is used and which is not.

在我们的示例中,我们将使用 Istanbul package. 这里的想法是根据实际的生产使用来运行它. 实现这一点的方法相当简单:

  1. 从池中取出一个生产服务器.
  2. Shut down your Node.js application.
  3. Run it again using Istanbul; instead of node app.js run 伊斯坦布尔——handle-sigint掩护应用程序.js.
  4. Wait for your application to start and put the server back in the pool.
  5. 取决于您的交通和架构, 你可以这样放几分钟, hours or days. The --handle-sigint is meant to be used with long-running processes, which is exactly the case with your web server.
  6. 再次将服务器从生产池中取出.
  7. Stop the Istanbul process. Once again the --handle-sigint 选项很有用:您只需要使用 SIGINT signal kill -s SIGINT[伊斯坦布尔PID].
  8. 的代码覆盖率报告 coverage directory and exit.
  9. Start your Node.js application in a normal way again and put the server back in the production pool.
  10. Explore the HTML coverage report to discover what code is unused.

您可能会担心响应时间开销. From my experience, the server running Istanbul had a response time around 5% higher than without it. In any case, the code coverage server should always be monitored closely.

Contributors

Pierre Killy

Freelance Node.js Developer

Sweden

从八岁开始写代码, Pierre's love of technology has led him to earn a master's degree in computer science. From pure engineering to building processes for CI and CD on heavy-loaded infrastructure at Viadeo (100+ production servers), 他以首席技术官的身份联合创立了一家初创公司. Pierre is a dedicated, enthusiastic leader, a creative solution-maker and a web engineering expert with more than a decade of experience.

Show More

如何正确使用登录Node.js

When working on a new project, it is common to log debug messages using the console.log. It is native in JavaScript and prints objects in a JSON-like style.

然而,有一些问题使用 console.log to debug your application:

  • 一旦你建立了你的应用程序, you must remove them all, 除非您想在生产环境中污染日志文件.
  • 您没有过滤它们的选项.

Enter debug, a small Node.js debugging utility modeled after the Node core’s debugging technique. With debug, you can keep your debug logs in the code and use them only when you need them.

Here is how it works:

  1. 导入调试模块并用变量引用它: var debug = require('debug')('myWonderfulApp');. By doing this, you immediately have an instance set up for your application (‘myWonderfulApp’).
  2. 使用引用来记录消息: 调试(“这些是变量内容”,someVar, someOtherVar);.
  3. Turn on your own application’s debug messages while running your Node.js application: DEBUG=myWonderfullApp节点应用程序.js. As you can see, the DEBUG environment variable is set to the exact name we’ve used to initialize the debug module.

An additional very useful feature is that you can declare the debug variable using a namespace like this: var debug = require("debug")("myWonderfulApp:startup");.

This enables you to distinguish each type or level of debugging in your project very precisely. Then, 在运行应用程序时, you can decide to display specific subsets of your debug messages (e.g., DEBUG=myWonderfullApp:启动节点应用程序.js) or all debug messages (e.g., DEBUG=myWonderfullApp:*节点应用程序.js).

Finally, 如果你使用像ExpressJS这样的框架, 你可以像这样启动你的应用程序来激活许多日志: DEBUG=* node app.js. This will display all debug messages from all namespaces, including yours.

Contributors

Pierre Killy

Freelance Node.js Developer

Sweden

从八岁开始写代码, Pierre's love of technology has led him to earn a master's degree in computer science. From pure engineering to building processes for CI and CD on heavy-loaded infrastructure at Viadeo (100+ production servers), 他以首席技术官的身份联合创立了一家初创公司. Pierre is a dedicated, enthusiastic leader, a creative solution-maker and a web engineering expert with more than a decade of experience.

Show More

Use a Code Change Watcher to Automatically Restart Your Node App

While developing software, you want your newly written code to be applied immediately to test it. Having to stop and restart your Node process by hand is a pain and a waste of time.

幸运的是,有一些工具可以解决这个问题. 让我们来看看这类工具中最流行的三种. 这三个都提供了非常相似的选项和功能, so your choice will probably be more a matter of personal preference.

nodemon

nodemon is a tool to restart your Node server on file change automatically. You can configure it through the command line option of a config file. It supports listening for (or ignoring) specific directories and file extensions, 延迟进程重启, 和不同的处理干净的进程退出和应用程序崩溃.

You run it simply be replacing “node” with “nodemon” on the command line, 这使得它使用起来非常简单.

Installation: npm install -g nodemon

forever

forever 提供许多选项来微调其行为, 比如设置工作目录, 将日志追加到文件而不是标准输出, 或将进程ID (PID)保存为 .pid file.

It has a different usage than nodemon that looks more like Unix services management, for example forever start app.js. It also has more extended options like coloring output or exit signal customization.

Installation: npm install -g forever

node-supervisor

node-supervisor (also known simply as supervisor) has the same features as nodemon and forever and several options to fine tune its behavior like not restarting on an error, for example. Very simple and efficient.

Installation: npm install -g supervisor

Contributors

Pierre Killy

Freelance Node.js Developer

Sweden

从八岁开始写代码, Pierre's love of technology has led him to earn a master's degree in computer science. From pure engineering to building processes for CI and CD on heavy-loaded infrastructure at Viadeo (100+ production servers), 他以首席技术官的身份联合创立了一家初创公司. Pierre is a dedicated, enthusiastic leader, a creative solution-maker and a web engineering expert with more than a decade of experience.

Show More

利用内置分析器

性能对任何系统都非常重要. Profiling your code will allow you to understand where time is spent in your code, so you can focus on the right pieces of code that can most benefit from performance optimization.

V8’s internal profiler comes built-in with Node.js. 它很容易使用,而且效率很高.

让我们看一下如何使用这个分析器.

在启用分析的情况下运行应用程序

It’s very easy to start using profiler; simply add the --prof 选项到你的节点命令:

node --prof app.js

Now let your task run, do all the HTTP calls or whatever needs to be done to execute your code. When finished, the profiler will create a “tick file”; a big text file in your current working directory named isolate-0x???????-v8.log.

接下来,我们需要处理这个文件.

Processing your tick file

要处理tick文件,只需运行以下命令:

节点——profi -process isolation -0x???????-v8.log

该命令将输出应用程序的分析结果, which consists of several parts (discussed further in the next section).

As this result can be a bit long, it is advised to pipe it into a text file.

读取tick文件处理结果

处理后的结果将包含几个部分,包括:

[Shared libraries]
[JavaScript]
[C++]
[Summary]
[C++ entry points]
[由下而上(重)轮廓]

Jump directly to the [Summary] part. It is short and gives an immediate overview of where to dig further. For example:

[Summary]:
   勾起非库的总名称
  15221   58.6%   59.7%  JavaScript
   7630   29.4%   29.9%  C++
    966    3.7%    3.8%  GC
    496    1.9%共享库
   2638   10.2%          Unaccounted

This makes it obvious that most of the time is being spent in the JavaScript functions. c++函数也要花很多时间. 值得注意的是:要小心创建massive Date objects, or overuse of the Object.keys() 函数,这两者都会对c++的性能产生不利影响.

以以上总结信息为指导, you can then jump to the sections where most of the time is being spent. You will find a list of functions sorted by the number of ticks spent on each, in descending order.

现在你知道该把精力集中在哪里了.

Contributors

Pierre Killy

Freelance Node.js Developer

Sweden

从八岁开始写代码, Pierre's love of technology has led him to earn a master's degree in computer science. From pure engineering to building processes for CI and CD on heavy-loaded infrastructure at Viadeo (100+ production servers), 他以首席技术官的身份联合创立了一家初创公司. Pierre is a dedicated, enthusiastic leader, a creative solution-maker and a web engineering expert with more than a decade of experience.

Show More

Submit a tip

Submitted questions and answers are subject to review and editing, 并可能会或可能不会选择张贴, 由Toptal全权决定, LLC.

* All fields are required

Toptal Connects the Top 3% 世界各地的自由职业人才.

Join the Toptal community.