node初探

204 阅读4分钟

前言

我们之前编写的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编写高性能的服务代码,让前端不仅仅停留在浏览器。所以是前端提升的必经之路。作为小白,要学习的还很多,感兴趣的朋友,官方文档是最好的学习资料。