二三(Node2)、Node.js 模块化、package.json、npm 软件包管理器、nodemon、Express、同源、跨域、CORS

1. Node.js 模块化

1.1 CommonJS 标准

utils.js

javascript 复制代码
/**
 * 目标:基于 CommonJS 标准语法,封装属性和方法并导出
 */
const baseURL = "http://hmajax.itheima.net";
const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);

module.exports = {
  baseURL,
  getArraySum,
};

index.js

javascript 复制代码
/**
 * 目标:基于 CommonJS 标准语法,导入工具属性和方法使用
 */

/* 
  模块化:每个文件都是独立的模块,需要标准语法导出和导入进行使用

  CommonJS 标准 - 导出和导入模块
  ➢ 导出:module.exports = {}
  ➢ 导入:require('模块名或路径')

  ➢ 内置模块,直接写名字。例如:fs,path,http等
  ➢ 自定义模块,写模块文件路径。例如:./utils.js
*/

// 解构导入的数据
// const { baseURL, getArraySum } = require("./utils");
const { baseURL, getArraySum } = require("./utils.js");

console.log(baseURL); // http://hmajax.itheima.net
console.log(getArraySum([1, 5, 8])); // 14

1.2 ECMAScript 标准 - 默认导出和导入

utils.js

javascript 复制代码
/**
 * 目标:基于 ECMAScript 标准语法,封装属性和方法并"默认"导出
 */
const baseURL = "http://hmajax.itheima.net";
const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);

export default {
  baseURL,
  getArraySum,
};

package.json

javascript 复制代码
{
  "type": "module"
}

index.js

javascript 复制代码
/**
 * 目标:基于 ECMAScript 标准语法,"默认"导入,工具属性和方法使用
 */

/* 
  1. ECMAScript 标准 - 默认导出和导入模块
  ➢ 导出:export default {}
  ➢ 导入:import 变量名 from '模块名或路径'
  
  2. Node.js 切换模块标准为 ECMAScript
  ➢ 运行模块所在文件夹,新建 package.json 并设置{ "type" : "module" }
*/

import obj from "./utils.js";
console.log(obj.baseURL); // http://hmajax.itheima.net
console.log(obj.getArraySum([1, 4, 7])); // 12

1.3 ECMAScript 标准 - 命名导出和导入

utils.js

javascript 复制代码
/**
 * 目标:基于 ECMAScript 标准语法,封装属性和方法并"命名"导出
 */
export const baseURL = "http://hmajax.itheima.net";
export const getArraySum = (arr) => arr.reduce((sum, item) => (sum += item), 0);

package.json

javascript 复制代码
{
  "type": "module"
}

index.js

javascript 复制代码
/**
 * 目标:基于 ECMAScript 标准语法,"命名"导入,工具属性和方法使用
 */

/* 
  ECMAScript 标准,命名导出和导入的语法
  ➢ 导出:export 修饰定义的语句
  ➢ 导入:import { 同名变量 } from '模块名或路径'

  按需加载,使用命名导出和导入
  全部加载,使用默认导出和导入
*/

import { getArraySum, baseURL } from "./utils.js";
console.log(baseURL); // http://hmajax.itheima.net
console.log(getArraySum([1, 5, 8, 12, 234])); // 260

2. 软件包

javascript 复制代码
/* 
  1. 什么是包?
  ➢ 将模块,代码,其他资料聚合成的文件夹

  2. 包分为哪 2 类呢?
  ➢ 项目包:编写项目代码的文件夹
  ➢ 软件包:封装工具和方法供开发者使用

  3. package.json 文件的作用?
  ➢ 记录软件包的名字,作者,入口文件等信息
  
  4. 导入一个包文件夹的时候,导入的是哪个文件?
  ➢ 默认 index.js 文件,或者 main 属性指定的文件
*/

3. npm 软件包管理器

3.1 npm - 软件包管理器

javascript 复制代码
/**
 * 目标:使用 npm 下载 dayjs 软件包来格式化日期时间
 *  1. (可选)初始化项目清单文件,命令:npm init -y
 *  2. 下载软件包到当前项目,命令:npm i 软件包名称
 *  3. 使用软件包
 */

/*
  npm config set registry xxx 这个命令用于设置 npm(Node Package Manager)的注册表地址
  默认情况下,npm 使用官方的 npm 注册表 (https://registry.npmjs.org),
  但有时为了加快下载速度或访问某些特定的包,用户可能会选择使用镜像源。

  1. 将 npm 的注册表设置为一个镜像源(在中国境内可能更快)
  npm config set registry http://registry.npmmirror.com

  2. 安装 dayjs 这个日期处理库; i - install
  npm i dayjs
*/

/* 
  1. npm 软件包管理器作用?
    ➢ 下载软件包以及管理版本
  2. 初始化项目清单文件 package.json 命令?
    ➢ npm init -y
  3. 下载软件包的命令?
    ➢ npm i 软件包名字
  4. 下载的包会存放在哪里?
    ➢ 当前项目下的 node_modules 中,并记录在 package.json 中
*/

const dayjs = require("dayjs");
const res = dayjs().format("YYYY-MM-DD");
console.log(res); // 2024-12-12

3.2 npm - 安装所有依赖

javascript 复制代码
/**
 * 目标:安装所有依赖软件包
 * 场景:一般拿到别人的项目后,只有 package.json 缺少 node_modules 时需要做
 * 语法:在当前项目终端下,输入命令:npm i
 * 效果:会根据 package.json 记录的所有包和版本开始下载
 */

/* 
  1. 当项目中只有 package.json 没有 node_modules 怎么办?
    ➢ 当前项目下,执行 npm i 安装所有依赖软件包
  2. 为什么 node_modules 不进行传递?
    ➢ 因为用 npm 下载比磁盘传递要快
*/

// 格式化日期
const dayjs = require("dayjs");
const nowDateStr = dayjs().format("YYYY-MM-DD");
console.log(nowDateStr); // 2024-12-12

// 求数组里最大值
const _ = require("lodash");
console.log(_.max([1, 2, 8, 3, 4, 5])); // 8

4. npm 全局软件包 nodemon

javascript 复制代码
/**
 * 目标:使用 nodemon 全局软件包,检测文件变化,自动重启程序
 * 语法:
 *  1. 安装 nodemon 全局软件包,命令:npm i nodemon -g
 *  2. 使用 nodemon 来执行目标 js 文件
 * 体验:启动后,修改代码,保存后观察终端效果
 */

/* 
  1. 本地软件包和全局软件包区别?
  ➢ 本地软件包,作用在当前项目,封装属性和方法
  ➢ 全局软件包,本机所有项目使用,封装命令和工具

  2. nodemon 作用?
  ➢ 替代 node 命令,检测代码更改,自动重启程序
  
  3. nodemon 怎么用?
  ➢ 先确保安装 npm i nodemon -g
  ➢ 使用 nodemon 执行目标 js 文件
*/

// 格式化日期
const dayjs = require("dayjs");
const nowDateStr = dayjs().format("YYYY-MM-DD");
console.log(nowDateStr);

// 求数组里最大值
const _ = require("lodash");
console.log(_.max([1, 10, 2, 3, 4, 55]));

5. Node.js 总结

javascript 复制代码
/**
 * 总结:
 * Node.js模块:
 *  概念:每个文件就是一个模块,独立作用域,按需加载,需使用特定语法导出导入
 *  CommonJS 标准语法:
 *    导出:module.exports = {}
 *    导入:require('模块名或路径')
 *  ECMAScript 标准语法:
 *    默认导出:export default {}
 *    默认导入:import 变量名 from '模块名或路径'
 *    命名导出:export 修饰定义语句
 *    命名导入:import { 同名变量 } from '模块名或路径'
 *
 * Node.js包:
 *  概念:把模块文件,代码文件,其他资料聚合成一个文件夹
 *  项目包:编写项目需求和业务逻辑的文件夹
 *  软件包:封装工具/方法的文件夹(一般用 npm 管理)
 *    本地软件包:封装属性/方法,在当前项目中使用,例如:dayjs,lodash
 *    全局软件包:封装工具/命令,在本机中使用,例如:nodemon
 *
 * 常用命令:
 *  执行 js 文件:node xxx
 *  初始化 package.json: npm init -y
 *  下载本地软件包:npm i 软件包名
 *  下载全局软件包:npm i 软件包名 -g
 *  删除软件包:npm uni 软件包名
 */

6. Express 搭建 Web 服务

javascript 复制代码
/* 
  Express - 框架
  使用 express 本地软件包,快速搭建 Web 服务(基于 http 模块)

  功能:1. 提供数据接口 2. 提供网页资源等
*/

// 1. 下载 express 软件包
const express = require("express");

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

// 3. 监听请求的方法和请求的资源路径
server.get("/", (req, res) => {
  res.send("哦耶 express");
});

// 4. 监听任意请求的方法和请求的资源路径
server.all("*", (req, res) => {
  res.status(404);
  res.send("您访问的资源不存在");
});

// 5. 监听端口号,启动 Web 服务
server.listen(3000, () => {
  console.log("启动成功成功");
});

7. 获取省份列表 - 接口开发

javascript 复制代码
/**
 * 目标:基于 express 软件包,开发提供省份列表的数据接口
 * 要求:get 请求方法,/api/province 的请求路径
 */

const fs = require("fs");
const path = require("path");
const express = require("express");
const server = express();

// 监听 get 请求方法,
// 监听资源路径 /api/province,
// 读取 province.json 省份数据返回
server.get("/api/province", (req, res) => {
  fs.readFile(path.join(__dirname, "/data/province.json"), (err, data) => {
    if (err) {
      console.log(err);
    } else {
      res.send(data.toString());
    }
  });
});

server.all("*", (req, res) => {
  res.status(404);
  res.send("你要访问的资源路径不存在");
});

server.listen(3000, () => {
  console.log("Web 服务已启动");
});

8. 跨域以及解决方案

8.1 浏览器的同源策略

javascript 复制代码
/**
 * 目标:了解浏览器中的同源策略
 * 同源策略:是一种安全策略,限制一个源的文档/脚本与另外一个源的资源交互
 *
 * 好处:保护网站的安全,减少被攻击的媒介
 * 限制:浏览器限制 AJAX 只能访问同源的 URL 网址!
 *
 * 源:指的 URL 中的协议,域名,端口号
 * 同源:网页加载所在的源,与 AJAX 请求的源完全相同即为同源
 */

8.2 跨域问题

javascript 复制代码
/* 
  跨域访问:
    网页所在源和 AJAX 请求的源(协议,域名,端口号)不完全相同,就发生跨域访问
*/

8.3 跨域问题 - 解决方案1 - CORS

javascript 复制代码
/* 
  跨域问题 - 解决方案1 - CORS
  目标:前后端分离的项目,前端和后端不在一个源,还要保证数据通信
  解决:
    采用 CORS (跨域资源共享),一种基于 HTTP 头的机制,
    该机制通过允许服务器标示除了它自己以外的其他源(域、协议或端口),
    使得浏览器允许这些源访问加载自己的资源

  步骤:
  1. 下载 cors 本地软件包
  2. 导入 cors 函数
  3. 使用 server.use() 给 Web 服务添加插件功能
  4. 把 cors 函数调用传入给 Web 服务,启动测试

  1. 为什么要解决跨域问题?
  ➢ 因为前后端分离的项目,不在同一个源去开发项目
  ➢ 需要保证数据之间通信
  
  2. 跨域问题如何解决?
  ➢ 让后端开启 CORS 跨域资源共享
  ➢ 在响应头设置 Access-Control-Allow-Origin: *
*/

// 2. 导入 cors 函数
const cors = require("cors");
// 3. 使用 server.use() 给 Web 服务添加插件功能
server.use(cors());

8.4 跨域问题 - 解决方案2 - 同源访问

javascript 复制代码
/* 
  跨域问题 - 解决方案2 - 同源访问
  目标:开发环境用 cors,上线部署关闭 cors,并采用同源访问方式
  做法:让后端 Web 服务既可以提供数据接口,也可以返回网页资源
  好处:安全,后端的接口不允许非同源来访问

  1. CORS 只适用于什么阶段的项目?
  ➢ 本地开发阶段项目
  
  2. 项目上线,如何解决跨域问题?
  ➢ 把前端项目和后端项目部署到同一个源下访问
*/

// 暴露指定的文件夹,让前端可以直接拼接路径和资源名字来访问
server.use(express.static(path.join(__dirname, "public")));
相关推荐
神仙别闹8 小时前
基于VUE+Node.JS实现(Web)学生组队网站
前端·vue.js·node.js
BXCQ_xuan10 小时前
基于Node.js的健身会员管理系统的后端开发实践
后端·mysql·node.js
wt_cs10 小时前
身份证实名认证接口数字时代的信任基石-node.js实名认证集成
开发语言·node.js·php
李剑一12 小时前
写一个vitepress新建文章脚本,自动化创建链接,别再手写了!
前端·node.js·vitepress
名字越长技术越强1 天前
Node.js学习
学习·node.js
知识分享小能手1 天前
JavaScript学习教程,从入门到精通,Ajax与Node.js Web服务器开发全面指南(24)
开发语言·前端·javascript·学习·ajax·node.js·html5
dwqqw1 天前
opencv图像库编程
前端·webpack·node.js
layman05281 天前
node.js 实战——(fs模块 知识点学习)
javascript·node.js
本本啊1 天前
node 启动本地应用程序并设置窗口大小和屏幕显示位置
前端·node.js
全栈派森1 天前
Next15 + Prisma + Auth5 实战讲解
react.js·node.js·next.js