Node.js 基础概览
Node.js 基础概览
在编写一个稍大的程序我们一般会将代码模块化使其更易开发维护。Node.js模块采用了CommonJS规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域。提供了 require
函数来调用其他模块、exports
对象是当前模块的导出对象,用于导出模块公有方法和属性。exports
是指向的 module.exports
的引用
模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。
我们都知道JavaScript先天就缺乏一种功能:模块。浏览器环境的js模块划分只能通过src
引入使用。然而,我们是辛运的的,我们在身在这个前端高速发展的时代*(当然了,这也是一种压力,一觉醒来又有新东西诞生了)*。高速发展下社区总结出了CommonJS这算得上是最为重要的里程碑。CommonJS 制定了解决这些问题的一些规范,而Node.js就是这些规范的一种实现。Node.js自身实现了require方法作为其引入模块的方法,同时NPM也是基于CommonJS定义的包规范
Node模块
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。commonJS这套规范的出现使得用户不必再考虑变量污染,命名空间这些问题了。
小示例
1 |
|
1.模块引用
require()
这个方法存在接受一个模块标识,以此引入模块
1 |
|
Node中引入模块要经历一下三步:
- 路径分析
- 文件定位
- 编译执行
Node优先从缓存中加载模块。Node的模块可分为两类:
- Node提供的核心模块
- 用户编写的文件模块
Node核心模块加载速度仅次于缓存中加载,然后路径形式的模块次之,最慢的是自定义模块。
2.模块定义
在模块中,上下文提供了exports
来到处模块的方法或者变量。它是唯一出口
1 |
|
在模块中还存在一个module对象,它代表模块自身,exports
是它的属性。为了方便,Node为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令
1 |
|
不能直接将exports变量指向一个值,因为这样等于切断了exports与module.exports的联系
exports和module.exports 区别
exports仅仅是module.exports的一个地址引用。nodejs只会导出module.exports的指向,如果exports指向变了,那就仅仅是exports不在指向module.exports,于是不会再被导出
- module.exports才是真正的接口,exports只不过是它的一个辅助工具。最终返回给调用的是module.exports而不是exports。
- 所有的exports收集到的属性和方法,都赋值给了module.exports。当然,这有个前提,就是module.exports本身不具备任何属性和方法。如果,module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略
- Node开发者建议导出对象用module.exports,导出多个方法和变量用exports
npm模块管理器
npm
的出现则是为了在CommonJS规范的基础上,实现解决包的安装卸载,依赖管理,版本管理等问题,npm
不需要单独安装。在安装Node的时候,会连带一起安装npm
- 允许用户从NPM服务器下载别人编写的第三方包到本地使用。
- 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。
- 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。
npm包
一个符合CommonJS规范的包应该是如下这种结构:
- 一个package.json文件应该存在于包顶级目录下
- 二进制文件应该包含在bin目录下。
- JavaScript代码应该包含在lib目录下。
- 文档应该在doc目录下。
- 单元测试应该在test目录下
package.json
- name:包名,需要在NPM上是唯一的,小写字母和数字组成可包含
_
-
.
但不能有空格 - description:包简介。通常会显示在一些列表中
- version:版本号。一个语义化的版本号(http://semver.org/ ),通常为x.y.z。该版本号十分重要,常常用于一些版本控制的场合
- keywords:关键字数组。用于NPM中的分类搜索
- maintainers:包维护者的数组。数组元素是一个包含name、email、web三个属性的JSON对象
- contributors:包贡献者的数组。第一个就是包的作者本人。在开源社区,如果提交的patch被merge进master分支的话,就应当加上这个贡献patch的人。格式包含name和email
- bugs:一个可以提交bug的URL地址。可以是邮件地址(mailto:mailxx@domain),也可以是网页地址
- licenses:包所使用的许可证
- repositories:托管源代码的地址数组
- dependencies:当前包需要的依赖。这个属性十分重要,NPM会通过这个属性,帮你自动加载依赖的包
除了前面提到的几个必选字段外,还有一些额外的字段,如bin、scripts、engines、devDependencies、author
npm的使用
行下面的命令,查看各种信息
1 |
|
npm 命令安装模块
Node模块采用npm install
命令安装。
每个模块可以“全局安装”,也可以“本地安装”。“全局安装”指的是将一个模块安装到系统目录中,各个项目都可以调用。一般来说,全局安装只适用于工具模块。“本地安装”指的是将一个模块下载到当前项目的node_modules
子目录,然后只有在项目目录之中,才能调用这个模块。
1 |
|
指定所安装的模块属于哪一种性质的依赖关系
–-save
:模块名将被添加到dependencies,可以简化为参数-S
。–-save-dev
: 模块名将被添加到devDependencies,可以简化为参数-D
。
1 |
|
卸载模块
我们可以使用以下命令来卸载 Node.js 模块
1 |
|
更新模块
我们可以使用以下命令来更新 Node.js 模块
1 |
|
创建模块
我们可以使用以下命令来创建 Node.js 模块
1 |
|
npm init
创建模块会在交互命令行帮我们生产package.json文件
1 |
|
以上的信息,你需要根据你自己的情况输入。默认回车即可。在最后输入 “yes” 后会生成 package.json 文件。
模块发布
发布模块前首先要在npm注册用户
1 |
|
然后
1 |
|
现在我们的npm包就成功发布了。
更多请查看npm帮助信息 npm 文档