详解Node.js包的工程目录与NPM包管理器的使用


Posted in Javascript onFebruary 16, 2016

工程目录

了解了以上知识后,现在我们可以来完整地规划一个工程目录了。以编写一个命令行程序为例,一般我们会同时提供命令行模式和 API 模式两种使用方式,并且我们会借助三方包来编写代码。除了代码外,一个完整的程序也应该有自己的文档和测试用例。因此,一个标准的工程目录都看起来像下边这样。

- /home/user/workspace/node-echo/  # 工程目录
  - bin/             # 存放命令行相关代码
    node-echo
  + doc/             # 存放文档
  - lib/             # 存放API相关代码
    echo.js
  - node_modules/         # 存放三方包
    + argv/
  + tests/            # 存放测试用例
  package.json          # 元数据文件
  README.md            # 说明文件

其中部分文件内容如下:

/* bin/node-echo */
var argv = require('argv'),
  echo = require('../lib/echo');
console.log(echo(argv.join(' ')));

/* lib/echo.js */
module.exports = function (message) {
  return message;
};

/* package.json */
{
  "name": "node-echo",
  "main": "./lib/echo.js"
}

以上例子中分类存放了不同类型的文件,并通过 node_moudles 目录直接使用三方包名加载模块。此外,定义了package.json 之后,node-echo 目录也可被当作一个包来使用。

NPM

NPM 是随同 NodeJS 一起安装的包管理工具,能解决 NodeJS 代码部署上的很多问题,常见的使用场景有以下几种:

  • 允许用户从 NPM 服务器下载别人编写的三方包到本地使用。
  • 允许用户从 NPM 服务器下载并安装别人编写的命令行程序到本地使用。
  • 允许用户将自己编写的包或命令行程序上传到 NPM 服务器供别人使用。

可以看到,NPM 建立了一个 NodeJS 生态圈,NodeJS 开发者和用户可以在里边互通有无。以下分别介绍这三种场景下怎样使用 NPM。

下载三方包
需要使用三方包时,首先得知道有哪些包可用。虽然 npmjs.org 提供了个搜索框可以根据包名来搜索,但如果连想使用的三方包的名字都不确定的话,就请百度一下吧。知道了包名后,比如上边例子中的 argv,就可以在工程目录下打开终端,使用以下命令来下载三方包。

$ npm install argv
...
argv@0.0.2 node_modules\argv

下载好之后,argv 包就放在了工程目录下的 node_modules 目录中,因此在代码中只需要通过 require('argv')的方式就好,无需指定三方包路径。

以上命令默认下载最新版三方包,如果想要下载指定版本的话,可以在包名后边加上@<version>,例如通过以下命令可下载 0.0.1 版的 argv。

$ npm install argv@0.0.1
...
argv@0.0.1 node_modules\argv

如果使用到的三方包比较多,在终端下一个包一条命令地安装未免太人肉了。因此 NPM 对 package.json 的字段做了扩展,允许在其中申明三方包依赖。因此,上边例子中的 package.json 可以改写如下:

{
  "name": "node-echo",
  "main": "./lib/echo.js",
  "dependencies": {
    "argv": "0.0.2"
  }
}

这样处理后,在工程目录下就可以使用 npm install 命令批量安装三方包了。更重要的是,当以后 node-echo 也上传到了 NPM 服务器,别人下载这个包时,NPM 会根据包中申明的三方包依赖自动下载进一步依赖的三方包。例如,使用 npm install node-echo 命令时,NPM 会自动创建以下目录结构。

- project/
  - node_modules/
    - node-echo/
      - node_modules/
        + argv/
      ...
  ...

如此一来,用户只需关心自己直接使用的三方包,不需要自己去解决所有包的依赖关系。

安装命令行程序
从 NPM 服务上下载安装一个命令行程序的方法与三方包类似。例如上例中的 node-echo 提供了命令行使用方式,只要 node-echo 自己配置好了相关的 package.json 字段,对于用户而言,只需要使用以下命令安装程序。

$ npm install node-echo -g

参数中的 -g 表示全局安装,因此 node-echo 会默认安装到以下位置,并且 NPM 会自动创建好 Linux 系统下需要的软链文件或 Windows 系统下需要的.cmd文件。

- /usr/local/        # Linux系统下
  - lib/node_modules/
    + node-echo/
    ...
  - bin/
    node-echo
    ...
  ...

- %APPDATA%\npm\      # Windows系统下
  - node_modules\
    + node-echo\
    ...
  node-echo.cmd
  ...

发布代码
第一次使用 NPM 发布代码前需要注册一个账号。终端下运行 npm adduser,之后按照提示做即可。账号搞定后,接着我们需要编辑 package.json 文件,加入 NPM 必需的字段。接着上边 node-echo 的例子,package.json 里必要的字段如下。

{
  "name": "node-echo",      # 包名,在NPM服务器上须要保持唯一
  "version": "1.0.0",      # 当前版本号
  "dependencies": {       # 三方包依赖,需要指定包名和版本号
    "argv": "0.0.2"
   },
  "main": "./lib/echo.js",    # 入口模块位置
  "bin" : {
    "node-echo": "./bin/node-echo"   # 命令行程序名和主模块位置
  }
}

之后,我们就可以在 package.json 所在目录下运行 npm publish 发布代码了。

版本号
使用 NPM 下载和发布代码时都会接触到版本号。NPM 使用语义版本号来管理代码,这里简单介绍一下。

语义版本号分为 X.Y.Z 三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。

+ 如果只是修复bug,需要更新Z位。

+ 如果是新增了功能,但是向下兼容,需要更新Y位。

+ 如果有大变动,向下不兼容,需要更新X位。
版本号有了这个保证后,在申明三方包依赖时,除了可依赖于一个固定版本号外,还可依赖于某个范围的版本号。例如"argv": "0.0.x"表示依赖于 0.0.x 系列的最新版 argv。NPM 支持的所有版本号范围指定方式可以查看官方文档。

灵机一点
除了本章介绍的部分外,NPM 还提供了很多功能,package.json 里也有很多其它有用的字段。除了可以在 npmjs.org/doc/ 查看官方文档外,这里再介绍一些 NPM 常用命令。

NPM 提供了很多命令,例如 install 和 publish,使用 npm help 可查看所有命令。

  • 使用 npm help 可查看某条命令的详细帮助,例如 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>可以撤销发布自己发布过的某个版本代码。
Javascript 相关文章推荐
ajax 文件上传应用简单实现
Mar 03 Javascript
Jquery实现仿腾讯微博发表广播
Nov 17 Javascript
Javascript实现获取窗口的大小和位置代码分享
Dec 04 Javascript
javascript使用appendChild追加节点实例
Jan 12 Javascript
Javascript之BOM(window对象)详解
May 25 Javascript
使用bootstrap typeahead插件实现输入框自动补全之问题及解决办法
Jul 07 Javascript
Vue中img的src属性绑定与static文件夹实例
May 18 Javascript
Vue from-validate 表单验证的示例代码
Sep 26 Javascript
微信小程序自定义底部导航带跳转功能
Nov 27 Javascript
利用原生JavaScript实现造日历轮子实例代码
May 08 Javascript
ES6顶层对象、global对象实例分析
Jun 14 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
Aug 10 Javascript
javascript每日必学之运算符
Feb 16 #Javascript
解析Node.js基于模块和包的代码部署方式
Feb 16 #Javascript
javascript每日必学之基础入门
Feb 16 #Javascript
快速掌握Node.js环境的安装与运行方法
Feb 16 #Javascript
js实现异步循环实现代码
Feb 16 #Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)
Feb 16 #Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(一)
Feb 16 #Javascript
You might like
PHP laravel中的多对多关系实例详解
2017/06/07 PHP
基于jquery的direction图片渐变动画效果
2010/05/24 Javascript
TBCompressor js代码压缩
2011/01/05 Javascript
js获取对象为null的解决方法
2013/11/21 Javascript
JQuery中serialize()用法实例分析
2015/02/06 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
2015/09/27 Javascript
图解js图片轮播效果
2015/12/20 Javascript
基于Node.js的强大爬虫 能直接发布抓取的文章哦
2016/01/10 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
2016/08/17 Javascript
JS用斜率判断鼠标进入DIV四个方向的方法
2016/11/07 Javascript
微信小程序 MD5加密登录密码详解及实例代码
2017/01/12 Javascript
ajax分页效果(bootstrap模态框)
2017/01/23 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
vue修改对象的属性值后页面不重新渲染的实例
2018/08/09 Javascript
vue项目中mock.js的使用及基本用法
2019/05/22 Javascript
Swiper.js实现移动端元素左右滑动
2019/09/08 Javascript
三剑客:offset、client和scroll还傻傻分不清?
2020/12/04 Javascript
[38:21]2018DOTA2亚洲邀请赛3月30日 小组赛A组 LGD VS Newbee
2018/03/31 DOTA
[00:32]2018DOTA2亚洲邀请赛出场——LGD
2018/04/04 DOTA
Python中Continue语句的用法的举例详解
2015/05/14 Python
Python编程之属性和方法实例详解
2015/05/19 Python
Python实现PS图像调整之对比度调整功能示例
2018/01/26 Python
Python3按一定数据位数格式处理bin文件的方法
2019/01/24 Python
Python八皇后问题解答过程详解
2019/07/29 Python
利用Python产生加密表和解密表的实现方法
2019/10/15 Python
python实现密码验证合格程序的思路详解
2020/06/01 Python
Python数据可视化图实现过程详解
2020/06/12 Python
如何用css3实现switch组件开关的方法
2018/02/09 HTML / CSS
如何使用amaze ui的分页样式封装一个通用的JS分页控件
2020/08/21 HTML / CSS
泰国国际航空公司官网:Thai Airways International
2019/12/04 全球购物
JPA的优势都有哪些
2013/07/04 面试题
爱护公共设施标语
2014/06/24 职场文书
2014年保洁工作总结
2014/11/24 职场文书
2015共产党员公开承诺书
2015/01/22 职场文书
五星级酒店宣传口号
2015/12/25 职场文书
解决Python字典查找报Keyerror的问题
2021/05/26 Python