Node.js (一) 安装使用与CommanJS模块化
Node.js 是基于谷歌 V8( 一种JavaScript 引擎 )构建的一种 JavaScript 运行环境,由 Ryan Dahl 开发
Node.js 使 JavaScript 脱离了浏览器,可以实现服务器开发的一种 JavaScript 运行环境
Node.js 的安装
官方地址:https://nodejs.org/zh-cn/
安装完成后,输入 node -v
命令检测是否安装成功
1 | node -v #显示node版本号 |
通常 nodejs 安装时会自动安装 npm
(node package manager)。输入 npm -v
检查 npm 是否安装
1 | npm -v #显示npm版本号 |
Node.js 版本管理
推荐下面这款工具来管理 Node.js 的版本
fnm: https://github.com/Schniz/fnm(推荐!!)
- 特点: 基于 Rust、快速、简单、垮平台
fnm 的使用:
1 | 查看已安装的所有版本及版本别名(包括系统内安装的版本) |
模块(Module)
Node.js 是基于 CommonJS 模块化规范实现的模块系统
在 CommonJS 模块化规范中一个文件就是一个模块,每个模块都有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见
每个模块中必须有一个变量 module
,它是一个对象,代表当前模块自身,通过 module.exports
或 exports
对象可以导出当前模块的方法或者变量
exports 和 module.exports 默认为相等关系:exports === module.exports
1 | // module.js |
通过 module.require()
方法 或 require()
函数来引入某个模块,函数会返回被引入模块中的 module.exports
对象
require 和 module.require 默认为相等关系:require === module.require
1 | // getModule.js |
在模块中,变量this 默认指向当前模块的导出对象
1 | console.log(this == module.exports); // true |
在Node.js中,模块分为两类:
一类是Node.js自身提供的模块,称为核心模块;另一类是用户编写的模块,称为文件模块
核心模块部分在Node 源代码的编译过程中,被编译成了二进制执行文件。在Node 进程启动时,核心模块就被直接加载进内存中,所以核心模块的加载速度是最快的,如:http、fs、url等
文件模块则是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程。速度相比核心模块稍微慢一些
包(Package)
包是实现模块系统的重要规范,Node.js 中包就是一个目录,一个包中包含了模块所需的所有文件,符合 CommonJS 模块化规范的包目录,应该包含以下文件:
package.json:包的描述文件(必要文件‼️),必须在包的根目录下
bin:可执行二进制文件放在该目录下
lib:JavaScript代码放在该目录下
doc:文档放在该目录下
test:单元测试放在该目录下
npm 命令行工具
npm 是一个命令行工具,它是 JavaScript 的包管理工具,借助 npm 我们可以实现 JavaScript 模块的发布,安装和依赖等
使用 npm 工具创建一个JavaScript项目:
1.新建一个名为 test 的目录
1 | mkdir test |
2.并在该目录下执行 npm init
命令,之后根据提示输入信息
1 | cd test |
npm 常用命令
初始化项目:
npm init
-y
: 使用默认配置
搜索包:
npm search <包名>
安装包:
npm install/i <包名>
--save
:默认参数,将下载或本地的包文件解压到当前目录下的node_modules
目录( 安装 ),并将其添加到项目依赖中
卸载包:
npm uninstall <包名>
- 别名:
npm remove/rm/r <包名>
- 别名:
安装指定版本的npm:
npm install npm@x.x.x -g
@latest
:最新版
设置淘宝镜像源:
npm config set registry https://registry.npmmirror.com
设置官方镜像源:
npm config set registry https://registry.npmjs.org
查看当前镜像源:
npm config get registry
模块的实现
Node.js 运行时会将每个模块中代码包装到一个函数内执行,Node.js 会将模块所需要的接口作为该函数的参数传入,函数代码大致如下:
1 | (function (exports, require, module, __filename, __dirname) { |
模块标识符:
模块标识符是用来查找和定位模块的一个字符串
文件模块的查找规则
在使用 require() 函数加载文件模块时,Node.js 会根据传入的参数,即模块标识符,对文件进行查找,查找规则如下:
1 | require('xxx') |
情况一:xxx是一个核心模块,则直接返回核心模块,并停止查找,比如:path、http等
情况二:xxx以./
(当前目录)、../
(上一级目录)、/
(根目录)开头的,会将xxx作 为文件在对应目录进行查找,查找规则如下:
有后缀名,按照当前后缀名查找对应的文件
没有后缀名,会按照如下顺序查找:
直接查找文件xxx
查找 xxx.js文件
查找 xxx.json文件
查找 xxx.node文件
如果依然没找到,则会将xxx作为目录查找,查找规则如下:
查找 xxx/index.js
查找 xxx/index.json
查找 xxx/index.node
如果还没找到,则抛出异常:not found
如果找到,则会使用
JSON.parse()
方法解析该目录下的package.json
文件的内容来得到描述对象,然后根据对象中main属性( 默认为index.js )指定的模块标识符来查找文件如果没找到,则抛出异常:not found
情况三:如果 xxx是一个单词(不包含特殊符号,如:./
、/
、空格等),并且xxx不是一个核心模块,则会将其作为一个包( 目录 )来查找,查找规则如下:
从当前模块的module.paths
属性中的所有路径以及全局路径下依次查找名为 xxx的目录
require()
函数加载文件模块时采用同步加载,为了提高效率,Node.js 运行时会缓存已经加载过的文件,当发现某个文件已加载过了,则直接从缓存中加载,不会重复加载同一个文件模块
查看已缓存的模块:console.log(require.cache)