Node.js / JavaScript后端开发指引

简介: 这是一篇关于后端 JavaScript 开发的指引,如果你对 JavaScript 的认识仍然停留在前端开发的话,你需要更新自己的知识体系了。 用 NPM 来做项目管理和包维护 用 Grunt 来做代码格式修整、Lint 和其他自动化任务 用 CoffeeScript 方言写更友好的 Ja...

这是一篇关于后端 JavaScript 开发的指引,如果你对 JavaScript 的认识仍然停留在前端开发的话,你需要更新自己的知识体系了。



Web 开发框架从以前流行的 LAMP/LEMP  架构逐渐转移到 Ruby on Rails 和 Python Django 架构之上。但最近有另外几种的架构变得成熟了:比如 Golang, Clojure/leiningen,  Node.js 。这三者之中我更关注 Node.js。原因是它的生态更加完善。所以最近的几个项目都是用它来实现的。Node.js 既适合做后端 API 的粘合,也适合给终端用户提供 API 。

 

用 NPM 来做项目管理和包维护

Node.js 的每个项目都应该有一个 package.json 配置文件。其中包含了这个项目或者库的信息和所依赖的库。一个相对完成的 package.json 文件像这样:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "description": "My app and service",
  "main": "app.js",
  "scripts": {
    "start": "forever start app.js",
    "test": "mocha test"
  },
  "dependencies": {
    "coffee-script": "=1.4.0",
    "express": "=3.0.6",
    "mocha": "=1.7.4",
    "underscore": "=1.4.3",
    "forever": "=0.10.0",
    "async": "",
    "grunt-beautify": ""
  },
  "repository": "",
  "author": "Bruce Dou",
  "license": "BSD"
}

这个文件可以在你的项目目录下执行 npm init 来按指引创建。注意其中的 scripts 部分,这里可以创建很多自定义命令。比如如此配置之后,npm start 会执行 forever start app.js 命令。

用 Grunt 来做代码格式修整、Lint 和其他自动化任务

Grunt 是一个命令行任务自动化工具。它包含了很多有用的插件。可以实现代码美化、自动化部署、自动生成 sprit、自动创建项目模板、自动压缩前端代码、自动编译 coffescript 等等你能想到的任务。假如你找不到自己需要的功能,还可以自己开发 Grunt 插件来实现。它的配置文件是位于项目根目录的 grunt.js 。一般项目都需要的功能是代码美化和 Lint,配置文件象这样:

module.exports = function (grunt) {
  // Project configuration.
  grunt.initConfig({
    beautify: {
      files: ['grunt.js', '*.js', 'lib/*.js']
    },
    lint: {
      files: ['grunt.js', '*.js', 'lib/*.js']
    },
    beautifier: {
      options: {
        indentSize: 2
      },
      tests: {
        options: {
          indentSize: 4
        }
      }
    },
    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        browser: true
      },
      globals: {
        jQuery: true,
        Drupal: true,
        Backbone: true,
        _: true,
        app: true
      }
    }
  });
  grunt.loadNpmTasks('grunt-beautify');
  //grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.registerTask('default', 'beautify');
};

添加了配置文件之后可以在项目目录运行 grunt 命令自动执行任务串。grunt beautify 可以执行子任务。

用 CoffeeScript 方言写更友好的 JavaScript

CoffeeScript 提供了类似于 Ruby 的语法,简化了 JavaScript 的书写,简化了 JavaScript 中实现类和类的继承的实现。你不必再自己繁琐得通过 prototype 和 constructor,call,apply 实现类的继承。 无论用 VIM 还是 Sublime Text 都可以找到对应的实时转换工具,在写 CoffeeScript 的同时就能看到对应的 JavaScript。

必不可少的几个库

underscore

underscore 是写 JavaScript 必不可少的库。提供了一些非常常用的方法,这些方法不仅使用方便,而且提高了代码的可读性。:

用 _.each 代替 for 循环,比如:

var contents = [];
for(var i in msgs) {
  contents.push(msgs[i].content);
}

可以改写为:

var contents = [];
_.each(msgs, function(el) {
  contents.push(el.content);
});

其他常用的方法还有:

_.map 用来对数组元素进行批量转换

_.reduce 用来将数组元素合并为结果

_.pluck 用来取对象数组中的子元素,返回包含对应子元素的新数组

_.filter 用来有选择性的取数组中的某些值,返回包含符合条件的值的新数组

_.mixin 用来增加自定义函数

_.chain 用来实现函数式编程:

_.chain([1,2,3])
 .map(function(v) {return v * 2;})
 .reduce(function(total, v) { total += v}, 0)
 .value();

Async

Async.js 对常用的流程控制模式进行了封装,比如并行处理、Pipeline等等:

async.parallel 并行处理,整体等待最慢的函数返回,常用作多个后端请求的聚合或者并行处理:

...
// construct call functions
var callItems = [];
function make_query_func(json) {
  return function (callback) {
    callBackService(json, callback);
  };
}
_.each(messages, function (el, i) {
  callItems.push(make_query_func({
    vmsg: messages[i].vmsg,
    cmsg: messages[i].cmsg
   }));
});
// execute the call functions parallelly
async.parallel(callItems, function (err, results) {
  main_cb(results);
});

async.waterfall 可以用来将大量嵌套的函数顺序执行,前一个函数的结果作为下一个函数的参数。用它之后你的代码里将不会再出现过深的 callback 嵌套:

// old way
...
var result = function(uid, callback) {
  get_user_ids(uid, function(err, user_ids) {
    get_content(user_ids, function(err, content) {
      content_clean(content, function(err, clean_content) {
        callback(err, clean_content);
      });
    });
  });
}
// new way
...
async.waterfall([get_user_ids, get_content, content_clean]);

开发 C++ addons 增强和扩展 Node.js

这意味着你不必担心某些逻辑的性能,也不必担心和其他框架的继承。因为所有语言或者开发栈都会提供 C/C++ 的接口。

Node.js 配置管理方式

有两种配置方式,config.js 或者 config.json 假如以 config.js 作为配置文件:

// config.js
exports.config = {'a':'a val', 'b': 'b val'};
// app.js
var config = require('./config').config;

如果以 config.json 作为配置文件:

// config.json
{'a': 'a val', 'b': 'b val'}
// app.js
var config = JSON.parse(fs.readFileSync(process.cwd() + '/config.json'));

开发内部 Service 推荐的部件

  • 进程统计信息,比如 uptime, memory usage, heap size, connection number, 处理的请求数量等等。这样便于和监控系统对接
  • RESTful apis,推荐以 RESTful JSON 格式作为内部通信协议,这其实对大部分应用完全足够,而且容易调试。
  • 配置文件。将可能会发生变化的变量放到配置文件里。
  • Service Level Agreement。比如超过 100ms 的请求报错而不是继续等待返回信息。

Forever: Daemon 管理工具

既然 Node.js 是长时间运行的后台进程,缺不了进程管理工具。Forever 就是为了实现对 Node.js 的 daemon 进程进行管理的工具。常用命令:

forever start app.js 启动进程
forever restart app.js 重启进程
forever list 列出后台进程,并且列出 log 文件,可以方便的及时查看 log 文件内容。

Node.js Cluster

Node.js Cluster 是为了利用多核 CPU 的计算能力, 并且子进程可以共用同一个端口:

var cluster = require('cluster');
if (cluster.isMaster) {
    //start up workers for each cpu
    require('os').cpus().forEach(function() {
        cluster.fork();
    });

} else {
    //load up your application as a worker
    require('./app.js');
}

JavaScript 开发常见问题:

JavaScript 是传值还是传引用?

简单说:如果参数为一个对象则为传引用,如果参数为变量或者函数则为传值。

如何用 GDB 调试自己开发的 Node.js C++ addons?

gdb –args nodejs script.js

如何捕获 uncaughtException 并打印详细错误信息?

在进程级别捕获异常:

process.on('uncaughtException', function (e) {
  console.trace('Error: '.red + e);
  console.trace(e.stack);
  //process.exit();
});

如何优雅结束进程?

Node.js 中对接收的 POSIX 信号做自定义操作很方便,进行进程结束前的清理工作:

process.on('SIGINT', function () {
  // wait connections to close
  process.exit();
  console.log("gracefully shutting down from  SIGINT (Crtl-C)".yellow);
});

如何使用 Array 和 Object

对于列表类的信息,比如用户列表推荐使用 Object 而不是 Array:

var a = [];
a[1000] = 1;
//a is an Array which length is 1001

如何聚合多个后端服务并提供 SLA ?

用 Node.js 可以非常简单的实现对返回所用时间进行控制。比如在之前例子代码 async.parallel 的请求中设置超时定时器。对多个处理进程并发请求取其中时间最短的结果,这样可以保证返回时间都保持很短。

什么时候使用 process.nextTick() ?

  1. 重量使用 CPU 的函数中释放 CPU 给其他任务
  2. 将执行放到下一个 tick ,等待初始化

更多相关参考:

http://nodejs.org/
https://npmjs.org/
http://coffeescript.org/
http://underscorejs.org/
http://nodejs.org/api/addons.html
http://expressjs.com/
https://github.com/caolan/async
http://howtonode.org/understanding-process-next-tick
http://book.mixu.net/ch7.html
http://gruntjs.com/

目录
相关文章
|
10天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
18 0
|
18天前
|
机器学习/深度学习 人工智能 JavaScript
js和JavaScript
js和JavaScript
20 4
|
24天前
|
负载均衡 测试技术 持续交付
高效后端开发实践:构建可扩展的微服务架构
在当今快速发展的互联网时代,后端开发扮演着至关重要的角色。本文将重点探讨如何构建可扩展的微服务架构,以及在后端开发中提高效率的一些实践方法。通过合理的架构设计和技术选型,我们可以更好地应对日益复杂的业务需求,实现高效可靠的后端系统。
|
24天前
|
开发框架 JavaScript 安全
js开发:请解释什么是Express框架,以及它在项目中的作用。
Express是Node.js的Web开发框架,简化路由管理,支持HTTP请求处理。它采用中间件系统增强功能,如日志和错误处理,集成多种模板引擎(EJS、Jade、Pug)用于HTML渲染,并提供安全中间件提升应用安全性。其可扩展性允许选用合适插件扩展功能,加速开发进程。
|
19天前
|
监控 Java 开发者
构建高效微服务架构:后端开发的新范式
在数字化转型的浪潮中,微服务架构以其灵活性、可扩展性和容错性成为企业技术战略的关键组成部分。本文深入探讨了微服务的核心概念,包括其设计原则、技术栈选择以及与容器化和编排技术的融合。通过实际案例分析,展示了如何利用微服务架构提升系统性能,实现快速迭代部署,并通过服务的解耦来提高整体系统的可靠性。
|
24天前
|
机器学习/深度学习 人工智能 搜索推荐
未来人工智能在后端开发中的应用前景
随着人工智能技术的不断发展,后端开发领域也迎来了新的机遇与挑战。本文探讨了人工智能在后端开发中的应用前景,分析了其对传统开发模式的影响和未来发展趋势。
|
3天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
4天前
|
监控 负载均衡 API
构建高性能微服务架构:后端开发的最佳实践
【4月更文挑战第14天】 在当今快速发展的软件开发领域,微服务架构已成为构建可扩展、灵活且容错的系统的首选方法。本文深入探讨了后端开发人员在设计和维护高性能微服务时需要遵循的一系列最佳实践。我们将从服务划分原则、容器化部署、API网关使用、负载均衡、服务监控与故障恢复等方面展开讨论,并结合实际案例分析如何优化微服务性能及可靠性。通过本文的阅读,读者将获得实施高效微服务架构的实用知识与策略。
|
6天前
|
小程序 前端开发 JavaScript
小程序全栈开发:前端与后端的完美结合
【4月更文挑战第12天】本文介绍了小程序全栈开发,涵盖前端和后端的关键点。前端使用WXML和WXSS进行页面结构和样式设计,JavaScript处理逻辑及组件使用;后端采用Node.js等语言处理业务逻辑、数据库设计和API接口开发。前端与后端通过数据交互实现结合,采用前后端分离模式,支持跨平台运行。调试测试后,提交微信审核并上线运营。掌握前端后端结合是小程序成功的关键。
|
17天前
|
JavaScript 前端开发
JavaScript生成的随机数随机字符串JS生成的随机数随机字符串
JavaScript生成的随机数随机字符串JS生成的随机数随机字符串
14 1