【前端工程化-Node.js】Node.js介绍、模块化、模块导入导出语法、npm包管理、同源和跨域

Node.js入门

Node.js是什么

Node.js 是一个跨平台的 JavaScript 运行环境,主要使用场景有:

  • 编写后端程序:充当服务器,对外提供Web服务(接口、数据、网页资源等)
  • 前端工程化:对代码进行压缩,转译和整合

浏览器和Node环境的对比

Node.js 内部封装了 Chrome V8 引擎,因此可以像浏览器一样运行 JS 代码:

bash 复制代码
node xxx.js

浏览器和 Node.js 都支持 ECMAScript 标准语法,Node 中没有 DOM 对象和 BOM 对象,但自身又封装了一些特殊的 API

Node常见内置模块

  • fs 模块:用来读写文件
  • path 模块:用来处理文件路径
  • http 模块:对外提供Web服务

Node中相对路径的问题

在 Node 中运行 JavaScript 代码时,代码中的相对路径总是根据 运行命令的终端 所在路径来查找的,在不同的终端下可能会无法找到目标文件

Node 推荐使用绝对路径,在 JS 代码中,先使用 __dirname__ 获取当前文件所在绝对路径,然后调用 path.join(__dirname__,相对路径) 方法拼接成目标文件的真实绝对路径

eg.使用Node对外提供web服务

js 复制代码
// 1.引入相关内置模块
const http = require("http");
const fs = require("fs");
const path = require("path");
// 2.创建server对象,用来对外提供web服务
const server = http.createServer();
// 3.监听请求并处理
server.on("request", (req, res) => {
  if (req.url === "/api/province") {
    fs.readFile(path.join(__dirname, "./data/province.json"), (err, data) => {
      // 解决中文乱码
      res.setHeader("Content-Type", "application/json;charset=utf-8");
      // 返回响应数据
      res.end(data.toString());
    });
  } else {
    res.end("<h1>404</h1>");
  }
});
// 4.启动web服务
server.listen(3000, () => {
  console.log("web服务已启动...");
});

eg.模拟前端工程化

js 复制代码
// 模拟前端工程化中的代码压缩
// 把 public/index.html 里的回车/换行符去掉,写入到 dist/index.html 中
const fs = require("fs");
const path = require("path");
// 1.读取原文件,利用replace方法替换代码中的回车和换行
fs.readFile(path.join(__dirname, "./public/index.html"), (err, data) => {
  if (err) return console.error(err);
  // 读取的文件内容
  const htmlStr = data.toString();
  // 压缩后的字符串
  const str = htmlStr.replace(/[\r\n]/g, "");
  // 2.将压缩后的代码写入一个新文件中
  fs.writeFile(path.join(__dirname, "./dist/index.html"), str, (err) => {
    if (err) return console.error(err);
    console.log("压缩成功");
  });
});

模块化

什么是模块化

模块化:可以把项目中的每个文件都看做是一个模块。模块之间彼此独立,使用特定语法进行导入导出

模块化的好处

  • 提高代码复用性
  • 实现按需加载
  • 作用域独立

CommonJS标准ECMAScript标准 是两种常见的模块导入导出的语法标准

CommonJS标准

CommonJS标准 是 Node 默认的导入导出语法规范

js 复制代码
const checkUsername = (uname) => uname.length >= 8;
const checkPwd = (pwd) => pwd.length >= 6;
// 导出一个对象
module.exports = {
  checkUsername,
  checkPwd,
};
js 复制代码
// 对于导入的对象,可以直接解构赋值
const { checkUsername, checkPwd } = require("./utils/check.js");
console.log(checkUsername("pc666888"));
console.log(checkPwd("123456"));

对于内置模块,导入时只写模块名就行;对于自定义模块,导入时需要写文件完整路径(包括后缀)

ECMAScript 标准

ECMAScript标准 是 ES6 新增的导入导出语法,在现代前端工程化中最为常用

ES6模块的设计思想是尽量的静态化,使得 编译时 就能确定模块的依赖关系,以及输入和输出的变量。CommonJS模块 和 AMD模块,都只能在 运行时 确定这些东西

要在 Node.js 中使用 ECMAScript 标准语法,需要在项目根目录中新建 package.json 文件,并设置 {"type":"module"} 属性

默认导入导出
js 复制代码
const checkUsername = (uname) => uname.length >= 8;
const checkPwd = (pwd) => pwd.length >= 6;
// 导出一个对象
export default { checkUsername, checkPwd };
js 复制代码
// 对于导入的对象,必须先用一个变量接收
import check from "./utils/check.js";
const { checkUsername, checkPwd } = check;
console.log(checkUsername("pc666888"));
console.log(checkPwd("123456"));

一个模块只能有一个默认导出语句
默认导出不能直接解构赋值,必须用一个变量接收,变量名是可以自定义的

命名导入与导出

使用 命名导入/导出 可以实现模块的按需加载:

js 复制代码
// 写法一:单独导出
// export后的修饰定义语句可以是:函数、类或普通变量
export const checkUsername = (uname) => uname.length >= 8;
export const checkPwd = (pwd) => pwd.length >= 6;
// 写法二:统一导出为对象
const checkUsername = (uname) => uname.length >= 8;
const checkPwd = (pwd) => pwd.length >= 6;
export { checkUsername, checkPwd };
js 复制代码
// 对于导入的对象,可以直接解构赋值
import { checkUsername, checkPwd } from "./utils/check.js";
console.log(checkUsername("pc666888"));
console.log(checkPwd("123456"));

在html引入js模块

html 复制代码
<!-- defer (默认)异步模块加载模式,等待html全部渲染完再执行 -->
<script type="module" src="./foo.js" defer></script>
<!-- async 异步模块加载模式,加载完就执行 -->
<script type="module" src="./foo.js" async></script>

包管理

什么是软件包

软件包:本质就是一个文件夹,内部封装了工具和方法供开发者使用。根目录中必须要有 package.json 文件(记录软件包的名字,作者,入口文件,依赖包等信息)

软件包的分类

  • 本地软件包:仅在当前项目内使用,封装属性和方法,存在于项目根目录下的 node_modules
  • 全局软件包:本机所有项目都可能会使用,封装命令和工具,存在于系统全局位置(如hexo命令)

在导入三方软件包时,默认入口文件是 index.js,我们也可以在 package.json 中使用 main 属性自定义入口文件的位置

使用npm管理软件包

命令 功能 备注
npm init -y 初始化一个 package.json 文件 -y 跳过填写信息
npm install <module> 安装指定依赖包 -g 全局安装 | --save-dev 安装开发时的依赖
npm install 安装所有依赖包 通常用来生成 node_modules

点击查看更多 npm 命令

同源和跨域

什么是同源策略

同源策略 是浏览器中的一个重要的安全策略,它用于限制一个源的文档或者它加载的脚本如何才能与另一个源的资源进行交互,从而帮助阻隔恶意文档,减少被攻击的可能性

:特指 URL 中的 协议、域名和端口号 部分

同源:如果两个URL的 协议、域名和端口号 都相同,那么这两个URL就是同源的

什么是跨域访问

在浏览器中,一个网页的脚本通过 ajax 请求另一个源的资源时,如果 网页所在源ajax 请求的源(协议、域名或端口号)不完全相同,就会发生 跨域访问,导致请求失败

解决跨域问题

开发中-CORS跨域资源共享

前后端分离的项目,不在同一个源开发,为了保证正常的数据通信,可以采用 CORS(Cross-Origin Resource Sharing)跨域资源共享 机制

CORS的实现过程:通过在服务端设置 Access-Control-Allow-Origin 响应头字段,标识允许跨域访问的源地址;浏览器在收到这个响应头后,就会允许跨域访问并将响应数据返回给前端页面

上线后-同源访问

把前端项目和后端项目部署到同一个源下,在保证安全性的前提下直接避免跨域访问的问题

良苦用心啊!我把7大跨域解决方法原理画成10张图,做成图解!
三分钟,带你理解并解决前端跨域

相关推荐
爱因斯坦乐20 小时前
Vue项目整合
前端·javascript·vue.js
FlyWIHTSKY20 小时前
TS、TSX、JS、JSX 文件扩展名详解
开发语言·javascript·ecmascript
无风听海20 小时前
IndexedDB 深度指南 浏览器中的事务型对象数据库
前端·数据库
ct97821 小时前
组件间的通信
前端·javascript·vue.js
左手吻左脸。21 小时前
Vue 全栈面试题大全(2026 最新版最详细)
前端·javascript·vue.js
Aphasia31121 小时前
手写KeepAlive组件
前端·react.js·面试
两个西柚呀1 天前
js中的同步和异步,三种处理异步任务的方式
前端·javascript
pe7er1 天前
软件设计不要“既要又要”
前端·后端·架构
kyriewen1 天前
从Webpack到Vite:我们迁移了一个10万行代码的项目,总结了这7个坑
前端·webpack·vite
IT_陈寒1 天前
Java Stream并行流的坑:我花了3小时才找到的线程安全问题
前端·人工智能·后端