最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node.js完全指南:從入門到精通

 更新時(shí)間:2018年05月16日 14:37:03   作者:迷失的蝸牛  
本文介紹了Node.js的基礎(chǔ)概念、安裝配置、模塊系統(tǒng)、NPM包管理、Express框架、數(shù)據(jù)庫操作、RESTful API實(shí)戰(zhàn)、最佳實(shí)踐和部署運(yùn)維等內(nèi)容,重點(diǎn)講解了Node.js的特點(diǎn)、應(yīng)用場景及開發(fā)流程,并提供了實(shí)踐項(xiàng)目示例,適合初學(xué)者快速入門Node.js,掌握其核心技術(shù)和開發(fā)方法

一、Node.js基礎(chǔ)概念

1.1 什么是Node.js?

Node.js是一個(gè)基于Chrome V8引擎的JavaScript運(yùn)行環(huán)境,讓JavaScript可以在服務(wù)器端運(yùn)行。它使用事件驅(qū)動(dòng)、非阻塞I/O模型,使其輕量且高效。

1.2 Node.js的歷史

  • 2009年:Ryan Dahl創(chuàng)建了Node.js
  • 2010年:NPM(Node Package Manager)誕生
  • 2011年:npm 1.0發(fā)布
  • 2015年:Node.js基金會(huì)成立
  • 2016年:引入長期支持(LTS)版本
  • 至今:持續(xù)快速發(fā)展,廣泛應(yīng)用于后端開發(fā)

1.3 Node.js的特點(diǎn)

  • 單線程:使用單線程事件循環(huán),避免線程切換開銷
  • 異步非阻塞I/O:提高并發(fā)處理能力
  • 跨平臺(tái):可在Windows、Linux、Mac上運(yùn)行
  • NPM生態(tài):擁有世界上最龐大的開源庫生態(tài)系統(tǒng)
  • JavaScript全棧:前后端統(tǒng)一語言,降低開發(fā)成本

1.4 Node.js的應(yīng)用場景

  • Web應(yīng)用:RESTful API、GraphQL服務(wù)
  • 實(shí)時(shí)應(yīng)用:聊天應(yīng)用、實(shí)時(shí)協(xié)作工具
  • 微服務(wù):構(gòu)建分布式系統(tǒng)
  • CLI工具:命令行工具開發(fā)
  • 數(shù)據(jù)流:處理大量數(shù)據(jù)
  • 物聯(lián)網(wǎng):IoT設(shè)備數(shù)據(jù)處理

二、Node.js安裝和環(huán)境配置

2.1 安裝Node.js

Windows系統(tǒng)

  • 訪問Node.js官網(wǎng):https://nodejs.org/
  • 下載LTS版本(推薦)或Current版本
  • 運(yùn)行安裝程序,按提示完成安裝
  • 驗(yàn)證安裝:
node --version
npm --version

Linux系統(tǒng)

# 使用包管理器安裝
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install nodejs npm
# CentOS/RHEL
sudo yum install nodejs npm
# 使用NVM安裝(推薦)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install --lts
nvm use --lts

Mac系統(tǒng)

# 使用Homebrew安裝
brew install node
# 使用NVM安裝
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install --lts

2.2 版本管理

使用NVM(Node Version Manager)

# 安裝NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 查看可用版本
nvm list-remote
# 安裝特定版本
nvm install 16.14.0
# 使用特定版本
nvm use 16.14.0
# 設(shè)置默認(rèn)版本
nvm alias default 16.14.0
# 查看已安裝版本
nvm list
# 卸載版本
nvm uninstall 16.14.0

使用n(簡單版本管理器)

# 安裝n
npm install -g n
# 安裝最新LTS版本
n lts
# 安裝最新版本
n latest
# 安裝特定版本
n 16.14.0
# 切換版本
n
# 查看已安裝版本
n ls

2.3 環(huán)境變量配置

# Windows系統(tǒng)
# 系統(tǒng)環(huán)境變量中添加:
# NODE_PATH = C:\Users\YourName\AppData\Roaming\npm\node_modules
# PATH = %NODE_PATH%;C:\Program Files\nodejs
# Linux/Mac系統(tǒng)
# 在 ~/.bashrc 或 ~/.zshrc 中添加:
export NODE_PATH=/usr/local/lib/node_modules
export PATH=$PATH:/usr/local/bin
# 重新加載配置
source ~/.bashrc

2.4 創(chuàng)建第一個(gè)Node.js應(yīng)用

// hello.js
console.log('Hello, Node.js!');
// 運(yùn)行
node hello.js
// http-server.js
const http = require('http');
const server = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello, Node.js!');
});
server.listen(3000, () => {
    console.log('Server running at http://localhost:3000/');
});
// 運(yùn)行
node http-server.js

三、模塊系統(tǒng)

3.1 CommonJS模塊系統(tǒng)

導(dǎo)出模塊

// math.js
// 方式1:導(dǎo)出單個(gè)值
module.exports = {
    add: function(a, b) {
        return a + b;
    },
    subtract: function(a, b) {
        return a - b;
    }
};
// 方式2:導(dǎo)出多個(gè)值
exports.add = function(a, b) {
    return a + b;
};
exports.subtract = function(a, b) {
    return a - b;
};
// 方式3:導(dǎo)出類
class Calculator {
    add(a, b) {
        return a + b;
    }
}
module.exports = Calculator;

導(dǎo)入模塊

// app.js
// 方式1:導(dǎo)入整個(gè)模塊
const math = require('./math');
console.log(math.add(1, 2)); // 3
// 方式2:解構(gòu)導(dǎo)入
const { add, subtract } = require('./math');
console.log(add(1, 2)); // 3
// 方式3:導(dǎo)入類
const Calculator = require('./math');
const calc = new Calculator();
console.log(calc.add(1, 2)); // 3

3.2 ES6模塊系統(tǒng)

啟用ES6模塊

// package.json
{
  "type": "module"
}

導(dǎo)出模塊

// math.mjs
// 方式1:命名導(dǎo)出
export function add(a, b) {
    return a + b;
}
export function subtract(a, b) {
    return a - b;
}
// 方式2:默認(rèn)導(dǎo)出
export default class Calculator {
    add(a, b) {
        return a + b;
    }
}
// 方式3:混合導(dǎo)出
export const PI = 3.14159;
export function multiply(a, b) {
    return a * b;
}

導(dǎo)入模塊

// app.mjs
// 方式1:導(dǎo)入命名導(dǎo)出
import { add, subtract } from './math.mjs';
console.log(add(1, 2)); // 3
// 方式2:導(dǎo)入默認(rèn)導(dǎo)出
import Calculator from './math.mjs';
const calc = new Calculator();
console.log(calc.add(1, 2)); // 3
// 方式3:導(dǎo)入所有
import * as math from './math.mjs';
console.log(math.add(1, 2)); // 3
// 方式4:動(dòng)態(tài)導(dǎo)入
const module = await import('./math.mjs');
console.log(module.add(1, 2)); // 3

3.3 核心模塊

1. fs(文件系統(tǒng))

const fs = require('fs');
const path = require('path');
// 同步讀取文件
try {
    const data = fs.readFileSync('input.txt', 'utf8');
    console.log(data);
} catch (error) {
    console.error('讀取文件失敗:', error);
}
// 異步讀取文件(推薦)
fs.readFile('input.txt', 'utf8', (error, data) => {
    if (error) {
        console.error('讀取文件失敗:', error);
        return;
    }
    console.log(data);
});
// 使用Promise
const fsPromises = require('fs').promises;
async function readFileAsync() {
    try {
        const data = await fsPromises.readFile('input.txt', 'utf8');
        console.log(data);
    } catch (error) {
        console.error('讀取文件失敗:', error);
    }
}
// 寫入文件
fs.writeFile('output.txt', 'Hello, Node.js!', 'utf8', (error) => {
    if (error) {
        console.error('寫入文件失敗:', error);
        return;
    }
    console.log('文件寫入成功');
});
// 追加內(nèi)容
fs.appendFile('output.txt', '\n追加的內(nèi)容', 'utf8', (error) => {
    if (error) {
        console.error('追加內(nèi)容失敗:', error);
        return;
    }
    console.log('內(nèi)容追加成功');
});
// 刪除文件
fs.unlink('output.txt', (error) => {
    if (error) {
        console.error('刪除文件失敗:', error);
        return;
    }
    console.log('文件刪除成功');
});
// 創(chuàng)建目錄
fs.mkdir('newdir', { recursive: true }, (error) => {
    if (error) {
        console.error('創(chuàng)建目錄失敗:', error);
        return;
    }
    console.log('目錄創(chuàng)建成功');
});
// 讀取目錄
fs.readdir('.', (error, files) => {
    if (error) {
        console.error('讀取目錄失敗:', error);
        return;
    }
    console.log('目錄內(nèi)容:', files);
});
// 檢查文件是否存在
fs.access('input.txt', fs.constants.F_OK, (error) => {
    if (error) {
        console.log('文件不存在');
    } else {
        console.log('文件存在');
    }
});
// 獲取文件信息
fs.stat('input.txt', (error, stats) => {
    if (error) {
        console.error('獲取文件信息失敗:', error);
        return;
    }
    console.log('文件信息:', stats);
    console.log('是否為文件:', stats.isFile());
    console.log('是否為目錄:', stats.isDirectory());
    console.log('文件大小:', stats.size);
});
// 路徑操作
const filePath = path.join(__dirname, 'files', 'input.txt');
console.log('文件路徑:', filePath);
console.log('文件名:', path.basename(filePath));
console.log('目錄名:', path.dirname(filePath));
console.log('擴(kuò)展名:', path.extname(filePath));
console.log('絕對路徑:', path.resolve(filePath));

2. http(HTTP服務(wù)器)

const http = require('http');
const url = require('url');
const querystring = require('querystring');
// 創(chuàng)建簡單的HTTP服務(wù)器
const server = http.createServer((req, res) => {
    // 處理CORS
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
    // 處理OPTIONS請求
    if (req.method === 'OPTIONS') {
        res.writeHead(200);
        res.end();
        return;
    }
    // 解析URL
    const parsedUrl = url.parse(req.url, true);
    const pathname = parsedUrl.pathname;
    const query = parsedUrl.query;
    console.log(`收到請求: ${req.method} ${pathname}`);
    // 路由處理
    if (pathname === '/') {
        res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
        res.end(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>Node.js HTTP服務(wù)器</title>
            </head>
            <body>
                <h1>歡迎使用Node.js HTTP服務(wù)器</h1>
                <p>當(dāng)前路徑: ${pathname}</p>
            </body>
            </html>
        `);
    } else if (pathname === '/api/data') {
        // JSON響應(yīng)
        const data = {
            message: '成功',
            data: [1, 2, 3, 4, 5]
        };
        res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
        res.end(JSON.stringify(data));
    } else {
        // 404頁面
        res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
        res.end(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>404 Not Found</title>
            </head>
            <body>
                <h1>404 - 頁面不存在</h1>
                <p>您訪問的頁面不存在: ${pathname}</p>
            </body>
            </html>
        `);
    }
});
server.listen(3000, () => {
    console.log('服務(wù)器運(yùn)行在 http://localhost:3000/');
});
// 處理POST請求
const server2 = http.createServer((req, res) => {
    if (req.method === 'POST' && req.url === '/api/login') {
        let body = '';
        req.on('data', chunk => {
            body += chunk.toString();
        });
        req.on('end', () => {
            try {
                const data = JSON.parse(body);
                console.log('接收到的數(shù)據(jù):', data);
                res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({
                    success: true,
                    message: '登錄成功',
                    user: data
                }));
            } catch (error) {
                res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
                res.end(JSON.stringify({
                    success: false,
                    message: '數(shù)據(jù)格式錯(cuò)誤'
                }));
            }
        });
    } else {
        res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' });
        res.end('404 Not Found');
    }
});
server2.listen(3001, () => {
    console.log('POST服務(wù)器運(yùn)行在 http://localhost:3001/');
});

3. path(路徑處理)

const path = require('path');
// 路徑拼接
const fullPath = path.join(__dirname, 'files', 'data.txt');
console.log('完整路徑:', fullPath);
// 路徑解析
const parsed = path.parse('/path/to/file.txt');
console.log('路徑解析:', parsed);
// {
//   root: '/',
//   dir: '/path/to',
//   base: 'file.txt',
//   ext: '.txt',
//   name: 'file'
// }
// 獲取文件名
console.log('文件名:', path.basename('/path/to/file.txt')); // file.txt
console.log('不含擴(kuò)展名的文件名:', path.basename('/path/to/file.txt', '.txt')); // file
// 獲取目錄名
console.log('目錄名:', path.dirname('/path/to/file.txt')); // /path/to
// 獲取擴(kuò)展名
console.log('擴(kuò)展名:', path.extname('/path/to/file.txt')); // .txt
// 獲取絕對路徑
console.log('絕對路徑:', path.resolve('files/data.txt'));
// 規(guī)范化路徑
console.log('規(guī)范化路徑:', path.normalize('/path/to/../to/./file.txt')); // /path/to/file.txt
// 判斷是否為絕對路徑
console.log('是否為絕對路徑:', path.isAbsolute('/path/to/file.txt')); // true
console.log('是否為絕對路徑:', path.isAbsolute('files/data.txt')); // false
// 獲取當(dāng)前工作目錄
console.log('當(dāng)前工作目錄:', process.cwd());
console.log('__dirname:', __dirname);
console.log('__filename:', __filename);

4. events(事件處理)

const EventEmitter = require('events');
// 創(chuàng)建事件發(fā)射器
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// 監(jiān)聽事件
myEmitter.on('event', () => {
    console.log('事件觸發(fā)!');
});
// 觸發(fā)事件
myEmitter.emit('event');
// 帶參數(shù)的事件
myEmitter.on('data', (data) => {
    console.log('收到數(shù)據(jù):', data);
});
myEmitter.emit('data', { name: '張三', age: 25 });
// 只觸發(fā)一次的事件
myEmitter.once('once', () => {
    console.log('這個(gè)事件只會(huì)觸發(fā)一次');
});
myEmitter.emit('once');
myEmitter.emit('once'); // 不會(huì)觸發(fā)
// 錯(cuò)誤處理
myEmitter.on('error', (error) => {
    console.error('發(fā)生錯(cuò)誤:', error.message);
});
myEmitter.emit('error', new Error('這是一個(gè)錯(cuò)誤'));
// 移除事件監(jiān)聽器
const handler = () => {
    console.log('這個(gè)監(jiān)聽器會(huì)被移除');
};
myEmitter.on('remove', handler);
myEmitter.emit('remove');
myEmitter.removeListener('remove', handler);
myEmitter.emit('remove'); // 不會(huì)觸發(fā)
// 獲取監(jiān)聽器數(shù)量
console.log('監(jiān)聽器數(shù)量:', myEmitter.listenerCount('event'));
// 獲取所有監(jiān)聽器
console.log('所有監(jiān)聽器:', myEmitter.listeners('event'));

5. stream(流處理)

const fs = require('fs');
const { Transform } = require('stream');
// 讀取流
const readStream = fs.createReadStream('input.txt', 'utf8');
readStream.on('data', (chunk) => {
    console.log('讀取數(shù)據(jù)塊:', chunk);
});
readStream.on('end', () => {
    console.log('讀取完成');
});
readStream.on('error', (error) => {
    console.error('讀取錯(cuò)誤:', error);
});
// 寫入流
const writeStream = fs.createWriteStream('output.txt', 'utf8');
writeStream.write('Hello, ');
writeStream.write('Node.js!\n');
writeStream.end('結(jié)束寫入');
writeStream.on('finish', () => {
    console.log('寫入完成');
});
writeStream.on('error', (error) => {
    console.error('寫入錯(cuò)誤:', error);
});
// 管道流(復(fù)制文件)
const readStream2 = fs.createReadStream('input.txt');
const writeStream2 = fs.createWriteStream('output.txt');
readStream2.pipe(writeStream2);
readStream2.on('end', () => {
    console.log('文件復(fù)制完成');
});
// 轉(zhuǎn)換流(大寫轉(zhuǎn)換)
const upperCaseTransform = new Transform({
    transform(chunk, encoding, callback) {
        this.push(chunk.toString().toUpperCase());
        callback();
    }
});
fs.createReadStream('input.txt')
    .pipe(upperCaseTransform)
    .pipe(fs.createWriteStream('uppercase.txt'));
// 壓縮流
const zlib = require('zlib');
const gzip = zlib.createGzip();
fs.createReadStream('input.txt')
    .pipe(gzip)
    .pipe(fs.createWriteStream('input.txt.gz'));
// 解壓流
const gunzip = zlib.createGunzip();
fs.createReadStream('input.txt.gz')
    .pipe(gunzip)
    .pipe(fs.createWriteStream('uncompressed.txt'));

6. crypto(加密)

const crypto = require('crypto');
// MD5哈希
const hash1 = crypto.createHash('md5').update('Hello, Node.js!').digest('hex');
console.log('MD5:', hash1);
// SHA256哈希
const hash2 = crypto.createHash('sha256').update('Hello, Node.js!').digest('hex');
console.log('SHA256:', hash2);
// HMAC
const hmac = crypto.createHmac('sha256', 'secret-key');
hmac.update('Hello, Node.js!');
console.log('HMAC:', hmac.digest('hex'));
// AES加密
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
function encrypt(text) {
    const cipher = crypto.createCipheriv(algorithm, key, iv);
    let encrypted = cipher.update(text, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    return encrypted;
}
function decrypt(encrypted) {
    const decipher = crypto.createDecipheriv(algorithm, key, iv);
    let decrypted = decipher.update(encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}
const original = 'Hello, Node.js!';
const encrypted = encrypt(original);
const decrypted = decrypt(encrypted);
console.log('原文:', original);
console.log('加密:', encrypted);
console.log('解密:', decrypted);
// 生成隨機(jī)數(shù)
const randomBytes = crypto.randomBytes(16).toString('hex');
console.log('隨機(jī)數(shù):', randomBytes);
// 生成UUID
function generateUUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        const r = Math.random() * 16 | 0;
        const v = c === 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
}
console.log('UUID:', generateUUID());

四、NPM包管理

4.1 NPM基礎(chǔ)命令

# 初始化項(xiàng)目
npm init
# 初始化項(xiàng)目(使用默認(rèn)配置)
npm init -y
# 安裝依賴
npm install
# 安裝指定包
npm install package-name
# 安裝到生產(chǎn)環(huán)境
npm install package-name --save
# 安裝到開發(fā)環(huán)境
npm install package-name --save-dev
# 全局安裝
npm install -g package-name
# 卸載包
npm uninstall package-name
# 更新包
npm update package-name
# 查看已安裝的包
npm list
# 查看全局安裝的包
npm list -g
# 查看包信息
npm info package-name
# 搜索包
npm search package-name
# 查看過期的包
npm outdated
# 清理緩存
npm cache clean --force

4.2 package.json詳解

{
  "name": "my-nodejs-app",
  "version": "1.0.0",
  "description": "我的Node.js應(yīng)用",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "jest",
    "build": "webpack --mode production"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.0.3",
    "dotenv": "^16.0.3"
  },
  "devDependencies": {
    "nodemon": "^2.0.22",
    "jest": "^29.5.0",
    "webpack": "^5.82.1"
  },
  "engines": {
    "node": ">=16.0.0",
    "npm": ">=8.0.0"
  },
  "author": "張三",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/username/repo.git"
  },
  "keywords": ["nodejs", "express", "api"]
}

4.3 常用NPM包

express - Web框架

npm install express
const express = require('express');
const app = express();
// 中間件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 路由
app.get('/', (req, res) => {
    res.send('Hello, Express!');
});
app.get('/api/users', (req, res) => {
    res.json([
        { id: 1, name: '張三' },
        { id: 2, name: '李四' }
    ]);
});
app.post('/api/users', (req, res) => {
    const user = req.body;
    user.id = Date.now();
    res.status(201).json(user);
});
app.listen(3000, () => {
    console.log('Express服務(wù)器運(yùn)行在 http://localhost:3000');
});

nodemon - 自動(dòng)重啟

npm install -D nodemon
{
  "scripts": {
    "dev": "nodemon index.js"
  }
}

dotenv - 環(huán)境變量

npm install dotenv
// .env
PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASS=password
// index.js
require('dotenv').config();
const port = process.env.PORT || 3000;
console.log('服務(wù)器端口:', port);

axios - HTTP客戶端

npm install axios
const axios = require('axios');
// GET請求
async function getData() {
    try {
        const response = await axios.get('https://api.example.com/data');
        console.log(response.data);
    } catch (error) {
        console.error('請求失敗:', error);
    }
}
// POST請求
async function postData() {
    try {
        const response = await axios.post('https://api.example.com/users', {
            name: '張三',
            age: 25
        });
        console.log(response.data);
    } catch (error) {
        console.error('請求失敗:', error);
    }
}

mongoose - MongoDB ODM

npm install mongoose
const mongoose = require('mongoose');
// 連接數(shù)據(jù)庫
mongoose.connect('mongodb://localhost:27017/mydatabase', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});
// 定義模型
const UserSchema = new mongoose.Schema({
    name: { type: String, required: true },
    age: { type: Number, required: true },
    email: { type: String, required: true, unique: true }
});
const User = mongoose.model('User', UserSchema);
// 創(chuàng)建用戶
async function createUser() {
    const user = new User({
        name: '張三',
        age: 25,
        email: 'zhangsan@example.com'
    });
    await user.save();
    console.log('用戶創(chuàng)建成功:', user);
}
// 查詢用戶
async function findUsers() {
    const users = await User.find({ age: { $gte: 20 } });
    console.log('查詢結(jié)果:', users);
}
// 更新用戶
async function updateUser(id) {
    const user = await User.findByIdAndUpdate(
        id,
        { age: 26 },
        { new: true }
    );
    console.log('用戶更新成功:', user);
}
// 刪除用戶
async function deleteUser(id) {
    await User.findByIdAndDelete(id);
    console.log('用戶刪除成功');
}

五、Express框架詳解

5.1 Express基礎(chǔ)

const express = require('express');
const app = express();
// 中間件配置
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
// 路由
app.get('/', (req, res) => {
    res.send('Hello, Express!');
});
app.get('/about', (req, res) => {
    res.send('關(guān)于我們');
});
// 路由參數(shù)
app.get('/users/:id', (req, res) => {
    const userId = req.params.id;
    res.send(`用戶ID: ${userId}`);
});
// 查詢參數(shù)
app.get('/search', (req, res) => {
    const keyword = req.query.keyword;
    res.send(`搜索關(guān)鍵詞: ${keyword}`);
});
// POST請求
app.post('/users', (req, res) => {
    const user = req.body;
    res.status(201).json(user);
});
// 啟動(dòng)服務(wù)器
app.listen(3000, () => {
    console.log('服務(wù)器運(yùn)行在 http://localhost:3000');
});

5.2 路由器

const express = require('express');
const router = express.Router();
// 用戶路由
router.get('/', (req, res) => {
    res.json([
        { id: 1, name: '張三' },
        { id: 2, name: '李四' }
    ]);
});
router.get('/:id', (req, res) => {
    const userId = req.params.id;
    res.json({ id: userId, name: '張三' });
});
router.post('/', (req, res) => {
    const user = req.body;
    user.id = Date.now();
    res.status(201).json(user);
});
router.put('/:id', (req, res) => {
    const userId = req.params.id;
    const user = req.body;
    res.json({ id: userId, ...user });
});
router.delete('/:id', (req, res) => {
    const userId = req.params.id;
    res.json({ message: `用戶${userId}已刪除` });
});
module.exports = router;
// 在主應(yīng)用中使用
const userRoutes = require('./routes/users');
app.use('/api/users', userRoutes);

5.3 中間件

// 日志中間件
const logger = (req, res, next) => {
    console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
    next();
};
// 認(rèn)證中間件
const auth = (req, res, next) => {
    const token = req.headers.authorization;
    if (!token) {
        return res.status(401).json({ message: '未授權(quán)' });
    }
    // 驗(yàn)證token
    next();
};
// 錯(cuò)誤處理中間件
const errorHandler = (err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({ message: '服務(wù)器錯(cuò)誤' });
};
// 使用中間件
app.use(logger);
app.use('/api/protected', auth);
// 錯(cuò)誤處理
app.use(errorHandler);

5.4 模板引擎

// 安裝EJS
npm install ejs
// 配置模板引擎
app.set('view engine', 'ejs');
app.set('views', './views');
// 渲染模板
app.get('/', (req, res) => {
    res.render('index', {
        title: '我的網(wǎng)站',
        users: [
            { name: '張三', age: 25 },
            { name: '李四', age: 30 }
        ]
    });
});
// views/index.ejs
<!DOCTYPE html>
<html>
<head>
    <title><%= title %></title>
</head>
<body>
    <h1><%= title %></h1>
    <ul>
        <% users.forEach(user => { %>
            <li><%= user.name %> - <%= user.age %>歲</li>
        <% }) %>
    </ul>
</body>
</html>

六、數(shù)據(jù)庫操作

6.1 MongoDB

const mongoose = require('mongoose');
// 連接數(shù)據(jù)庫
mongoose.connect('mongodb://localhost:27017/myapp');
// 定義Schema
const userSchema = new mongoose.Schema({
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true },
    age: { type: Number, default: 0 },
    createdAt: { type: Date, default: Date.now }
});
// 創(chuàng)建Model
const User = mongoose.model('User', userSchema);
// CRUD操作
// 創(chuàng)建
async function createUser() {
    const user = new User({
        name: '張三',
        email: 'zhangsan@example.com',
        age: 25
    });
    await user.save();
    return user;
}
// 讀取
async function getUsers() {
    const users = await User.find({ age: { $gte: 18 } })
        .sort({ age: -1 })
        .limit(10);
    return users;
}
async function getUserById(id) {
    const user = await User.findById(id);
    return user;
}
// 更新
async function updateUser(id, updates) {
    const user = await User.findByIdAndUpdate(
        id,
        updates,
        { new: true, runValidators: true }
    );
    return user;
}
// 刪除
async function deleteUser(id) {
    await User.findByIdAndDelete(id);
}

6.2 MySQL

const mysql = require('mysql2/promise');
// 創(chuàng)建連接池
const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'myapp',
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});
// CRUD操作
// 創(chuàng)建
async function createUser(user) {
    const sql = 'INSERT INTO users (name, email, age) VALUES (?, ?, ?)';
    const [result] = await pool.execute(sql, [user.name, user.email, user.age]);
    return result.insertId;
}
// 讀取
async function getUsers() {
    const [rows] = await pool.execute('SELECT * FROM users WHERE age >= ?', [18]);
    return rows;
}
async function getUserById(id) {
    const [rows] = await pool.execute('SELECT * FROM users WHERE id = ?', [id]);
    return rows[0];
}
// 更新
async function updateUser(id, updates) {
    const sql = 'UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?';
    const [result] = await pool.execute(sql, [updates.name, updates.email, updates.age, id]);
    return result.affectedRows > 0;
}
// 刪除
async function deleteUser(id) {
    const sql = 'DELETE FROM users WHERE id = ?';
    const [result] = await pool.execute(sql, [id]);
    return result.affectedRows > 0;
}
// 事務(wù)
async function transferMoney(fromId, toId, amount) {
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        // 扣款
        await connection.execute(
            'UPDATE users SET balance = balance - ? WHERE id = ?',
            [amount, fromId]
        );
        // 加款
        await connection.execute(
            'UPDATE users SET balance = balance + ? WHERE id = ?',
            [amount, toId]
        );
        await connection.commit();
        return true;
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
}

七、實(shí)戰(zhàn)項(xiàng)目:RESTful API

7.1 項(xiàng)目結(jié)構(gòu)

my-api/
├── config/
│   └── database.js
├── models/
│   └── User.js
├── routes/
│   └── users.js
├── middleware/
│   └── auth.js
├── controllers/
│   └── userController.js
├── app.js
├── .env
└── package.json

7.2 實(shí)現(xiàn)代碼

// package.json
{
  "name": "my-api",
  "version": "1.0.0",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.0.3",
    "dotenv": "^16.0.3",
    "bcryptjs": "^2.4.3",
    "jsonwebtoken": "^9.0.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.22"
  }
}
// .env
PORT=3000
MONGODB_URI=mongodb://localhost:27017/myapi
JWT_SECRET=your-secret-key
// config/database.js
const mongoose = require('mongoose');
const connectDB = async () => {
    try {
        await mongoose.connect(process.env.MONGODB_URI);
        console.log('MongoDB連接成功');
    } catch (error) {
        console.error('MongoDB連接失敗:', error);
        process.exit(1);
    }
};
module.exports = connectDB;
// models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true
    },
    email: {
        type: String,
        required: true,
        unique: true,
        trim: true,
        lowercase: true
    },
    password: {
        type: String,
        required: true,
        minlength: 6
    },
    role: {
        type: String,
        enum: ['user', 'admin'],
        default: 'user'
    }
}, {
    timestamps: true
});
// 密碼加密
userSchema.pre('save', async function(next) {
    if (!this.isModified('password')) {
        return next();
    }
    const salt = await bcrypt.genSalt(10);
    this.password = await bcrypt.hash(this.password, salt);
    next();
});
// 密碼驗(yàn)證
userSchema.methods.comparePassword = async function(candidatePassword) {
    return await bcrypt.compare(candidatePassword, this.password);
};
module.exports = mongoose.model('User', userSchema);
// controllers/userController.js
const User = require('../models/User');
const jwt = require('jsonwebtoken');
// 生成JWT
const generateToken = (userId) => {
    return jwt.sign({ userId }, process.env.JWT_SECRET, {
        expiresIn: '7d'
    });
};
// 注冊
exports.register = async (req, res) => {
    try {
        const { name, email, password } = req.body;
        // 檢查用戶是否已存在
        const existingUser = await User.findOne({ email });
        if (existingUser) {
            return res.status(400).json({ message: '郵箱已被注冊' });
        }
        // 創(chuàng)建用戶
        const user = new User({ name, email, password });
        await user.save();
        // 生成token
        const token = generateToken(user._id);
        res.status(201).json({
            message: '注冊成功',
            token,
            user: {
                id: user._id,
                name: user.name,
                email: user.email,
                role: user.role
            }
        });
    } catch (error) {
        res.status(500).json({ message: '服務(wù)器錯(cuò)誤', error: error.message });
    }
};
// 登錄
exports.login = async (req, res) => {
    try {
        const { email, password } = req.body;
        // 查找用戶
        const user = await User.findOne({ email });
        if (!user) {
            return res.status(401).json({ message: '郵箱或密碼錯(cuò)誤' });
        }
        // 驗(yàn)證密碼
        const isMatch = await user.comparePassword(password);
        if (!isMatch) {
            return res.status(401).json({ message: '郵箱或密碼錯(cuò)誤' });
        }
        // 生成token
        const token = generateToken(user._id);
        res.json({
            message: '登錄成功',
            token,
            user: {
                id: user._id,
                name: user.name,
                email: user.email,
                role: user.role
            }
        });
    } catch (error) {
        res.status(500).json({ message: '服務(wù)器錯(cuò)誤', error: error.message });
    }
};
// 獲取用戶信息
exports.getProfile = async (req, res) => {
    try {
        const user = await User.findById(req.userId).select('-password');
        if (!user) {
            return res.status(404).json({ message: '用戶不存在' });
        }
        res.json(user);
    } catch (error) {
        res.status(500).json({ message: '服務(wù)器錯(cuò)誤', error: error.message });
    }
};
// 更新用戶信息
exports.updateProfile = async (req, res) => {
    try {
        const { name, email } = req.body;
        const user = await User.findByIdAndUpdate(
            req.userId,
            { name, email },
            { new: true, runValidators: true }
        ).select('-password');
        if (!user) {
            return res.status(404).json({ message: '用戶不存在' });
        }
        res.json({ message: '更新成功', user });
    } catch (error) {
        res.status(500).json({ message: '服務(wù)器錯(cuò)誤', error: error.message });
    }
};
// middleware/auth.js
const jwt = require('jsonwebtoken');
const auth = async (req, res, next) => {
    try {
        const token = req.header('Authorization')?.replace('Bearer ', '');
        if (!token) {
            return res.status(401).json({ message: '未提供認(rèn)證token' });
        }
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        req.userId = decoded.userId;
        next();
    } catch (error) {
        res.status(401).json({ message: '無效的token' });
    }
};
module.exports = auth;
// routes/users.js
const express = require('express');
const router = express.Router();
const { register, login, getProfile, updateProfile } = require('../controllers/userController');
const auth = require('../middleware/auth');
router.post('/register', register);
router.post('/login', login);
router.get('/profile', auth, getProfile);
router.put('/profile', auth, updateProfile);
module.exports = router;
// app.js
require('dotenv').config();
const express = require('express');
const connectDB = require('./config/database');
const userRoutes = require('./routes/users');
const app = express();
// 連接數(shù)據(jù)庫
connectDB();
// 中間件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 路由
app.use('/api/users', userRoutes);
// 錯(cuò)誤處理
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({ message: '服務(wù)器錯(cuò)誤' });
});
// 啟動(dòng)服務(wù)器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`服務(wù)器運(yùn)行在 http://localhost:${PORT}`);
});

八、Node.js最佳實(shí)踐

8.1 錯(cuò)誤處理

// 使用異步函數(shù)和try-catch
async function asyncOperation() {
    try {
        const result = await someAsyncOperation();
        return result;
    } catch (error) {
        console.error('操作失敗:', error);
        throw error;
    }
}
// 錯(cuò)誤處理中間件
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).json({
        message: '服務(wù)器錯(cuò)誤',
        error: process.env.NODE_ENV === 'development' ? err.message : {}
    });
});
// 未捕獲的Promise拒絕
process.on('unhandledRejection', (reason, promise) => {
    console.error('未處理的Promise拒絕:', reason);
});
// 未捕獲的異常
process.on('uncaughtException', (error) => {
    console.error('未捕獲的異常:', error);
    process.exit(1);
});

8.2 安全性

// 使用helmet
const helmet = require('helmet');
app.use(helmet());
// 使用cors
const cors = require('cors');
app.use(cors());
// 輸入驗(yàn)證
const { body, validationResult } = require('express-validator');
app.post('/users', [
    body('name').notEmpty().withMessage('姓名不能為空'),
    body('email').isEmail().withMessage('郵箱格式不正確'),
    body('password').isLength({ min: 6 }).withMessage('密碼至少6位')
], (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }
    // 處理請求
});
// 環(huán)境變量
require('dotenv').config();
// 限制請求頻率
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15分鐘
    max: 100 // 限制100次請求
});
app.use(limiter);

8.3 性能優(yōu)化

// 啟用Gzip壓縮
const compression = require('compression');
app.use(compression());
// 使用緩存
const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 600 }); // 10分鐘緩存
app.get('/api/data', async (req, res) => {
    const cacheKey = 'data';
    const cachedData = cache.get(cacheKey);
    if (cachedData) {
        return res.json(cachedData);
    }
    const data = await fetchData();
    cache.set(cacheKey, data);
    res.json(data);
});
// 使用連接池
const pool = mysql.createPool({
    connectionLimit: 10,
    // 其他配置
});
// 使用集群(多進(jìn)程)
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
} else {
    // 啟動(dòng)服務(wù)器
    app.listen(3000);
}

8.4 日志記錄

const winston = require('winston');
const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.json()
    ),
    transports: [
        new winston.transports.File({ filename: 'error.log', level: 'error' }),
        new winston.transports.File({ filename: 'combined.log' })
    ]
});
if (process.env.NODE_ENV !== 'production') {
    logger.add(new winston.transports.Console({
        format: winston.format.simple()
    }));
}
// 使用日志
logger.info('服務(wù)器啟動(dòng)');
logger.error('發(fā)生錯(cuò)誤', error);

九、部署和運(yùn)維

9.1 PM2進(jìn)程管理

# 安裝PM2
npm install -g pm2
# 啟動(dòng)應(yīng)用
pm2 start app.js
# 啟動(dòng)應(yīng)用并指定名稱
pm2 start app.js --name my-app
# 列出所有進(jìn)程
pm2 list
# 查看日志
pm2 logs
# 重啟應(yīng)用
pm2 restart my-app
# 停止應(yīng)用
pm2 stop my-app
# 刪除應(yīng)用
pm2 delete my-app
# 監(jiān)控
pm2 monit
# 保存進(jìn)程列表
pm2 save
# 設(shè)置開機(jī)自啟
pm2 startup

9.2 Docker容器化

# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
# 構(gòu)建鏡像
docker build -t my-nodejs-app .
# 運(yùn)行容器
docker run -p 3000:3000 my-nodejs-app
# docker-compose.yml
version: '3'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - MONGODB_URI=mongodb://mongo:27017/myapp
    depends_on:
      - mongo
  mongo:
    image: mongo:latest
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db
volumes:
  mongo-data:
# 使用docker-compose啟動(dòng)
docker-compose up -d

十、總結(jié)

Node.js是一個(gè)功能強(qiáng)大、生態(tài)豐富的后端開發(fā)平臺(tái)。通過本文的學(xué)習(xí),你應(yīng)該掌握了:

  • Node.js的基礎(chǔ)概念和安裝配置
  • 模塊系統(tǒng)(CommonJS和ES6)
  • 核心模塊的使用(fs、http、path、events等)
  • NPM包管理和常用包
  • Express框架的詳細(xì)使用
  • 數(shù)據(jù)庫操作(MongoDB、MySQL)
  • 完整的RESTful API項(xiàng)目實(shí)戰(zhàn)
  • Node.js最佳實(shí)踐(錯(cuò)誤處理、安全性、性能優(yōu)化)
  • 部署和運(yùn)維(PM2、Docker)

學(xué)習(xí)建議

  • 多動(dòng)手實(shí)踐,創(chuàng)建自己的項(xiàng)目
  • 深入理解Node.js的異步編程模型
  • 學(xué)習(xí)TypeScript提高代碼質(zhì)量
  • 關(guān)注Node.js的最新發(fā)展
  • 參與開源項(xiàng)目,學(xué)習(xí)優(yōu)秀的代碼
  • 掌握監(jiān)控和調(diào)試技巧

Node.js的學(xué)習(xí)是一個(gè)持續(xù)的過程,隨著技術(shù)的發(fā)展,Node.js也在不斷進(jìn)化。保持學(xué)習(xí)的熱情,不斷提升自己的技能,你一定能成為一名優(yōu)秀的Node.js開發(fā)者!

希望這篇Node.js詳解教程對你有所幫助!如果你有任何問題或建議,歡迎留言討論。持續(xù)學(xué)習(xí),不斷進(jìn)步,讓我們一起在后端開發(fā)的道路上越走越遠(yuǎn)!

到此這篇關(guān)于Node.js完全指南:從入門到精通的文章就介紹到這了,更多相關(guān)Node.js從入門到精通內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Node.js基礎(chǔ)入門之回調(diào)函數(shù)及異步與同步詳解

    Node.js基礎(chǔ)入門之回調(diào)函數(shù)及異步與同步詳解

    Node.js是一個(gè)基于Chrome?V8引擎的JavaScript運(yùn)行時(shí)。類似于Java中的JRE,.Net中的CLR。本文將詳細(xì)為大家介紹Node.js中的回調(diào)函數(shù)及異步與同步,感興趣的可以了解一下
    2022-03-03
  • node.js超時(shí)timeout詳解

    node.js超時(shí)timeout詳解

    本文介紹了nodejs中超時(shí)timeout事件,并給出了詳細(xì)的示例分析,非常的詳盡,推薦給需要的小伙伴參考下
    2014-11-11
  • 基于Node.js實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)換工具

    基于Node.js實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)換工具

    在前端項(xiàng)目中,利用?Excel?表格和?Node.js?實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)換工具,可以有效優(yōu)化增刪改查等功能,下面小編就來和大家講講具體的實(shí)現(xiàn)步驟吧
    2025-02-02
  • 如何正確使用Nodejs 的 c++ module 鏈接到 OpenSSL

    如何正確使用Nodejs 的 c++ module 鏈接到 OpenSSL

    這篇文章主要介紹了如何正確使用Nodejs 的 c++ module 鏈接到 OpenSSL,需要的朋友可以參考下
    2014-08-08
  • 從零學(xué)習(xí)node.js之詳解異步控制工具async(八)

    從零學(xué)習(xí)node.js之詳解異步控制工具async(八)

    sync是一個(gè)流程控制工具包,提供了直接而強(qiáng)大的異步功能。基于JavaScript為Node.js設(shè)計(jì),同時(shí)也可以直接在瀏覽器中使用。下面這篇文章主要介紹了node.js之異步控制工具async的相關(guān)資料,需要的朋友可以參考下。
    2017-02-02
  • express中static中間件的具體使用方法

    express中static中間件的具體使用方法

    這篇文章主要介紹了express中static中間件的具體使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Ubuntu22.04系統(tǒng)下升級(jí)nodejs到v18版本

    Ubuntu22.04系統(tǒng)下升級(jí)nodejs到v18版本

    ubuntu默認(rèn)安裝的nodejs版本比較老,要安裝到最新的,下面這篇文章主要給大家介紹了關(guān)于Ubuntu22.04系統(tǒng)下升級(jí)nodejs到v18版本的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06
  • mongoose中利用populate處理嵌套的方法

    mongoose中利用populate處理嵌套的方法

    這篇文章主要給大家介紹了關(guān)于mongoose中利用populate處理嵌套的方法,文中通過示例代碼介紹的非常詳細(xì),對大家具有一的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • 詳解基于Koa2開發(fā)微信二維碼掃碼支付相關(guān)流程

    詳解基于Koa2開發(fā)微信二維碼掃碼支付相關(guān)流程

    這篇文章主要介紹了詳解基于Koa2開發(fā)微信二維碼掃碼支付相關(guān)流程,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • 使用forever管理nodejs應(yīng)用教程

    使用forever管理nodejs應(yīng)用教程

    這篇文章主要介紹了使用forever管理nodejs應(yīng)用教程,本文介紹了forever的安裝、常用命令等,最有用的莫過于文件改動(dòng)監(jiān)聽并自動(dòng)重啟了,這可以增加開nodejs應(yīng)用的效率,需要的朋友可以參考下
    2014-06-06

最新評(píng)論

万宁市| 屏东市| 朝阳市| 双牌县| 年辖:市辖区| 邮箱| 车致| 济阳县| 女性| 获嘉县| 库车县| 丹棱县| 额尔古纳市| 开江县| 开鲁县| 彰化市| 龙州县| 筠连县| 建昌县| 西安市| 宣恩县| 古丈县| 江达县| 寻乌县| 盐津县| 东明县| 台中县| 泗水县| 德钦县| 临江市| 镇远县| 宜黄县| 清原| 阳信县| 明光市| 丹寨县| 安岳县| 嘉禾县| 晴隆县| 广西| 顺义区|