Node.js 入门,进阶核心:CommonJS+ES6 模块化、包、Express 与跨域

今天我们聚焦 Node.js 进阶必备技能 ------ 模块化(含 CommonJS+ES6 两种规范)、包管理、Express 框架和跨域解决方案。这是从 "零散代码" 到 "规范项目" 的关键跨越,新手也能快速上手!

一、模块化:Node.js 的代码组织核心(CommonJS+ES6 双规范)

模块化的核心目的是拆分代码、解决命名冲突、提高复用性。Node.js 默认支持 CommonJS 规范(传统方案),同时也兼容 ES6 模块化(现代前端 / Node.js 14.13 + 支持),两种规范都要掌握!

1. 传统方案:CommonJS 规范(Node.js 默认)

Node.js 原生支持的模块化规范,核心是require()导入、module.exports/exports导出,适合 Node.js 后端项目。

(1)核心语法

  • 导出模块:单个导出 / 批量导出
javascript 复制代码
// 模块文件:utils.js
// 方式1:批量导出(推荐,清晰直观)
const add = (a, b) => a + b;
const sub = (a, b) => a - b;
module.exports = { add, sub }; // 导出一个对象

// 方式2:单个导出(也可给exports赋值)
// exports.add = add;
// exports.sub = sub;
  • 导入模块:整体导入 / 解构导入
javascript 复制代码
// 主文件:index.js
// 方式1:解构导入(按需获取)
const { add, sub } = require('./utils.js');
console.log(add(2, 3)); // 输出5
console.log(sub(10, 4)); // 输出6

// 方式2:整体导入(获取整个导出对象)
const utils = require('./utils.js');
console.log(utils.add(2, 3)); // 输出5

(2)CommonJS 关键特性

  • 运行时加载:导入时会执行整个模块文件,返回导出对象的拷贝
  • 动态导入:require()可写在代码任意位置(如条件判断中)
  • 路径规则:导入本地模块需写相对路径(.//.../),导入内置模块(如 fs)或 npm 包可直接写名称

2.现代方案:ES6 模块化(兼容前端 / Node.js)

ES6 模块化是 ECMAScript 标准规范,核心是import导入、export导出,统一了前端(Vue/React)和后端(Node.js)的模块化语法,更推荐长期使用。

(1)Node.js 启用 ES6 模块的前提

Node.js 默认不识别import/export,需满足以下任一条件:

  • 文件名后缀改为.mjs
  • package.json中添加配置:"type": "module"(推荐,整个项目生效)
json 复制代码
// package.json
{
  "type": "module" // 声明项目使用ES6模块化
}

(2)核心语法

  • 导出模块:默认导出 / 命名导出
javascript 复制代码
// 模块文件:utils.mjs(或package.json设type:module后用.js)
// 方式1:命名导出(可多个)
export const add = (a, b) => a + b;
export const sub = (a, b) => a - b;

// 方式2:默认导出(只能一个,可导出任意类型)
export default {
  multiply: (a, b) => a * b,
  divide: (a, b) => a / b
};
  • 导入模块:对应命名导入 / 默认导入
javascript 复制代码
// 主文件:index.js(package.json已设type:module)
// 方式1:命名导入(必须和导出名称一致,可重命名)
import { add, sub as subtract } from './utils.js';
console.log(add(2, 3)); // 输出5
console.log(subtract(10, 4)); // 输出6

// 方式2:默认导入(名称可自定义)
import calc from './utils.js';
console.log(calc.multiply(3, 4)); // 输出12
console.log(calc.divide(10, 2)); // 输出5

// 方式3:整体导入(导入所有命名导出和默认导出)
import * as allUtils from './utils.js';
console.log(allUtils.add(2,3)); // 输出5
console.log(allUtils.default.multiply(3,4)); // 输出12

(3)ES6 模块化关键特性

  • 编译时加载:导入时只加载需要的部分(静态分析),更高效
  • 静态导入:import必须写在文件顶部,不能写在条件判断中
  • 跨端兼容:语法和前端框架(Vue/React)一致,无需切换思维

新手建议:如果是纯 Node.js 后端项目,CommonJS 足够简单;如果需要和前端协同开发(如全栈项目),优先用 ES6 模块化,统一语法减少混乱。

二、包:Node.js 的 "工具仓库"

"包" 是多个模块的集合(包含package.json配置文件),是 Node.js 生态的核心。通过npm(Node 包管理器) 可快速下载、管理第三方包(如 Express、cors)

1. npm 基础操作(必备)

  • 初始化项目:生成package.json(项目配置文件,记录依赖、脚本等)
bash 复制代码
npm init -y # -y表示默认配置,无需手动输入
  • 安装包:
bash 复制代码
# 1. 生产依赖(项目运行必需,如express)
npm install express
# 2. 开发依赖(仅开发时用,如nodemon自动重启服务)
npm install nodemon --save-dev
# 3. 全局安装(全局可用,如npm-check-updates更新依赖)
npm install -g npm-check-updates
  • 使用包:无论是 CommonJS 还是 ES6 模块,导入方式一致
javascript 复制代码
// CommonJS
const express = require('express');
// ES6模块化(package.json设type:module)
import express from 'express';
  • 卸载包:
bash 复制代码
npm uninstall express # 卸载生产依赖
npm uninstall nodemon --save-dev # 卸载开发依赖

2. package.json 的核心作用

  • 记录项目依赖的包及版本(避免 "我本地能跑,线上跑不了")
  • 配置脚本命令(简化启动、构建等操作):
json 复制代码
{
  "scripts": {
    "start": "node index.js", // 普通启动
    "dev": "nodemon index.js" // 开发时自动重启
  }
}

运行脚本:npm run dev(启动开发服务)、npm start(启动生产服务)

三、Express 框架:Web 开发的 "快捷键"

之前用原生http模块写接口繁琐,Express是 Node.js 最流行的 Web 框架,封装了路由、中间件、响应处理等功能,能 10 倍提升接口开发效率!

1. 快速搭建 Express 服务(ES6 模块化示例)

javascript 复制代码
/**
 * 目标:基于 express 软件包,开发 Web 服务返回资源给用户
 * 1. 下载 express 软件包
 * 2. 导入 express 并创建服务对象
 * 3. 监听请求方法和请求路径
 * 4. 对其他路径返回 404 提示 (设置状态码)
 * 5. 设置监听端口号
 */

// 2.导入 express 并创建服务对象
const express = require('express')
const server = express()

// 监听 get 请求
// server.get
server.get('/', (req, res) => {
    // 全自动设置响应头
    res.send("你好世界")
})

// 版本不兼容
// server.get('/*', (req, res) => {
//     // 修改状态码
//     res.status(404)
//     // 响应文本内容
//     res.send('您访问的资源不存在')
// })

// 终极 404 写法(替换原来的 server.get('/*', ...))
server.use((req, res) => {
    res.status(404).send('您访问的资源不存在')
})

// 开启服务
server.listen(3000 ,() => {
    console.log('服务器已启动')
})

启动后访问http://localhost:3000 ,即可看到 JSON 响应,无需手动设置响应头!

结果演示:

2.Express 核心优势

  • 路由简洁:server.get()/server.post()快速定义接口
  • 响应便捷:res.json()/res.send()/res.status()简化响应操作
  • 中间件生态:支持日志、跨域、解析请求体等各类中间件

四、跨域:前端请求后端的 "拦路虎"

浏览器的同源策略(协议、域名、端口必须一致)会阻止前端(如http://localhost:8080)请求后端接口(如http://localhost:3000),这就是跨域问题。Express 用cors中间件可轻松解决!

1. 解决跨域步骤

  • 第一步:安装 cors 包
bash 复制代码
npm install cors
  • 第二步:在 Express 中启用(ES6 模块化示例)
javascript 复制代码
import express from 'express';
import cors from 'cors'; // 导入cors
import fs from 'fs/promises';
import path from 'path';

const app = express();
const port = 3000;

// 关键:启用cors中间件(允许所有跨域请求)
app.use(cors());

// 省份接口(前端可跨域请求)
app.get('/api/province', async (req, res) => {
  const filePath = path.join(process.cwd(), 'data/province.json');
  const data = await fs.readFile(filePath, 'utf-8');
  res.json(JSON.parse(data));
});

app.listen(port, () => {
  console.log(`跨域服务启动:http://localhost:${port}/api/province`);
});

2. 跨域原理

cors中间件会在响应头中添加:

plaintext 复制代码
Access-Control-Allow-Origin: *

表示 "允许所有域名请求该接口",浏览器收到后会绕过同源策略限制,前端即可正常请求。

相关推荐
李少兄1 小时前
解决 `npm install` 卡在 `idealTree: sill idealTree buildDeps` 的排查与修复
前端·npm·node.js
程序员爱钓鱼1 小时前
Node.js 架构与事件循环(Event Loop)深度解析
后端·node.js·trae
程序员爱钓鱼1 小时前
Node.js 起源与发展:改变后端世界的一次“意外革命”
后端·node.js·trae
f***14772 小时前
Node.js npm 安装过程中 EBUSY 错误的分析与解决方案
前端·npm·node.js
古韵2 小时前
深入alova3服务端能力:分布式BFF层到API网关的最佳实践
javascript·redis·node.js
z***751510 小时前
Node.js卸载超详细步骤(附图文讲解)
node.js
W***r2610 小时前
nvm下载安装教程(node.js 下载安装教程)
node.js
A***F15714 小时前
从零到上线:Node.js 项目的完整部署流程(包含 Docker 和 CICD)
docker·容器·node.js