Skip to content

Node.js 基础入门学习笔记

什么是 Node.js

Node.js 就是能在服务器跑 js 的环境,基于 V8 引擎。

特点:

  • 事件驱动,异步非阻塞
  • 单线程(主线程)
  • 跨平台
  • npm 生态很丰富

安装

用 nvm 装比较方便:

bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install --lts
nvm use --lts

验证:

bash
node --version
npm --version

第一个应用:

javascript
// app.js
console.log("Hello, Node.js!");
// node app.js

模块系统

CommonJS

导出:

javascript
// math.js
module.exports = {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b
};

导入:

javascript
const math = require('./math');
const { add } = require('./math');

ES6 模块

javascript
// math.mjs
export function add(a, b) {
  return a + b;
}

// main.mjs
import { add } from './math.mjs';

注意:ES6 模块要用 .mjs 扩展名,或者在 package.json 里设置 "type": "module"

核心模块

fs

javascript
const fs = require('fs');

// 同步
const data = fs.readFileSync('file.txt', 'utf8');

// 异步回调
fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) return console.error(err);
  console.log(data);
});

// Promise
const fsPromises = require('fs').promises;
const data = await fsPromises.readFile('file.txt', 'utf8');

path

javascript
const path = require('path');

path.join(__dirname, 'files', 'data.txt');
path.basename('/path/to/file.txt'); // file.txt
path.dirname('/path/to/file.txt');  // /path/to
path.extname('file.txt');           // .txt

http

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello');
});

server.listen(3000);

url

javascript
const url = require('url');
const parsed = url.parse('https://example.com/path?q=1', true);
// parsed.query = { q: '1' }

全局对象

process

javascript
process.env.NODE_ENV
process.argv        // 命令行参数
process.cwd()       // 当前目录
process.exit(0)     // 退出

__dirname 和 __filename

javascript
__dirname   // 当前文件目录
__filename  // 当前文件路径

注意:ES6 模块里没有这两个,要用 import.meta.url

事件循环

javascript
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// 输出:1, 4, 3, 2

事件循环的几个阶段:Timer -> Pending -> Poll -> Check -> Close

可读流

javascript
const readStream = fs.createReadStream('file.txt');
readStream.on('data', chunk => console.log(chunk));
readStream.on('end', () => console.log('完成'));

可写流

javascript
const writeStream = fs.createWriteStream('output.txt');
writeStream.write('data');
writeStream.end();

管道

javascript
readStream.pipe(writeStream);

错误处理

同步用 try/catch,异步用回调的 err 参数或者 Promise 的 catch。

javascript
// 同步
try {
  fs.readFileSync('file.txt');
} catch (err) {
  console.error(err);
}

// 异步
fs.readFile('file.txt', (err, data) => {
  if (err) return console.error(err);
  // ...
});

// Promise
try {
  const data = await fsPromises.readFile('file.txt');
} catch (err) {
  console.error(err);
}

未捕获的异常:

javascript
process.on('uncaughtException', err => {
  console.error(err);
  process.exit(1);
});

package.json

主要字段:

  • name, version, main
  • scripts
  • dependencies, devDependencies