什么是Nodejs?
Nodejs是一个基于Chrome V8 引擎的JavaScript运行时(运行环境)。
下载安装Nodejs
官方站点:https://nodejs.org/en/
国内站点:http://nodejs.cn/
建议安装长期支持版(Long Term Support)
建议不要修改默认的安装目录
默认安装的内容有哪些?
- Node.js runtime JavaScript运行时的环境
- npm package manager(Node Package Manager,NPM)Node.js的包管理器,简称为npm
- Online documentation shortcuts 在线帮助文档
- Add to PATH 将Nodejs安装目录添加到PATH环境变量中
Node.js提供了哪些内容?
- Nodejs运行时,JavaScript代码运行时的环境。
- 提供了一些核心模块,应用程序编程接口(Application Program Interface,API)
- 官方API文档https://nodejs.org/dist/latest-v12.x/docs/api/
- 国内API文档http://nodejs.cn/api/
- 交互式解析器(Read Execute Print Loop,REPL),以及一些相关的命令
- 打开命令窗口,输入node并回车,即可进入交互式解析器
- 输入.help命令,获取帮助信息。
- 输入.break或.clear(.break命令的别名)跳出当前代码块,例如,if(true){ .break
- 输入.save命令,可以将当前会话中的代码保存到一个文件中,例如,.save app.js
- 输入.load命名,可以一个文件中的代码加载到当前会话中执行,例如,.load app.js
- 输入.editor命名,进入编辑器模式,Ctrl + D编辑完成,Ctrl + C取消编辑
- 输入.exit命令,回车既可以退出交互式解析器
- 引入CommonJS模块化规范,同时支持ECMAScript模块化规范
CommonJS模块化规范
设计初衷
早期的JavaScript没有模块化系统,标准库比较少,缺乏包管理器工具;为了让JavaScript可以在任何地方执行,以达到Java、C#、PHP这些后台语言具备开发大型应用的能力。
设计理念
- 在Node.js模块系统中,每个文件都被视为一个独立的模块,拥有独立的作用域。
- 使用普通方式定义的变量、常量、函数以及类等等都属于当前模块。
- 通过exports和module.exports来导出模块中的成员。
- 使用require()方法导入其他模块导出的成员。
- 所有的代码都运行在当前模块作用域下,不会污染全局作用域。
- 模块可以被多次导入,但是模块中的代码只会在第一次被加载时执行,执行结果会被缓存,再次加载时,则读取上次缓存的结果。
- 模块会按照引入的顺序同步加载。
导出模块成员
使用module.exports对象导出模块成员
每个模块内部都有一个 module 对象,代表当前模块,我们可以使用它的 exports 属性导出模块成员。该属性的初始值为一个空对象,我们只需要将被导出的成员添加为该对象的属性即可。例如:
// 模块私有的成员
function divide ( x, y ) {
return x / y;
}
function multiply ( x, y ) {
return x * y;
}
// 如果我们想导出某个成员的话,只需要将它添加为 module.exports 对象的属性即可。
// 模块导出的成员
module.exports.add = function (x, y) {
return x + y;
};
.exports.subtract = function (x, y) {
return x - y;
};
使用module.exports的别名:exports对象
为了方便导出模块成员,Node.js为每个模块提供了一个exports对象,exports对象的初始值与module.exports对象的初始值相同,也就是说exports对象与module.exports对象指向同一个对象。我们可以用如下代码解释:
var exports = module.exports = {}
这样一来,我们就可以直接使用exports对象导出模块成员,如下所示:
exports.add = function (x, y) {
return x + y;
};
exports.subtract = function (x, y) {
return x - y;
};
一次导出多个成员
上面的两种导出方式每次只能导出一个成员,如果我们想一次导出多个成员,则可以使用一个包含要导出成员的新对象替换module.exports属性来的值(空对象)。
function add (x, y) {
return x + y;
}
function subtract (x, y) {
return x - y;
}
module.exports = {
add,
subtract
};
module.exports属性的值改变之后,exports对象的值并不会随着改变,此时两者不再指向同一个对象。Node.js规定只有module.exports对象中的成员会被导出,因此exports对象失去了导出模块成员的功能。
// 使用一个新对象替换module.exports属性来的对象
module.exports = {
add,
subtract
};
// exports对象失去了导出模块成员的功能,此处导出模块成员失败。
exports.multiply = multiply;
// 1. exports对象的初始值与module.exports对象相同,指向同一个空对象。
// 2. module.exports属性的值改变之后,exports对象的值并不会随着改变,还指向原来的空对象。
// 3. 由于只有module.exports对象中的成员会被导出,因此向exports对象添加的成员不会被导出。
// 简而言之,module.exports 指向哪个对象,哪个对象中的成员就会被导出
但是我们可以让exports对象重新指向module.exports对象,从而让exports对象再次具有导出模块成员的功能。
exports = module.exports = {
add,
subtract
};
// 由于exports对象与module.exports再次指向同一个对象,因此下面的导出语句成功
exports.multiply = multiply;
使用NodeJS模块
除了使用自己写的本地模块以外,NodeJS可以使用另外两种类型的模块,分别是NodeJS官方提供的核心模块和第三方提供的模块。
NodeJS官方提供的核心模块
NodeJS平台自带的一套基本的功能模块,也被称为NodeJS平台的API。
// 使用模块全局的 require() 方法引入 fs 模块
const fs = require('fs')
// 使用 fs 模块导出的 readFile() 方法读取 data.json 文件中的内容
fs.readFile('./data.json', {encoding: 'utf8', flag: 'r'}, (err, data) => {})
第三方开发者提供的模块
第三方模块是由NodeJS社区或第三方个人开发的功能模块,这些功能模块以软件包的形式存在。被发布在npmjs注册表中。npmjs是一个注册中心,所有软件包的信息都会被记录到该注册中的数据库中,我们可以来到npmjs官方站点,根据关键字搜索自己需要的软件包。
点击软件包的名字会跳转到软件包的详情页面:
我们需要的软件包已经找到了,但是我们怎么样去使用软件包提供的功能呢?
我们可以通过NPM(Node Package Manager)使用软件包,NPM是NodeJS的包管理器,它提供了一系列的命令,可以帮我们安装、删除、更新、搜索以及创建自己的软件包。
由于只有软件包才是使用其他的软件包,因此我们必须要先创建自己的软件包,然后才能在自己的软件包中使用其他的软件包。
我们怎么样去创建自己的软件包呢?答案是通过NPM提供的一系列命令创建自己的软件包。
1、 在合适的目录下,打开命令窗口,创建软件包的目录,并切换到该目录下:
mkdir lodashdemo && cd loadshdemo
2、 使用NPM提供的命令,初始化软件包,你需要回答几个问题,回答完毕之后会生成一个package.json文件,该文件记录了软件包的所有信息。
npm init
3、如果你只是想把创建的包作为一个本地项目,并不想将它发布到npmjs注册中心(不想让别人使用你的软件包),你需要移除package.json文件中的main字段,然后添加private字段,并指定其值为true,表示这是私有的软件包。修改之后的结果如下:
{
"name": "lodashdemo",
"version": "1.0.0",
"description": "讲解 NPM 包管理器的使用方法",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"demo",
"lodash",
"陈老师"
],
"author": "陈老师",
"license": "MIT"
}
3、 使用NPM的命令安装第三方模块,此步骤需要访问网络。
npm install lodash --save-prod
- install也可以简写成i
- –save-prod 将 lodash 模块作为当前软件包的产品依赖,并将依赖信息记录到package.json文件中的dependencies字段中
- 此外,初次执行install命令时,还会生成一个package-lock.json文件,该文件记录了当前软件包所依赖的其他软件包的详细信息,用于将软件包锁定到特定的版本。
- 安装完成之后,当前项目的目录下会生成一个node_modules/目录,目录中保存就是我们下载后的软件包。
4、 创建自己的项目文件,例如,app.js文件,导入第三方模块,即可使用模块提供的功能
// 导入 lodash 模块
const _ = require('lodash');
// 使用 lodash 模块提供的方法
const add = _.add(12, 56)
console.log(add)
const subtract = _.subtract(8, 4)
console.log(subtract)
const multiply = _.multiply(8, 4)
console.log(multiply)
NPM使用说明
什么是NPM
NPM是世界上最大的软件注册机构(登记处)。来自世界各地的开源开发者可以使用NPM来共享自己的写软件包,也可以使用他人写的软件包。
NPM有3部分内容组成:
- Npmjs官方站点,用于搜索你想要使用的软件包
- 注册表,一个大型的公共数据库,记录了所有软件包的信息
- 命令行界面(Command Line Interface,CLI),开发者与NPM交互的工具
获取离线帮助信息
npm help <command>
在windows系统中,该命令会自动使用默认的浏览器打开命令的帮助文档。
NPM常用命令
1、 初始化软件包
npm init
该命令会询问你几个问题,然后把我们出入的结果记录到package.json文件中。但是你可以使用 -y/–yes选项跳过提问的过程。
2、 安装第三方的软件包
npm install [@scope/]<package name>[@version]
命名参数:
- scope,一般指的是组织或公司的名字,通常情况下我们安装的软件包是没有scope
- package name,要安装的包名
- version,你要安装哪个版本,省略则默认安装最新版本
安装选项:
- –global,-g,全局安装,安装到了C:\Users\Administrator\AppData\Roaming\npm\node_modules,全局安装的软件包可以在任何项目中使用,一般安装的是一些需要全局使用的命令行软件包。
- –save-prod,-P,安装到当前目录下的node_modules/目录下,作为当前项目的产品阶段的依赖,会被记录到package.json文件中的dependencies字段中。
- –save-dev,-D,安装到当前目录下的node_modules/目录下,作为当前项目的开发阶段的依赖,会被记录到package.json文件中的devDependencies字段中。
- –no-save,安装到当前目录下的node_modules/目录下,不会被记录到package.json文件中。
3、 删除某个软件包
npm uninstall [@scope/]<package name>[@version]
该命令不仅会删除软件包及其依赖的其他软件包,还会删除软件包在package.json文件中的记录。
4、 查看已经安装的软件包
npm list
该命令默认会树形结构输出当前项目依赖的所有软件包。但是我们可以使用一些选项该改变输出的结果。
--global,列出所有全局安装的软件包
--depth number,number指的是层数,从0开始,例如,npm list --depth 0,表示显示第一层的软件包。
全局安装与本地安装
全局安装
全局安装的软件包可以在任何目录下使用,一般情况下,用于安装提供命令行工具的软件包。全局安装的软件包不能使用require()方法导入到项目中。
npm install http-server --global
例如,上面的命令全局安装了一个http-server软件包,该软件包提供了一个http-server命令,可以在任意目录下打开一个http服务器,并托管该目录下的所有静态资源。
本地安装
软件包会被安装到项目的node_modules/目录下。
安装成开发阶段的依赖
如果我们只是在开发阶段需要某个软件包,那么我们就可以把它安装成项目的开发依赖,例如less或sass。
npm install --save-dev/-D less
安装成产品阶段的依赖
如果在产品上线之后我们还需要某个软件包,那么这个软件包就可以安装成我们项目的产品依赖,例如,lodash。
npm install --save-prod/--save/-P
解决npm下载慢的问题
方法一:使用淘宝定制的cnpm命令行工具替代默认安装npm
npm install -g cnpm --registry=https://registry.npm.taobao.org
方法二:将npm默认的下载地址修改为淘宝镜像
npm cofig set registry https://registry.npm.taobao.org/
注意,如果将来你需要发布自己的软件包时,需要将registry字段的值修改回来
npm cofig set registry https://registry.npmjs.org/
命令行常用命名
cd,change directory:改变目录
mkdir,make directory:创建目录
&& 用于一次执行多个命令
全局变量
以下几个变量虽然看起来是全局的,但其实并不是,它们仅存在于模块范围内。
- require(),模块作用域中的全局方法,用于导入其他模块
- module,表示当前模块
- exports,module.exports属性的别名,用于导出模块成员
- __dirname,表示当前文件所在的目录
- __filename,表示当前文件的名称(名称前面具有完整的路径)
在package.json文件配置命令
当我们要执行的命令比较复杂时,可以将该命名配置到package.json文件中scripts字段中,并为该命令指定一个别名;
"scripts": {
"serve": "node server.js"
},
上面的代码为 node server.js指定了一个别名serve,然后我们可以通过npm的子命令run去执行该命令:
npm run serve
如果命令的别为start,则执行时可以省略子命令run
"scripts": {
"start": "node server.js",
},
npm start
单词表
env,environment,美 [ɪnˈvaɪrənmənt] n. (运行)环境;环境变量
单词表
execute 美 [ˈeksɪkjuːt] v.实行;执行;实施;
manager 美 [ˈmænɪdʒər] n.(企业、店铺等的)经理,经营者,老板,管理者;
module 美 [ˈmɑːdʒuːl] n.模块;功能块;程序块;
exports 美 [ɪkˈspɔːrts] v.出口;输出;传播,输出(思想或活动);移出;调出
require 美 [rɪˈkwaɪər] v.需要;依靠;依赖;
command 美 [kəˈmænd] n.(给人或动物的)命令;指令;命令;控制;管辖;指挥
license 美 [ˈlaɪsns] n.执照,许可证;特许
private 美 [ˈpraɪvət] adj.私有的;私用的;自用的;
production 美 [prəˈdʌkʃn] n.生产;制造;制作;
depth 美 [depθ] n.向下的距离;深(度);纵深;