node入门(二)核心API(二)
2015-11-24 16:20:23

145
NPM 使用介绍
npm有两层含义。一层含义是Node.js的开放式模块登记和管理系统,网址为http://npmjs.org。另一层含义是Node.js默认的模块管理器,是一个命令行下的软件,用来安装和管理node模块。 NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题,常见的使用场景有以下几种:
- 允许用户从NPM服务器下载别人编写的第三方包到本地使用。
- 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
- 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了。 同样可以通过输入 "npm -v" 来测试是否成功安装。命令如下,出现版本提示表示安装成功:
D:\vip_data\mygit\zhufeng_node\2.node>npm -v 2.14.7
如果你安装的是旧版本的 npm,可以很容易得通过 npm 命令来升级,命令如下
npm install npm@latest -g
node安装完成后,可以用下面的命令,查看一下npm的帮助文件。
# npm命令列表 $ npm help # 各个命令的简单用法 $ npm -l
下面的命令分别查看npm的版本和配置。
$ npm -v $ npm config list -l
npm set
npm set用来设置环境变量。
$ npm set init-author-name 'Your name' $ npm set init-author-email 'Your email' $ npm set init-author-url 'http://www.zhufengpeixun.cn' $ npm set init-license 'MIT'
上面命令等于为npm init设置了默认值,以后执行npm init的时候,package.json的作者姓名、邮件、主页、许可证字段就会自动写入预设的值。 这些信息会存放在用户主目录的~/.npmrc文件,使得用户不用每个项目都输入。如果某个项目有不同的设置,可以针对该项目运行npm config。
$ npm set save-exact true
上面命令设置加入模块时,package.json将记录模块的确切版本,而不是一个可选的版本范围。
npm info
npm info命令可以查看每个模块的具体信息。比如,查看underscore模块的信息。
$ npm info underscore { name: 'underscore', description: 'JavaScript\'s functional programming helper library.', 'dist-tags': { latest: '1.5.2', stable: '1.5.2' }, repository: { type: 'git', url: 'git://github.com/jashkenas/underscore.git' }, homepage: 'http://underscorejs.org', main: 'underscore.js', version: '1.5.2', devDependencies: { phantomjs: '1.9.0-1' }, licenses: { type: 'MIT', url: 'https://raw.github.com/jashkenas/underscore/master/LICENSE' }, files: [ 'underscore.js', 'underscore-min.js', 'LICENSE' ], readmeFilename: 'README.md'}
上面命令返回一个JavaScript对象,包含了underscore模块的详细信息。这个对象的每个成员,都可以直接从info命令查询。
$ npm info underscore description JavaScript's functional programming helper library. $ npm info underscore homepage http://underscorejs.org $ npm info underscore version 1.5.2
npm search
npm search命令用于搜索npm仓库,它后面可以跟字符串,也可以跟正则表达式。
$ npm search <搜索词>
下面是一个例子。
$ npm search node-gyp // NAME DESCRIPTION // autogypi Autogypi handles dependencies for node-gyp projects. // grunt-node-gyp Run node-gyp commands from Grunt. // gyp-io Temporary solution to let node-gyp run `rebuild` under… // ...
npm list
npm list命令以树型结构列出当前项目安装的所有模块,以及它们依赖的模块。
$ npm list
加上global参数,会列出全局安装的模块。
$ npm list -global
npm list命令也可以列出单个模块。
$ npm list underscore
npm install
Node模块采用npm install命令安装。每个模块可以“全局安装”,也可以“本地安装”。两者的差异是模块的安装位置,以及调用方法。
“全局安装”指的是将一个模块直接下载到Node的安装目录中,各个项目都可以调用。“本地安装”指的是将一个模块下载到当前目录的node_modules子目录,然后只有在当前目录和它的子目录之中,才能调用这个模块。一般来说,全局安装只适用于工具模块,比如npm和grunt。
默认情况下,npm install命令是“本地安装”某个模块。
$ npm install <package name>
npm也支持直接输入github地址。
$ npm install git://github.com/package/path.git $ npm install git://github.com/package/path.git#0.1.0
运行上面命令后,模块文件将下载到当前目录的node_modules子目录。
使用global参数,可以“全局安装”某个模块。global参数可以被简化成g参数。
$ sudo npm install -global [package name] $ sudo npm install -g [package name]
install命令总是安装模块的最新版本,如果要安装模块的特定版本,可以在模块名后面加上@和版本号。
$ npm install sax@latest $ npm install sax@0.1.1 $ npm install sax@">=0.1.0 <0.2.0"
如果使用--save-exact参数,会在package.json文件指定安装模块的确切版本。
$ npm install readable-stream --save --save-exact
install命令可以使用不同参数,指定所安装的模块属于哪一种性质的依赖关系,即出现在packages.json文件的哪一项中。
--save:模块名将被添加到dependencies,可以简化为参数-S。 --save-dev: 模块名将被添加到devDependencies,可以简化为参数-D。
$ npm install sax --save $ npm install node-tap --save-dev # 或者 $ npm install sax -S $ npm install node-tap -D
如果要安装beta版本的模块,需要使用下面的命令。
# 安装最新的beta版 $ npm install <module-name>@beta (latest beta) # 安装指定的beta版 $ npm install <module-name>@1.3.1-beta.3
npm install默认会安装dependencies字段和devDependencies字段中的所有模块,如果使用production参数,可以只安装dependencies字段的模块。
$ npm install --production # 或者 $ NODE_ENV=production npm install
一旦安装了某个模块,就可以在代码中用require命令调用这个模块。
var backbone = require('backbone') console.log(backbone.VERSION)
语义版本(SemVer)
npm采用”语义版本“管理软件包。所谓语义版本,就是指版本号为a.b.c的形式,其中a是大版本号,b是小版本号,c是补丁号。 一个软件发布的时候,默认就是 1.0.0 版。如果以后发布补丁,就增加最后一位数字,比如1.0.1;如果增加新功能,且不影响原有的功能,就增加中间的数字(即小版本号),比如1.1.0;如果引入的变化,破坏了向后兼容性,就增加第一位数字(即大版本号),比如2.0.0。 npm允许使用特殊符号,指定所要使用的版本范围,假定当前版本是1.0.4。
只接受补丁包:1.0 或者 1.0.x 或者 ~1.0.4 只接受小版本和补丁包:1 或者 1.x 或者 ^1.0.4 接受所有更新:* or x
对于~和^,要注意区分。前者表示接受当前小版本(如果省略小版本号,则是当前大版本)的最新补丁包,后者表示接受当前大版本的最新小版本和最新补丁包。
~2.2.1 // 接受2.2.1,不接受2.3.0 ^2.2.1 // 接受2.2.1和2.3.0 ~2.2 // 接受2.2.0和2.2.1,不接受2.3.0 ^2.2 // 接受2.2.0、2.2.1和2.3.0 ~2 // 接受2.0.0、2.1.0、2.2.0、2.2.1和2.3.0 ^2 // 接受2.0.0、2.1.0、2.2.0、2.2.1和2.3.0
还可以使用数学运算符(比如>, <, =, >= or <=等),指定版本范围。
>2.1 1.0.0 - 1.2.0 >1.0.0-alpha >=1.0.0-rc.0 <1.0.1 ^2 <2.2 || > 2.3
注意,如果使用连字号,它的两端必须有空格。如果不带空格,会被npm理解成预发布的tag,比如1.0.0-rc.1。
npm update,npm uninstall
npm update 命令可以升级本地安装的模块。
$ npm update [package name]
加上global参数,可以升级全局安装的模块。
$ npm update -global [package name]
npm uninstall 命令,删除本地安装的模块。
$ npm uninstall [package name]
加上global参数,可以删除全局安装的模块。
$ sudo npm uninstall [package name] -global
npm shrinkwrap收缩模块
对于一个项目来说,通常不会写死依赖的npm模块的版本。比如,开发时使用某个模块的版本是1.0,那么等到用户安装时,如果该模块升级到1.1,往往就会安装1.1。 但是,对于开发者来说,有时最好锁定所有依赖的版本,防止模块升级带来意想不到的问题。但是,由于模块自己还依赖别的模块,这一点往往很难做到。举例来说,项目依赖A模块,A模块依赖B模块。即使写死A模块的版本,但是B模块升级依然可能导致不兼容。 npm shrinkwrap命令就是用来彻底锁定所有模块的版本。
$ npm shrinkwrap
运行上面这个命令以后,会在项目目录下生成一个npm-shrinkwrap.json文件,里面包含当前项目(读取的是node_modules文件夹里的文件)用到的所有依赖(包括依赖的依赖,以此类推),以及它们的准确版本,也就是当前正在使用的版本。 只要存在npm-shrinkwrap.json文件,下一次用户使用npm install命令安装依赖的时候,就会安装所有版本完全相同的模块。 如果执行npm shrinkwrap的时候,加上参数dev,还可以记录devDependencies字段中模块的准确版本。
$ npm shrinkwrap --dev
npm prune 修剪模块
npm prune命令与npm shrinkwrap配套使用。使用npm shrinkwrap的时候,有时可能存在某个已经安装的模块不在dependencies字段内的情况,这时npm shrinkwrap就会报错。
npm prune命令可以移除所有不在dependencies字段内的模块。如果指定模块名,则移除指定的模块。
$ npm prune $ npm prune <package name>
npm run
npm不仅可以用于模块管理,还可以用于执行脚本。package.json文件有一个scripts字段,可以用于指定脚本命令,供npm直接调用。
{ "name": "myproject", "devDependencies": { "jshint": "latest", "browserify": "latest", "mocha": "latest" }, "scripts": { "lint": "jshint **.js", "test": "mocha test/" } }
上面代码中,scripts字段指定了两项命令lint和test。命令行输入npm run lint,就会执行jshint **.js,输入npm run test,就会执行mocha test/。
npm run命令会自动在环境变量$PATH添加node_modules/.bin目录,所以scripts字段里面调用命令时不用加上路径,这就避免了全局安装NPM模块。
npm内置了两个命令简写,npm test等同于执行npm run test,npm start等同于执行npm run start。
npm run会创建一个shell,执行指定的命令,并将node_modules/.bin加入PATH变量,这意味着本地模块可以直接运行。也就是说,npm run lint直接运行jshint **.js即可,而不用./node_modules/.bin/jshint **.js。
如果直接运行npm run不给出任何参数,就会列出scripts属性下所有命令。
$ npm run Available scripts in the user-service package: lint jshint **.js test mocha test/
下面是另一个package.json文件的例子。
"scripts": { "watch": "watchify client/main.js -o public/app.js -v", "build": "browserify client/main.js -o public/app.js", "start": "npm run watch & nodemon server.js", "test": "node test/all.js" },
上面代码在scripts项,定义了四个别名,每个别名都有对应的脚本命令。
$ npm run watch $ npm run build $ npm run start $ npm run test
其中,start和test属于特殊命令,可以省略run。
$ npm start $ npm test
如果希望一个操作的输出,是另一个操作的输入,可以借用Linux系统的管道命令,将两个操作连在一起。
"build-js": "browserify browser/main.js | uglifyjs -mc > static/bundle.js"
但是,更方便的写法是引用其他npm run命令。
"build": "npm run build-js && npm run build-css"
上面的写法是先运行npm run build-js,然后再运行npm run build-css,两个命令中间用&&连接。如果希望两个命令同时平行执行,它们中间可以用&连接。
下面是一个流操作的例子。
"devDependencies": { "autoprefixer": "latest", "cssmin": "latest" }, "scripts": { "build:css": "autoprefixer -b 'last 2 versions' < assets/styles/main.css | cssmin > dist/main.css" }
写在scripts属性中的命令,也可以在node_modules/.bin目录中直接写成bash脚本。下面是一个bash脚本。
#!/bin/bash cd site/main browserify browser/main.js | uglifyjs -mc > static/bundle.js
假定上面的脚本文件名为build.sh,并且权限为可执行,就可以在scripts属性中引用该文件。
"build-js": "bin/build.sh"
参数
npm run命令还可以添加参数。
"scripts": { "test": "mocha test/" }
全局安装与本地安装
全局安装
npm 的包安装分为本地安装(local)、全局安装(global)两种,从敲的命令行来看,差别只是有没有-g而已,比如
本地安装
- 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。
- 可以通过 require('express') 来引入本地安装的包。
npm install express # 本地安装
全局安装
mac全局路径 /usr/local 下 windows全局路径 C:\Users\Administrator\AppData\Roaming\npm 这个路径可以在 C:\Program Files\nodejs\node_modules\npm\npmrc 中配置 prefix=${APPDATA}\npm
- 将安装包放在全局路径下。
- 可以直接在命令行里使用。
接下来我们使用全局方式安装 express-generator
$ npm install express-generator -g # 全局安装
安装过程输出如下内容,第一行输出了模块的版本号及安装位置。
你可以使用以下命令来查看所有全局安装的模块
$ npm ls -g
使用 package.json
package.json 位于模块的目录下,用于定义包的属性。接下来让我们来看下 express 包的 package.json 文件,位于 node_modules/express/package.json 内容: Package.json 属性说明
- name - 包名。
- version - 包的版本号。
- description - 包的描述。
- homepage - 包的官网 url 。
- author - 包的作者姓名。
- contributors - 包的其他贡献者姓名。
- dependencies - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。
- repository - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。
- main - main 字段是一个模块ID,它是一个指向你程序的主要项目。就是说,如果你包的名字叫 express,然后用户安装它,然后require("express")。
- keywords - 关键字
卸载模块
我们可以使用以下命令来卸载 Node.js 模块。
$ npm uninstall express
卸载后,你可以到 /node_modules/ 目录下查看包是否还存在,或者使用以下命令查看:
$ npm ls
更新模块
我们可以使用以下命令更新模块:
$ npm update express
搜索模块
使用以下来搜索模块: $ npm search express
创建模块
创建模块,package.json 文件是必不可少的。我们可以使用 NPM 生成 package.json 文件,生成的文件包含了基本的结果。
npm init
接下来我们可以使用以下命令在 npm 资源库中注册用户(使用邮箱注册):
npm adduser
接下来我们就用以下命令来发布模块:
npm publish
如果你以上的步骤都操作正确,你就可以跟其他模块一样使用 npm 来安装。
版本号
使用NPM下载和发布代码时都会接触到版本号。NPM使用语义版本号来管理代码,这里简单介绍一下。
- 语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。
- 如果只是修复bug,需要更新Z位。
- 如果是新增了功能,但是向下兼容,需要更新Y位。
- 如果有大变动,向下不兼容,需要更新X位。
- 版本号有了这个保证后,在申明第三方包依赖时,除了可依赖于一个固定版本号外,还可依赖于某个范围的版本号。例如"argv": "0.0.x"表示依赖于0.0.x系列的最新版argv。
- NPM支持的所有版本号范围指定方式可以查看官方文档。
NPM 常用命令
除了本章介绍的部分外,NPM还提供了很多功能,package.json里也有很多其它有用的字段。 除了可以在 ://docs.npmjs.com/ 查看官方文档外,这里再介绍一些NPM常用命令。
- npm install 安装包
- npm publish 发布包
- npm help 可查看所有命令。
- 使用npm help <command>可查看某条命令的详细帮助,例如 npm help install。
- 在package.json所在目录下使用npm install -g 可先在本地安装当前命令行程序。
- 使用npm update <package>可以把当前目录下node_modules子目录里边的对应模块更新至最新版本。
- 使用npm update <package> -g可以把全局安装的对应命令行程序更新至最新版。
- 使用npm cache clear可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。
- 使用npm unpublish <package>@<version>可以撤销发布自己发布过的某个版本代码。
console
console 用于提供控制台标准输出,它是由 Internet Explorer 的 JScript 引擎提供的调试工具,后来逐渐成为浏览器的事实标准。 Node.js 沿用了这个标准,提供与习惯行为一致的 console 对象,用于向标准输出流(stdout)或标准错误流(stderr)输出字符。
console 方法 以下为 console 对象的方法:
- console.log([data][, ...]) 向标准输出流打印字符并以换行符结束。该方法接收若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。
- console.info([data][, ...]) P该命令的作用是返回信息性消息,这个命令与console.log差别并不大,除了在chrome中只会输出文字外,其余的会显示一个蓝色的惊叹号。
- console.error([data][, ...]) 输出错误消息的。控制台在出现错误时会显示是红色的叉子。
- console.warn([data][, ...]) 输出警告消息。控制台出现有黄色的惊叹号。
- console.dir(obj[, options]) 用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示。
- console.time(label) 输出时间,表示计时开始。
- console.timeEnd(label) 结束时间,表示计时结束。
- console.trace(message[, ...]) 当前执行的代码在堆栈中的调用路径,这个测试函数运行很有帮助,只要给想测试的函数里面加入 console.trace 就行了。
- console.assert(value[, message][, ...]) 用于判断某个表达式或变量是否为真,接手两个参数,第一个参数是表达式,第二个参数是字符串。只有当第一个参数为false,才会输出第二个参数,否则不会有任何结果。
console.log():向标准输出流打印字符并以换行符结束。 console.log 接受若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。 第一个参数是一个字符串,如果没有 参数,只打印一个换行。
console.log('Hello world'); console.log('byvoid%diovyb'); console.log('byvoid%diovyb', 1991);
console.error():与console.log() 用法相同,只是向标准错误流输出。 console.trace():向标准错误流输出当前的调用栈。