前端与Node.js

前端与Node.js

1. 前端(浏览器环境)

前端通常指的是在浏览器中运行的JavaScript代码。它主要负责用户界面的渲染、交互逻辑和与后端API的通信。

  • 核心运行环境:浏览器(如Chrome、Firefox、Safari等)
  • 核心引擎:V8(Chrome)、SpiderMonkey(Firefox)、JavaScriptCore(Safari)等
  • 宿主对象(Host Objects)
    • window:全局对象,提供浏览器窗口相关的API
    • document:DOM操作接口,用于构建和操作网页结构
    • navigator:获取浏览器信息
    • localStoragesessionStorage:浏览器本地存储
    • fetchXMLHttpRequest:网络请求API
  • 特点
    • 运行在客户端,直接面向用户
    • 受同源策略(Same-Origin Policy)限制
    • 需要考虑浏览器兼容性
    • 代码通常通过HTML文件加载

2. Node.js(服务器端环境)

Node.js是一个基于Chrome V8引擎 构建的JavaScript运行时,它允许JavaScript在服务器端运行。

  • 核心运行环境:Node.js 运行时
  • 核心引擎:V8(与Chrome浏览器相同)
  • 宿主对象
    • global:全局对象(相当于浏览器中的window
    • process:提供进程信息和控制
    • Buffer:处理二进制数据
    • requiremodule.exports:模块系统(CommonJS)
    • fspathhttp等:Node.js内置模块,提供文件系统、网络、路径处理等能力
  • 特点
    • 运行在服务器端,处理业务逻辑、数据存储、API服务等
    • 无浏览器安全限制(如同源策略)
    • 可直接访问操作系统资源(文件系统、网络等)
    • 通常通过命令行启动(node app.js

🌟 关键区别总结

维度 前端(浏览器) Node.js(服务器)
运行环境 浏览器 Node.js 运行时
全局对象 window global
模块系统 ES Modules(主流)、CommonJS(打包工具中) CommonJS(原生)、ES Modules(支持)
网络请求 fetchXMLHttpRequest httphttps 模块,或第三方库
文件系统 无法直接访问(受限) 可通过 fs 模块直接读写
主要用途 UI渲染、用户交互 后端服务、API、脚本工具

为什么Lodash、Axios能在前端和Node.js中"通用"?

这是本文的核心问题。答案是:它们是"环境无关"的JavaScript库,通过巧妙的设计实现了跨平台兼容

我们以 LodashAxios 为例,深入分析其原理。


🔹 案例1:Lodash ------ 纯函数工具库的"环境无关性"

Lodash 是一个提供大量实用函数的JavaScript工具库,如 _.debounce_.cloneDeep_.get 等。

为什么它能跨平台?
  1. 不依赖特定宿主对象

    • Lodash 的函数大多是纯函数(Pure Functions) ,只依赖输入参数,不依赖 windowdocumentfs 等环境特定对象。
    • 例如 _.cloneDeep(obj) 只操作JavaScript原生对象,不涉及DOM或文件系统。
  2. 模块化设计

    • Lodash 支持多种模块格式:CommonJS、ES Modules、UMD(Universal Module Definition)。

    • UMD 是关键!它是一种兼容多种环境的模块包装方式:

      复制代码
      (function (root, factory) {
          if (typeof define === 'function' && define.amd) {
              // AMD
              define([], factory);
          } else if (typeof module === 'object' && module.exports) {
              // CommonJS (Node.js)
              module.exports = factory();
          } else {
              // 浏览器全局变量
              root._ = factory();
          }
      }(typeof self !== 'undefined' ? self : this, function () {
          // Lodash 核心实现
          return _;
      }));
    • 这段代码会自动检测当前环境,选择合适的模块导出方式。

  3. 构建工具支持

    • 在前端项目中,Webpack、Vite等工具会将Lodash打包进最终的bundle.js。
    • 在Node.js中,直接通过 require('lodash') 加载。

结论 :Lodash 之所以通用,是因为它不依赖环境API + 使用UMD兼容多模块系统


🔹 案例2:Axios ------ HTTP客户端的"适配器模式"跨平台方案

Axios 是一个基于Promise的HTTP客户端,用于发送网络请求。

它比Lodash更复杂,因为网络请求在浏览器和Node.js中实现方式完全不同

  • 浏览器 :使用 XMLHttpRequestfetch
  • Node.js :使用 http / https 模块

那么,Axios是如何做到"一套API,两端运行"的?

核心机制:适配器模式(Adapter Pattern)

Axios 内部采用了适配器模式,根据运行环境自动选择合适的HTTP实现。

  1. 默认适配器选择逻辑

    复制代码
    // Axios 源码简化示意
    function getDefaultAdapter() {
      let adapter;
      if (typeof XMLHttpRequest !== 'undefined') {
        // 浏览器环境
        adapter = require('./adapters/xhr');
      } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
        // Node.js 环境
        adapter = require('./adapters/http');
      }
      return adapter;
    }
  2. 浏览器适配器 :使用 XMLHttpRequest 发送请求

  3. Node.js适配器 :使用 http 模块发送请求

  4. 统一的API层

    • 无论底层是XHR还是http模块,Axios向上暴露的API完全一致:

      复制代码
      axios.get('/api/users')
        .then(response => console.log(response.data));
  5. 配置化与可替换

    • Axios 允许开发者手动指定适配器,甚至使用自定义适配器。

结论 :Axios 通过适配器模式,在不同环境中使用不同的底层实现,但对外提供统一的API,从而实现跨平台。


如何判断一个库是否"跨平台通用"?

你可以通过以下几点快速判断:

判断标准 跨平台库(如Lodash) 非跨平台库(如jQuery)
是否依赖DOM/BOM API ❌ 不依赖 ✅ 依赖 documentwindow
是否依赖Node.js内置模块 ❌ 不依赖 fspath ✅ 如 fs-extra 只能在Node.js用
模块格式 支持 UMD 或 ESM + CJS 仅支持 CJS 或仅浏览器
构建方式 可通过CDN引入或npm安装 通常只能npm安装用于Node.js

✅ 推荐的跨平台库:Lodash、Axios、Moment.js(已归档)、Day.js、Zod、Yup等

❌ 仅Node.js库:expressfs-extrachild_process

❌ 仅浏览器库:jquerythree.js(虽可Node运行,但无意义)

特性 CJS (CommonJS) ESM (ES Modules) UMD (Universal)
语法 require() / module.exports import / export 兼容多种
加载方式 同步 异步(支持动态导入) 取决于环境
原生支持 Node.js ✅ 浏览器 ✅ + Node.js ✅ Node.js 从 v12+ 开始支持 (需 .mjs 扩展名或 package.json 中设置 "type": "module" ❌(需构建)
Tree Shaking ❌ 不支持 ✅ 支持 ❌ 通常不支持
适用环境 Node.js 前端 + 现代 Node.js 所有环境(兼容性最强)
典型使用 const _ = require('lodash') import _ from 'lodash' CDN 引入或老项目兼容

实际开发中的常见组合"ESM + CJS"

指的是一个 npm 包同时提供两种格式的构建版本:

  • dist/index.esm.js → 供前端构建工具(Vite/Webpack)使用 ESM
  • dist/index.cjs.js → 供 Node.js 直接 require 使用

例如 package.json 中可能这样配置:

复制代码
{
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "exports": {
    ".": {
      "import": "./dist/index.esm.js",
      "require": "./dist/index.cjs.js"
    }
  }
}

前端工程项目打包

前端打包就是在 Node.js 环境下进行的

  • 谁在干活? → Node.js 进程中的打包工具(Webpack/Vite)
  • 输入是什么? → 你的源码 + node_modules 中的库
  • 输出是什么? → 适合浏览器加载的 .html.js.css.png 等静态文件
  • 为什么必须用 Node.js? → 因为需要文件系统、模块解析、高性能计算等能力,浏览器做不到

1. 代码是如何处理的?

  • 流程

    入口文件 → 递归解析 import → 收集所有模块(含 node_modules)→ 转换(Babel/TS)→ 优化 → 输出 dist/ 静态文件。

  • 关键机制

    • Tree Shaking:仅打包实际使用的代码(需 ESM 模块)。
    • Scope Hoisting:合并模块,减少闭包开销。
    • Code Splitting :自动分包(如 vendor.js),提升缓存利用率。

2. 变量(如 process.env)是如何处理的?

  • 机制构建时静态替换(不是运行时)。

  • 流程

    1. 打包工具读取 Node.js 环境变量(或 .env 文件)
    2. 在配置中定义替换规则(如 Vite 的 define,Webpack 的 DefinePlugin
    3. 源码中的 process.env.NODE_ENV 被替换为字符串(如 'production'
    4. 无用代码被 Tree Shaking 删除
  • ⚠️ 注意

    • 浏览器中没有 process,这是"伪变量"。
    • 敏感信息(如密钥)不应暴露在前端变量中。

3. 开发依赖(devDependencies)如何处理?

  • 不会被打包进前端文件
  • 用途 :仅在 Node.js 构建时使用,如:
    • 打包工具(Vite、Webpack)
    • 编译器(TypeScript、Babel)
    • 代码检查(ESLint、Prettier)
  • 类比:厨师的刀具,不端上餐桌。

4. 生产依赖(dependencies)如何处理?

  • 会被打包,但仅限"被引用"的部分
  • Tree Shaking 生效前提
    • 使用 ESM 语法:import { func } from 'lib'
    • 库支持 ESM 格式(package.jsonmodule 字段)
    • 生产模式构建(mode: 'production'
  • 不会打包
    • 未使用的库或函数(如只用 lodash.debounce,其他函数被摇掉)
    • 全量导入(import _ from 'lodash')会打包整个库(应避免)

✅ 一句话总结

打包是在 Node.js 中运行工具 ,将代码按需打包,通过 静态替换注入变量开发依赖不进前端生产依赖按需打包,最终生成轻量、高效的浏览器可用文件。

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼8 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax