前言
我们之前编写的JavaScript都是在浏览器中运行的,所以我们可以直接在浏览器里面写代码,直接运行。那么问题来了,除了浏览器,我们编写的JavaScript代码还能在什么环境下运行呢?
我们编写的JavaScript代码可以在node环境下运行。也就是说,我们的JavaScript代码直接在你的计算机上以命令行的方式运行。因此我们要用文本编辑器编写我们的代码,并且把我们的代码保存到本地硬盘的某个目录下,才能运行。
node模式
命令行模式
我们可以在本地的某个目录下执行某个js文件。例如:
// he.js
'use strict'
console.log('hello')
执行这个he.js文件,会直接运行这个js文件,输出在控制台:

node交互模式
除了上面的命令行模式,我们还可以通过node命令进入node交互模式,直接写代码运行。例如:

运行和调试JavaScript
配置launch.json,可以通过debug自动生成launch.json文件。有了配置文件,我们就可使用VS Code调试JavaScript了。
// launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/he.js"
}
]
}
模块(module)
为了编写可维护的代码,我们需要对函数代码进行分组,在node.js里面一个js文件就是一个模块(module)。
首先我们来编写一个模块:
// he.js
'use strict'
const text = 'hello';
function greet(name){
console.log(`${text} ${name}`)
}
module.exports = greet;
如上,我们一般就称之为he模块。可以在其他文件中引入该模块。
// main.js
'use strict';
// 引入hello模块:
var greet = require('./hello');
var s = 'Michael';
greet(s); // Hello, Michael!
基本模块
fs模块 —— 文件系统模块
fs模块是node内置的文件系统模块,负责文件的读写。fs模块同时提供了同步和异步的方法。
- 异步读模块
// fs_read.js
'use strict'
const fs = require('fs');
fs.readFile('testfs.txt', 'utf-8', (err, data) => {
if(err){
console.log(err)
}else{
console.log(data)
}
})
注意:
* 必须是utf-8模式。
* 读取的时候传入两个参数,一个err,一个data。当正常读取的时候err为null,data参数为读取到的内容。
如果我们读取的不是一个文本文件,而是二进制文件,例如一个图片,怎么办呢?
'use strict'
const fs = require('fs');
fs.readFile('tree-shaking.png',(err, data) => {
if(err){
console.log(err)
}else{
console.log(data)
console.log(`${data.length} bytes`)
}
})

如上,当读取二进制文件时,不传入文件编码,回调函数的data参数将返回一个Buffer对象,在Node.js中,Buffer对象就是一个包含零个或者任意个字节的数组。
Buffer对象可以和String做转换。
data.toString('utf-8')
Buffer.from(text, 'utf-8');
- 同步读模块 除了异步读取文件以外,fs也提供了同步读取文件的方法。
'use strict'
const fs = require('fs');
const data = fs.readFileSync('testfs.txt', 'utf-8');
console.log(data)
同步读取文件多了个Sync后缀,并且没有回调函数。如果同步读取函数发生错误,我们需要用try....cattch捕获。
try {
var data = fs.readFileSync('testfs.txt', 'utf-8');
console.log(data);
} catch (err) {
// 出错了
}
- 写文件 fs中也有写文件的函数fs.writeFile()。
'use strict'
const fs = require('fs');
fs.writeFile('testfs.txt', 'node', 'utf-8', () => {
console.log('aa')
})
当然也有同步写文件的函数。
fs.writeFileSync('testfs.txt', 'node111', {encoding: 'utf-8'})
除了读写文件,我们常用的还会有stats类。
- stats
fs.stats类用来获取文件信息。文件大小和创建时间等信息。
stream模块 —— 流
流(stream)是Node.js中处理流式数据的抽象接口。流式可读的,可写的,或者是可读可写的。所有的流都是EventEmitter的实例。
-
流的类型
Node.js中有四种基本流的类型:
- writable —— 可写入数据的流(fs.createWriteStream())
- readable —— 可读数据的流(fs.createReadStream())
- Duplex —— 可写又可读的流(net.Socket())
- Transform —— 在读写的过程中可转换修改的Duplex流(zlib.createDeflate)
-
以流的形式读取文件
'use strict'
const fs = require('fs');
const rs = fs.createReadStream('testfs.txt', 'utf-8');
rs.on('data', (chunk) => {
console.log('-------')
console.log(chunk)
})
rs.on('end', () => {
console.log('end')
})
- 以流的形式写入文件
'use strict'
const fs = require('fs');
const ws = fs.createWriteStream('testfs.txt', 'utf-8');
ws.write('1111 \n')
ws.write('2222')
ws.write('333')
ws.end()
- pipe pipe是把两个流串起来。就像两个水管一样。一个Readable流和一个Writeable流串起来。就是从一个文件里读出然后写入另一个文件。相当于一个复制的过程。
'use strict'
const fs = require('fs');
const rs = fs.createReadStream('testfs.txt', 'utf-8');
const ws = fs.createWriteStream('test.txt', 'utf-8');
rs.pipe(ws)
http模块
Node.js开发的目的就是用JavaScript代码编写服务端程序。我们不用开发Http服务器,从头开始处理Tcp连接,解析http请求。Node.js的http模块已经帮我们处理好了。应用程序不直接跟http服务器打交道。而是操作http模块提供的resquest和response对象。
- resquest对象 resquest对象封装了http请求。我们调用resquest对象的属性和方法就可以拿到所有的请求信息。
- response对象 response对象封装了http响应。我们调用response对象,就可以把响应返回给浏览器。
- 实现一个Http服务器
const http = require('http');
const server = http.createServer((req, res) => {
console.log(req.method)
console.log(req.url)
res.writeHead(200, {'Content-Type': 'text/html'})
res.end('<h1> hello server </h1>')
})
server.listen(8080)
console.log('Server is running at http://127.0.0.1:8080/')
控制台输出:


- 文件服务器 文件服务器需要用到Node.js的path模块。path模块是对路径的处理,可以获取目录地址和拼接地址。
const path = require('path');
// 解析当前目录
const workDir = path.resolve('.');
const filePath = path.join(workDir, 'pub', 'index.html')
console.log(workDir)
console.log(filePath)
总结: Node.js可以通过JavaScript编写高性能的服务代码,让前端不仅仅停留在浏览器。所以是前端提升的必经之路。作为小白,要学习的还很多,感兴趣的朋友,官方文档是最好的学习资料。