node相关概念

node

首先是node,对node的完整理解见这篇帖子:node是什么。这里简单来说,node是一个server端的运行平台,目前大部分在server端运行的javascript程序,都是在node上跑的,可以说node是基础

运行的基本方法是node xxx.js。当然程序要遵循node的API来写,就像java程序要根据JAVA API来写一样

npm

node程序是模块化的,同时也有目录结构的规范,node实现的是CommonJS定义的模块化规范和包结构规范,详见:

node.js的模块化分析

CommonJS Package Spec 1.0

按照这个格式打包的一组文件,就称为一个node module,可以加载到node里运行

同时,模块多了以后,就需要有工具来管理版本和依赖关系等,这是任何平台都需要考虑解决的问题。在node平台,npm就是这个官方的模块管理工具。npm自身也是一个node的模块,最初和node是分离的,但是现在已经是node的内置组件,随node一起发布的了。可以说,npm是node平台上包管理的事实标准。类似于java平台上jar + maven

根据CommonJS的package规范,可以在bin目录下放二进制文件,其实一般就是shell脚本



这里的执行脚本npm,其实就是一个普通的shell,其中调用的也是node xxx.js方法:
!/bin/sh

basedir=`dirname "$0"`

case `uname` in
    *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node.exe" ]; then
  "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "[email protected]"
else
  node "$basedir/node_modules/npm/bin/npm-cli.js" "[email protected]"
fi

grunt和spm


上面说的npm是包管理工具,日常开发中还需要用到构建工具,这个非常好理解,比如要单元测试、文件压缩、拷贝、占位符替换等等,在java平台还有编译等等,这些工作当然也可以依赖手工完成,但是更好的做法还是用工具实现自动化
注意grunt、spm和npm的关系:本质上他们是平等的,都是node module,都运行在node之上。但是npm稍微特殊一点的地方在于,虽然它也是module,但是同时它也管理着其他的module

grunt是一个用javascript写的,基于node的 构建框架,执行各种官方自带的task,也可以执行第三方扩展的task。grunt非常像ant,可以说grunt就是node平台的ant

spm比较特殊,它是Static Package Manager的缩写,官方定位它 是一个包管理工具,而不是一个构建工具。不过它管理的是前端(浏览器)用到的包,而不是像npm那样管理server端的包。同时spm也带有构建的功能(专门针对seajs),而且是seajs官方推荐的配套构建工具。在大部分人心里,都把spm定位成一个构建工具,原本的包管理功能反倒很少被提到了

相关的帖子:

最早的spm1.0带有构建功能,专门为seajs服务。但是为了强调自身的清晰定位,以及把构建的工作分离出来让更专业的grunt来做,spm2.0进行了大规模重构,把spm-build独立出来,其实成了一个grunt的task插件

seajs


seajs和node没有什么关系

seajs是跑在浏览器里的一个javascript模块加载器(module loader),用来实现浏览器js的模块化功能,实现的也是CommonJS规范,所以会发现语法和node非常像。可以说,node实现了server端的模块化,seajs实现了client端的模块化。虽然做的事情类似,但是seajs和node没有什么关系,seajs不需要运行在node环境下,server端代码也不需要seajs

但是seajs对目录结构也是有要求的,需要有构建工具来自动化打包。不管是用grunt还是spm,构建工具都是需要跑在node上的,但是seajs本身却不需要,这点需要搞清楚,不可混淆