1. Node.js 介绍
npm的两层含义
- npm 是一个网站,这个网站上托管了几十万个使用 JavaScript 开发的功能模块库
- npm 是一个基于Node开发的一个终端命令行包管理工具
- 可以使用这个工具去 npm 网站上下载对应的库
npm 安装
只要安装了 node 就有了 npm。
通过 npm -v
测试是否有 npm 工具。
使用 npm 安装包
- 找到能解决自己问题的包,看文档使用说明
- 通过
npm install 包名
下载到当前项目中的根目录 - 在代码中通过
require('第三方包名')
使用你下载的包
通过 npm install 包名
安装的包会自动下载到当前目录下的 node_modules
目录,
如果该目录不存在,则直接创建,如果已存在,则直接将文件下载进去。
使用 Npm 安装全局命令行工具
在 npm 社区中,除了有可以在项目中使用的第三方包之外,还有一些特殊的包:
这些特殊的包被称之为命令行工具,不是用于项目的,而是可以安装到计算机中,
然后通过命令行中的命令的形式来使用,这种工具有很多,例如:http-server
、gulp
、
browser-sync
、nodemon
等等等等很多。
安装方式:
npm install --global 第三方命令行工具名字
卸载:
npm uninstall --global 第三方命令行工具名称
查看全局命令行安装目录:
npm root --global
1.1 网站开发模型(BS)
- Server
- 为客户端提交接口:数据
- Java、.Net、Ruby、Python、PHP、Go、Swift、Lua
- 学 Node 本质不是在学 Node,在学 服务器(Web后台)编程
- 请求
- 处理
- 响应
- 大前端时代:JavaScript 语言也可以运行在服务器端
- 使用 JavaScript 这门语言也可以进行服务器编程
- JavaScript 通过 Node.js 运行在服务器端
- Browser
- 客户端:把一堆用户看不懂的数据变成友好的形式给用户体验
1.2 什么是 Node.js?
简单的说 Node.js 就是运行在服务端的 JavaScript
Node开发就是利用 Ecmascript + 第三方开源库 + Node平台环境API进行编程
-
什么是 JavaScript
- JavaScript 一个运行在浏览器端的脚本原因
- 运行时:浏览器
- Ecmascript:JavaScript 基本语法:var、if-else、for、Array、Object、String、function
- BOM
- Window
- DOM
- 渲染引擎
- JavaScript 解析执行引擎
- 在所有浏览器中,Google Chrome 的 V8 引擎是最快的 JS 脚本代码解析执行引擎
- 通过 V8 引擎解析和执行 JavaScript 代码
Node 官网:https://nodejs.org/en/
-
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
- Node.js 是一个构建与 Chrome V8 引擎之上的一个 JavaScript 运行时(执行环境)
- Node 使用 JavaScript 进行编程
- Node 采用了 Chrome 的 V8 引擎解析和执行 JavaScript 脚本代码
- Node 不是一种语言,Node 可以用来解析和执行 JavaScript 代码
- 在 Node 没有 DOM、BOM 了,也不用去关心样式、结构问题了
- Node 在基本的 JavaScript 语言之上,或者在 Node 平台给 Ecmascript 提供了大量的底层编程接口
- 例如文件IO
- 例如网络IO
- 处理数据
- 操作数据库
- 构建网络服务
- 。。。
-
Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
- event-driven:事件驱动
- 在 Node 中,也采用了类似于浏览器端的编程思想,事件模型编程思想
- non-blocking I/O model:非阻塞IO模型
- Node 中大量的通过类似于浏览器中 ajax 的方式进行编程
- 绝大多数代码都是异步编程模型
- lightweight & efficient:轻量和高效
- event-driven:事件驱动
Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world.
1.3 使用 Node 可以做什么?
- 开发网站服务器
- 游戏服务器
- 开发命令行工具
- 软件分为两种:
- GUI:看得见,鼠标点点点
- CLI:命令窗口,各种命令,选项参数等
2 核心模块(Node 提供)
以下是常用的核心模块及作用:
核心模块名 | 作用 |
---|---|
fs | 文件操作 |
http | 网络操作 |
net | 更底层的网络操作 |
os | 操作系统相关 |
path | 文件路径操作 |
querystring | 查询字符串处理 |
url | url操作处理 |
2 Node 中的模块化
模块通信交互规则
- 一个 JavaScript 文件就是一个模块
- 模块天生就是一个私有的作用域,默认模块内定义的变量等成员只能被模块内部访问
- 每一个模块中都有一个
module.exports
编程接口对象,默认是一个空对象- 可以通过给
module.exports
编程接口对象添加成员向外暴露内部成员 - 例如:
var foo = 'bar' module.exports.foo = foo
- 上面示例标识当前模块向外部暴露了一个接口对象,内部有一个 foo 成员,值是 bar
- 可以通过给
-
require
方法可以用来加载模块,该方法是同步加载执行的,主要做两件事儿- 执行被加载模块中所有的代码
- 拿到被加载模块中的
module.exports
接口对象
- 拿到被加载模块中的
用户自定义模块
核心模块
核心模块就是 Node 提供的模块,例如 fs
、http
、path
。。。,
这些模块其实也是文件模块,核心模块一般都是通过一个固定的标识名称进行加载的,
也就是说不能写错,固定的。用什么就加载什么,无论是程序执行效率还是可维护性都非常好。
第三方模块
也就是npm社区提供的第三方包,用的时候,先下载,然后也是通过 require
进行加载,
加载第三方模块的时候,就是通过 require('第三方模块标识名')
,所以第三方模块不可能有和
核心模块重名的名称。
第三方加载模块有自己的一套加载规则,node 会按照对应的加载机制去加载。
具体明天上午会给大家详细解析。
- __dirname
- 用于获取当前文件所属目录的绝对路径
- 使用场景:常用语将相对路径转为绝对路径,防止执行node命令所处的目录影响路径的问题
- __filename
- 作用:获取当前文件的绝对路径
- process
- process 是Node中一个进程对象,可以用来访问当前运行进程的一些信息
- global
- 类似于浏览器中的 window,是一个全局对象
- 唯一的区别在于浏览器中的 window 是全局对象,默认在全局声明的变量成员都属于 window
- Node 中是模块作用域
- 在一个模块系统中,所有的模块都共享一个 global
- 也就是说可以通过给 global 显示的挂载成员在多个模块之间全局共享
- 虽然可以这样做,了解即可,尽量不要使用
- 模块成员
- module
- module 是一个模块对象,里面包含了当前模块的一些信息
- 例如 exports 就是当前模块对外的导出接口对象
- exports
- 在每一个模块中,同时还提供了一个接口成员:
exports
-
exports
是module.exports
接口对象的一个引用 - 也就是可以把
module.exports.foo=xxx
的形式简写为exports.foo=xxx
- 注意:注重向外的暴露的接口对象是:
module.exports
- 在每一个模块中,同时还提供了一个接口成员:
- require()
- 执行被加载模块中的代码
- 拿到被加载模块中的
module.exports
接口对象
3.启动node项目的准备工作
Babel Register
第一:在项目根目录下创建一个 .babelrc
文件,写入以下内容:
{
"presets": [
]
}
第二:安装对应的转码规则:
# ES2015转码规则
$ npm install --save-dev babel-preset-es2015
# react转码规则
$ npm install --save-dev babel-preset-react
# ES7不同阶段语法提案的转码规则(共有4个阶段),选装一个
$ npm install --save-dev babel-preset-stage-0
$ npm install --save-dev babel-preset-stage-1
$ npm install --save-dev babel-preset-stage-2
$ npm install --save-dev babel-preset-stage-3
第三:将 .babelrc
文件中修改为以下内容:
{
"presets": [
"es2015"
]
}
第四步(从第四步开始,前三部必不可少):
- babel-cli:命令行转码
- babel-node:babel-cli工具自带一个babel-node命令,提供一个支持ES6的REPL环境
- babel-register:实时转码,所以只适合在开发环境使用
- babel-core:如果某些代码需要调用Babel的API进行转码,就要使用babel-core模块
babel-cli:
一种使用方式就是全局安装:npm install -g babel-cli
(可以通过 npm root -g
查看全局包安装目录),
只要全局安装了 babel-cli
,则会在命令行中多出一个命令:babel
。
这里如果使用全局安装的 babel-cli
进行转码是没有问题的,但是问题是如果一旦项目给了别人,
别人不知道你使用了这个转码工具,所以解决方式就是将 babel-cli
安装到本地项目中:
npm install --save-dev babel-cli
这种第三方命令行工具如果安装到本地项目,会在 node_modules
中生成一个目录:.bin
,
然后第三方命令行工具会将对应的可执行文件放到该目录中。
这样的话,就可以直接在本地项目中使用该第三方命令行工具了。
对于如何使用,则可以通过配置 package.json
文件中的 scripts
字段来配置使用:
{
"name": "babel-demo",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "babel demo1.js"
},
"devDependencies": {
"babel-cli": "^6.22.2",
"babel-preset-es2015": "^6.22.0",
"babel-preset-react": "^6.22.0"
}
}
babel-register(适合开发阶段,实时编码转换):
第一:安装 babel-register
npm install --save-dev babel-register
第二:添加一个傀儡文件(main.js):
require('babel-register')
require('你的核心功能代码入口文件模块')
第三:使用 node 执行 main.js
,而不是你的入口文件.
--save 和 --save-dev
通过 --save
参数安装的包,是将依赖项保存到 package.json 文件中的 dependencies 选项中。
通过 --save-dev
参数安装的包,是将依赖项保存到 package.json 文件中的 devDependencies 选项中。
无论是 --save
或者 --save-dev
安装的包,通过执行 npm install
都会将对应的依赖包安装进来。
但是,在开发阶段会有一些仅仅用来辅助开发的一些第三方包或是工具,然后最终上线运行(到了生产环境),
这些开发依赖项就不再需要了,就可以通过 npm install --production
命令仅仅安装 dependencies
中的
依赖项。