「本文正在参与技术专题征文Node.js进阶之路,点击查看详情」
什么是 Node.js
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
Node.js 是支持所有 ECMAScript 语法规范的, 所以所有的 js 基础和高级语法都可以使用
JavaScript 运行环境
- 浏览器是
JavaScript客户端的运行环境 Node.js是JavaScript服务端的运行环境
Node 中的模块化
Node 中,规定每个 JS 文件都是一个小模块。一个项目由许许多多的小模块( JS 文件)组合而成。
模块化
什么是模块化
模块化,就是把一个大的文件拆分成若干小文件,而且还能把小文件通过特定的语法组合到一起的实现过程。
模块化优点
Node 中模块化的优势:
- 更利于维护
- 例 : 项目后期需要对某个模块(登录模块)进行修改, 其他模块不会受到影响
- 更好的复用性
- 例 : 公共的业务逻辑进行封装, 复用更加方便
Node 模块化规范
CommonJS : Node中的模块化使用的是CommonJS规范。
CommonJS 模块的特点
- 模块内的变量不会污染全局, 模块内的代码都运行在模块内的作用域
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 同步加载, 模块加载的顺序是同步加载,按照使用的顺序加载, 只有当前加载完成,才能执行后面的操作
CommonJS 使用模块的语法
- 通过
require函数进行导入const 模块名 = require('模块路径')
- 通过
export或者module.exports导出module.exports = {模块内的变量}
模块的分类
- 自定义模块
Node.JS中,创建的 js 文件都是自定义模块
- 内置模块( 又叫核心模块 )
Node.JS中, 自带的模块- 内置模块的导入语法:
const 模块名 = require('模块名')
- 第三方模块
- 下载第三方文件 , 导入后使用
自定义模块
Node.JS 中每个 JS 文件都是一个自定义模块,并且具有模块作用域,也就是在一个模块中创建的变量、常量、函数等等一切,都只能在当前模块中使用。
共享(导出/暴露)内容
共享内容给其他模块用,需要使用 module.exports 导出内容。
module是Node.JS中的一个全局对象,对象包含当前模块的详细信息。module.exports是模块的出口,就是导出内容用的,默认值是{}
代码实例
let age = 18
let name = '响响'
let fn = x => x
// 导出age、name、fn给其他模块使用
module.exports = { age, name, square }
使用自定义模块
如果需要使用上述模块导出的内容,可以使用 require() 加载(导入)
let 模块名 = require('模块路径')- 注意: 加载自定义模块,必须使用路径,不能省略前缀(例:
./)但是可以省略后缀(例:'.js')
代码实例
let 模块名 = require('上述文件路径')
console.log(模块名); // { age: 18, name: '响响', fn: X => X }
内置模块
内置模块是 Node.js 平台自带的 API (功能模块)。也叫做核心模块。
注意: 加载内置模块,不能写路径 , 直接使用模块名
常用的内置模块
- path 模块 : 路径处理模块
- fs 模块 : 文件处理模块
- querystring模块 : 查询字符串处理模块
- http模块 : http服务器处理模块
1 . path 模块
path 是 Node 本身提供的 API,专门用来处理路径。
使用方法
- 加载模块
let path = require('path')
path模块中的方法
path.basename(参数1,参数2): 返回 path 的最后一部分(文件名)- 第一参数是路径, 第二个参数是扩展名
- 传一个参数, 返回
文件名.扩展名 - 传两个参数, 返回
文件名
path.dirname(路径): 返回目录名path.extname(路径): 返回路径中文件的扩展名(包含.)
// extname -- 获取文件后缀
console.log(path.extname('index.html')); // .html
console.log(path.extname('index.coffee.md')); // .md
path.format(对象): 将一个对象格式化为一个路径字符串path.join(__dirname,文件路径): 拼接路径__dirname动态获取文件所在文件夹(业务中常用)__filename动态获取文件位置
path.parse(路径): 把路径字符串解析成对象的格式
// join -- 智能拼接路径
// console.log(path.join('a', 'b', 'c')); // a/b/c
// console.log(path.join('a', 'b', 'c', 'index.css')); // a/b/c/index.css
// a里面有b,b里面有../c,言外之意,c和b同级。
// console.log(path.join('a', 'b', '../c', 'index.js')); // a/c/index.js
// __dirname 永远表示当前js文件的绝对路径
console.log(path.join(__dirname, 'css', 'demo.css')); // /Users/code/css/demo.css
2 . fs 模块
fs (file system) : 文件系统模块 , 可以实现对 文件、文件夹的操作
fs模块的方法
fs.readFile: 读取文件的方法, 异步操作fs.readFile('文件路径', '编码集', (err, data)=>{}}- 读取失败
err为对象,data是undefined; - 读取成功
err为null,data是读取到的字符串; - 所有的错误对象都有两个属性: name 和 message (错误信息)
- 注意点:
- 错误优先原则
err参数在前面 - 纯文本一般设置编码集,但是如果是 图片/音频/视频... 特定的软件,用的定方式打开
- 错误优先原则
fs.writeFile: 写入文件内容, 写入方法也是异步fs.writeFile('文件路径', '我是刚刚写入的内容', err => {})- 写入成功,
err为null; 写入失败,err为错误对象; - 注意 :
- 文件不存才会创建文件,文件存在会覆盖原有内容 (
appendFile不会覆盖,会追加) - 文件夹如果不存在就报错!
- 文件不存才会创建文件,文件存在会覆盖原有内容 (
fs.appendFile: 写入文件内容 , 不会覆盖原有内容fs.appendFile('文件路径', '我是刚刚写入的内容', err => {})
fs.access: 判断一个文件是否存在/可读/可写fs.access('文件路径', 参数2, err => {})- 参数2可选;
fs.constants.F_OK: 或不填,表示判断文件是否存在;fs.constants.R_OK: 表示判断文件是否可读;fs.constants.W_OK: 表示文件是否可写
err是对象,就说明文件不存在;err是null,就说明文件存在;
querystring模块
查询字符串处理模块
3 . querystring 模块两个方法
querystring.parse: 字符串转换为对象, 自带解码
// parse -- 将查询字符串解析成JS对象
console.log(querystring.parse('id=1&name=zs&age=20'))
// { id: '1', name: 'zs', age: '20' }
querystring.stringify: 转换为字符串, 自带编码
// stringify -- 将JS对象转成查询字符串
console.log(querystring.stringify({ id: '1', name: 'zs', age: '20' }));
// id=1&name=zs&age=20
4 . http 模块
http是一个系统模块,让我们能够通过简单的流程创建一个 Web 服务器
使用http模块搭建Web服务器
创建 Web 服务器的步骤
- 导入 http 核心模块
- 创建 server 对象(server 对象负责建立连接,接收数据)
- 注册 request 事件,当浏览器发送请求到服务器执行,设置处理请求的函数
- 监听端口(==这个步骤也可以放到注册request事件之前==)
- 当服务器接收到浏览器的请求后,如果没有做出响应,浏览器会等待
- 服务器的最终目的是要根据请求做出响应,肯定要调用 res.end() 方法。
// 导入 http 模块
const http = require('http');
// 创建一个服务器对象
const server = http.createServer();
// 监听事件
server.on('request', (request, response) => {
// 响应给客户端信息 - 别用标签和汉字
response.end('hello Mr Lv!');
})
// 启动服务
server.listen(8888, () => {
console.log('程序已经启动,请访问: http://127.0.0.1:8888 ');
});
request(req) 和 response(res) 参数
上述代码的格式基本固定。只有 请求事件 的处理函数需要说明一下。
当收到浏览器的请求后,会触发request事件,事件处理函数有两个形式参数 request 和 response。
server.on('request', (request, response) => {
// 设置响应状态码
response.statusCode = 200;
// 设置响应头
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
// 设置响应体
response.end('hello,欢迎访问服务器,这是服务器给你的回应');
});
-
形参 request
- 通过
request对象,可以获取到 请求相关信息。 request.url获取请求行中的路径request.method获取请求行中的请求方法request.headers获取请求头
- 通过
-
形参 response
- 做出响应,需要使用
response对象。 statusCode设置响应状态码,必须在end方法前调用。response.setHeader()设置响应头,比如设置响应体的编码,必须在end方法前调用。response.end()把响应报文(响应行、响应头、响应体)发送给浏览器,通俗的讲就是做出响应。end()调用,表示做出响应end()调用后,不能再设置响应状态码和响应头end()的参数表示响应结果;只能填字符串。
- 做出响应,需要使用