前端架构设计

#前端#架构#设计

前端面试题 - 前端架构设计篇

本章节收录前端架构设计相关面试题,涵盖微前端、组件库设计、低代码平台、性能监控、工程化架构等高级话题。适合前端架构师和高级工程师面试准备。


📊 数据统计

统计项数值
总题数50道
基础题10道 (20%)
中级题22道 (44%)
高级题18道 (36%)

📚 目录


一、微前端架构

1. 什么是微前端?解决了什么问题?

难度:⭐⭐(中级)
标签:#微前端 #架构

参考答案要点

定义:微前端是一种架构风格,将前端应用拆分为多个独立部署的小型应用,再由主应用集成。

解决的问题

问题说明
技术栈无关不同团队可使用不同技术栈(React/Vue/Angular)
独立部署各微应用可独立开发、测试、部署
团队自治减少团队间依赖,提升开发效率
渐进升级可逐步重构老系统,而非一次性重写
代码复用共享组件和工具函数

实现方案

  • iframe
  • Web Components
  • Module Federation
  • qiankun/single-spa

2. 微前端的实现方案有哪些?各自的优缺点?

难度:⭐⭐⭐(高级)
标签:#微前端 #方案对比

参考答案要点

方案优点缺点代表
iframe简单、隔离性好体验差、通信困难、SEO 不友好传统方案
Web Components标准化、隔离性好兼容性、生态不成熟LitElement
Module Federation共享依赖、体验好技术栈需统一(Webpack)Webpack 5
qiankun成熟、易用、技术栈无关沙箱有性能损耗蚂蚁开源
single-spa灵活、生态丰富配置复杂社区方案
无界原生隔离、性能好较新、生态待完善腾讯开源

选型建议

  • 简单场景:iframe
  • Webpack 项目:Module Federation
  • 多技术栈:qiankun
  • 追求性能:无界

3. qiankun 的实现原理是什么?

难度:⭐⭐⭐⭐(专家)
标签:#qiankun #微前端

参考答案要点

核心原理

Plain Text
主应用(基座)
    ↓
├─ 路由拦截(判断加载哪个微应用)
├─ 加载微应用 HTML/JS/CSS
├─ JS 沙箱(Proxy 代理 window)
├─ CSS 沙箱(Shadow DOM / 样式隔离)
└─ 生命周期管理(bootstrap/mount/unmount)

JS 沙箱实现

JAVASCRIPT
// 简化版沙箱
class ProxySandbox {
  constructor() {
    this.fakeWindow = {}
    this.proxy = new Proxy(window, {
      get(target, key) {
        return this.fakeWindow[key] || target[key]
      },
      set(target, key, value) {
        this.fakeWindow[key] = value
        return true
      },
    })
  }

  active() {
    // 激活沙箱
  }

  inactive() {
    // 失活沙箱,清理副作用
  }
}

CSS 隔离方案

  1. Shadow DOM:真正的隔离
  2. CSS Module:类名哈希
  3. Dynamic Stylesheet:动态添加/移除样式

4. Module Federation 的实现原理是什么?

难度:⭐⭐⭐⭐(专家)
标签:#ModuleFederation #Webpack

参考答案要点

核心概念

Plain Text
Host(宿主应用)
    ↓
加载 Remote(远程应用)暴露的模块
    ↓
共享依赖(Shared Dependencies)

配置示例

JAVASCRIPT
// 远程应用(Remote)
// webpack.config.js
const { ModuleFederationPlugin } = require("webpack").container

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "app2",
      filename: "remoteEntry.js",
      exposes: {
        "./Button": "./src/Button",
        "./utils": "./src/utils",
      },
      shared: ["react", "react-dom"],
    }),
  ],
}

// 宿主应用(Host)
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "app1",
      remotes: {
        app2: "app2@http://localhost:3002/remoteEntry.js",
      },
      shared: ["react", "react-dom"],
    }),
  ],
}

// 使用
const Button = React.lazy(() => import("app2/Button"))

原理

  1. 远程应用打包时暴露模块
  2. 宿主应用运行时加载远程应用的 remoteEntry.js
  3. 通过全局变量获取远程模块
  4. 共享依赖避免重复加载

5. 微前端如何共享状态?

难度:⭐⭐⭐(高级)
标签:#微前端 #状态管理

参考答案要点

方案对比

方案适用场景实现方式
URL 参数简单数据?userId=123
CustomEvent事件通信window.dispatchEvent
全局状态复杂应用Redux/Vuex + 持久化
Props 传递父子关系主应用传递
发布订阅解耦通信EventBus

推荐方案

JAVASCRIPT
// 全局状态管理(推荐)
// 主应用创建 Store
import { createStore } from 'redux'

const globalStore = createStore(reducer)

// 通过 props 传递给微应用
<MicroApp store={globalStore} />

// 微应用接收并使用
function MicroApp({ store }) {
  store.subscribe(() => {
    console.log(store.getState())
  })
}

二、组件库设计

6. 如何设计一个组件库?

难度:⭐⭐⭐(高级)
标签:#组件库 #设计

参考答案要点

设计原则

  1. 单一职责:每个组件只做一件事
  2. 可复用性:props 配置,支持多种场景
  3. 可扩展性:支持自定义样式和行为
  4. 一致性:API 设计统一
  5. 可访问性:支持键盘导航、屏幕阅读器

目录结构

Plain Text
my-ui/
├── src/
│   ├── components/       # 组件
│   │   ├── Button/
│   │   │   ├── Button.tsx
│   │   │   ├── Button.vue
│   │   │   ├── style.css
│   │   │   └── index.ts
│   │   └── Input/
│   ├── styles/           # 公共样式
│   ├── utils/            # 工具函数
│   └── index.ts          # 入口
├── docs/                 # 文档
├── tests/                # 测试
├── package.json
└── vite.config.ts

技术选型

  • 框架:Vue 3 / React 18
  • 构建:Vite / Rollup
  • 样式:CSS Variable / SCSS
  • 文档:Storybook / VitePress
  • 测试:Vitest / Jest

7. 组件库如何实现主题定制?

难度:⭐⭐⭐(高级)
标签:#组件库 #主题

参考答案要点

方案一:CSS 变量(推荐)

CSS
:root {
  --primary-color: #1890ff;
  --border-radius: 4px;
  --font-size-base: 14px;
}

.btn {
  background: var(--primary-color);
  border-radius: var(--border-radius);
}

方案二:SCSS 变量

SCSS
// _variables.scss
$primary-color: #1890ff !default;
$border-radius: 4px !default;

// 用户覆盖
@import "~my-ui/styles/variables";
$primary-color: #ff4d4f;
@import "~my-ui/styles/index";

方案三:CSS-in-JS

JAVASCRIPT
const theme = {
  primaryColor: "#1890ff",
  borderRadius: "4px",
}

const Button = styled.button`
  background: ${(props) => props.theme.primaryColor};
`

8. 组件库如何实现按需加载?

难度:⭐⭐⭐(高级)
标签:#组件库 #按需加载

参考答案要点

方案一:ES Module(推荐)

JAVASCRIPT
// 用户按需引入
import { Button, Input } from "my-ui"

// 构建工具自动 Tree-shaking

方案二:Babel 插件

JAVASCRIPT
// .babelrc
{
  "plugins": [
    ["import", {
      "libraryName": "my-ui",
      "libraryDirectory": "es",
      "style": true  // 自动引入样式
    }]
  ]
}

// 源码
import { Button } from 'my-ui'

// 编译后
import Button from 'my-ui/es/button'
import 'my-ui/es/button/style'

方案三:手动按需引入

JAVASCRIPT
import Button from "my-ui/lib/button"
import "my-ui/lib/button/style.css"

三、低代码平台

9. 低代码平台的核心设计思路是什么?

难度:⭐⭐⭐(高级)
标签:#低代码 #架构

参考答案要点

核心概念

  • 可视化设计:拖拽组件生成页面
  • 数据驱动:JSON Schema 定义页面结构
  • 代码生成:可视化配置生成代码
  • 扩展能力:支持自定义组件和逻辑

架构分层

Plain Text
┌─────────────────────────────────────┐
│           设计器(Designer)          │
│  ┌─────────┐ ┌─────────┐ ┌────────┐ │
│  │ 组件面板 │ │ 画布区  │ │ 属性面板│ │
│  └─────────┘ └─────────┘ └────────┘ │
└─────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────┐
│           渲染器(Renderer)          │
│      解析 JSON Schema 渲染页面        │
└─────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────┐
│           运行时(Runtime)           │
│    状态管理、事件处理、API 调用       │
└─────────────────────────────────────┘

核心模块

  1. 物料系统:组件注册、分类、版本管理
  2. Schema 协议:页面配置标准格式
  3. 设计器引擎:拖拽、选中、撤销重做
  4. 代码生成器:可视化配置转代码
  5. 扩展系统:自定义组件、插件

10. 低代码平台的 Schema 如何设计?

难度:⭐⭐⭐⭐(专家)
标签:#低代码 #Schema

参考答案要点

Schema 结构

JSON
{
  "type": "page",
  "title": "用户管理",
  "body": [
    {
      "type": "form",
      "api": "/api/users",
      "body": [
        {
          "type": "input-text",
          "name": "username",
          "label": "用户名",
          "required": true
        },
        {
          "type": "input-number",
          "name": "age",
          "label": "年龄"
        }
      ]
    },
    {
      "type": "table",
      "source": "${users}",
      "columns": [
        { "name": "id", "label": "ID" },
        { "name": "username", "label": "用户名" }
      ]
    }
  ]
}

设计原则

  1. 声明式:描述做什么,而非怎么做
  2. 可扩展:支持自定义组件类型
  3. 可校验:JSON Schema 校验
  4. 可转换:支持导入/导出代码

11. 低代码平台如何支持自定义逻辑?

难度:⭐⭐⭐⭐(专家)
标签:#低代码 #扩展

参考答案要点

方案对比

方案优点缺点
可视化逻辑编排易用复杂逻辑受限
代码编辑器灵活需要编程能力
JS 表达式平衡安全性问题

推荐方案

JAVASCRIPT
// JS 表达式(推荐)
{
  "type": "button",
  "label": "提交",
  "onClick": "${submitForm()}",
  "visible": "${form.status === 'draft'}"
}

// 安全沙箱执行
function safeEval(expression, context) {
  const sandbox = new Proxy(context, {
    has() { return true },
    get(target, key) {
      if (key === 'window' || key === 'document') {
        throw new Error('禁止访问全局对象')
      }
      return target[key]
    }
  })

  return new Function('context', `with(context) { return ${expression} }`)(sandbox)
}

四、性能监控与埋点

12. 如何设计前端性能监控系统?

难度:⭐⭐⭐⭐(专家)
标签:#性能监控 #架构

参考答案要点

系统架构

Plain Text
┌─────────────────────────────────────────┐
│              数据采集层(SDK)             │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ Web Vitals │ │ 资源加载 │ │ 错误监控   │ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              数据传输层                  │
│      Beacon / Fetch / WebSocket         │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              数据处理层                  │
│    数据清洗 → 聚合计算 → 存储(ES/ClickHouse)│
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              数据展示层                  │
│         可视化平台 / 告警系统            │
└─────────────────────────────────────────┘

核心指标

指标说明目标值
FPFirst Paint< 1.8s
FCPFirst Contentful Paint< 1.8s
LCPLargest Contentful Paint< 2.5s
FIDFirst Input Delay< 100ms
CLSCumulative Layout Shift< 0.1
TTFBTime to First Byte< 600ms

13. 如何实现前端错误监控?

难度:⭐⭐⭐(高级)
标签:#错误监控

参考答案要点

错误类型

JAVASCRIPT
// 1. JavaScript 错误
window.addEventListener("error", (event) => {
  reportError({
    type: "js",
    message: event.message,
    filename: event.filename,
    lineno: event.lineno,
    colno: event.colno,
    stack: event.error?.stack,
  })
})

// 2. Promise 未捕获错误
window.addEventListener("unhandledrejection", (event) => {
  reportError({
    type: "promise",
    message: event.reason?.message || "Promise rejected",
    stack: event.reason?.stack,
  })
})

// 3. 资源加载错误
window.addEventListener(
  "error",
  (event) => {
    if (event.target !== window) {
      reportError({
        type: "resource",
        url: event.target.src || event.target.href,
        tagName: event.target.tagName,
      })
    }
  },
  true
)

// 4. Vue/React 错误(框架捕获)
// Vue
app.config.errorHandler = (err, vm, info) => {
  reportError({ type: "vue", error: err, info })
}

// React
class ErrorBoundary extends React.Component {
  componentDidCatch(error, errorInfo) {
    reportError({ type: "react", error, errorInfo })
  }
}

14. 如何实现用户行为埋点?

难度:⭐⭐⭐(高级)
标签:#埋点 #监控

参考答案要点

埋点类型

类型说明示例
PV/UV页面访问页面浏览量
点击埋点用户点击按钮点击、链接点击
曝光埋点元素可见广告曝光、商品曝光
性能埋点性能指标加载时间、接口耗时
错误埋点异常监控JS 错误、接口错误

实现方案

JAVASCRIPT
// 自动埋点(推荐)
// 通过事件委托自动采集
class AutoTracker {
  constructor() {
    this.initClickTracking()
    this.initExposureTracking()
  }

  initClickTracking() {
    document.addEventListener("click", (e) => {
      const target = e.target.closest("[data-track]")
      if (target) {
        this.track({
          type: "click",
          element: target.dataset.track,
          text: target.textContent,
          path: location.pathname,
        })
      }
    })
  }

  initExposureTracking() {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          this.track({
            type: "exposure",
            element: entry.target.dataset.exposure,
          })
        }
      })
    })

    document.querySelectorAll("[data-exposure]").forEach((el) => {
      observer.observe(el)
    })
  }

  track(data) {
    // 上报数据
    navigator.sendBeacon("/api/track", JSON.stringify(data))
  }
}

五、前端工程化架构

15. 如何设计前端工程化体系?

难度:⭐⭐⭐(高级)
标签:#工程化 #架构

参考答案要点

工程化体系

Plain Text
┌─────────────────────────────────────────┐
│              开发阶段                    │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ 代码规范 │ │ 脚手架  │ │ 本地Mock   │ │
│  │ (ESLint)│ │        │ │            │ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              构建阶段                    │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ 代码转换 │ │ 资源处理 │ │ 代码优化   │ │
│  │(Babel)  │ │(Webpack)│ │ (压缩/分割)│ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              部署阶段                    │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ CI/CD   │ │ 自动化测试│ │ 灰度发布   │ │
│  │(GitHub  │ │        │ │            │ │
│  │ Actions)│ │        │ │            │ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              监控阶段                    │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ 性能监控 │ │ 错误监控 │ │ 用户反馈   │ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘

核心能力

  1. 标准化:代码规范、提交规范、目录结构
  2. 自动化:构建、测试、部署
  3. 可视化:构建分析、性能报告
  4. 可度量:代码质量、性能指标

16. 如何设计 Monorepo 架构?

难度:⭐⭐⭐(高级)
标签:#Monorepo #架构

参考答案要点

Monorepo vs Polyrepo

特性MonorepoPolyrepo
代码共享容易困难(需发布 npm)
版本管理统一分散
构建优化支持增量构建独立构建
团队协作代码可见隔离
适用场景大型项目、多包项目独立项目

工具选择

工具特点适用
pnpm workspace轻量、高效中小型项目
Turborepo增量构建、缓存大型项目
Nx功能丰富、插件多企业级项目
Rush微软出品、规范超大型项目

目录结构

Plain Text
my-monorepo/
├── apps/                 # 应用
│   ├── web/              # Web 应用
│   ├── admin/            # 管理后台
│   └── mobile/           # 移动端
├── packages/             # 共享包
│   ├── ui/               # UI 组件库
│   ├── utils/            # 工具函数
│   └── hooks/            # 共享 Hooks
├── package.json          # 根配置
├── pnpm-workspace.yaml   # pnpm 工作区
└── turbo.json            # Turborepo 配置

17. 如何实现前端自动化部署?

难度:⭐⭐⭐(高级)
标签:#CI/CD #部署

参考答案要点

CI/CD 流程

Plain Text
代码提交 → 触发构建 → 运行测试 → 构建产物 → 部署 → 通知

GitHub Actions 配置

YAML
# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "18"

      - name: Install pnpm
        uses: pnpm/action-setup@v2

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test

      - name: Build
        run: pnpm build

      - name: Deploy to CDN
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          source: "dist/*"
          target: "/var/www/html"

部署策略

策略说明适用
全量部署替换所有文件小型项目
增量部署只更新变更文件大型项目
蓝绿部署两套环境切换高可用要求
金丝雀发布灰度放量风险控制

六、安全架构

18. 前端安全架构如何设计?

难度:⭐⭐⭐(高级)
标签:#安全 #架构

参考答案要点

安全体系

Plain Text
┌─────────────────────────────────────────┐
│              应用层安全                  │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ XSS 防护 │ │ CSRF 防护│ │ 点击劫持   │ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              传输层安全                  │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ HTTPS   │ │ HSTS    │ │ 证书固定   │ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────┐
│              数据层安全                  │
│  ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │ 输入校验 │ │ 输出编码 │ │ 敏感数据   │ │
│  └─────────┘ └─────────┘ └────────────┘ │
└─────────────────────────────────────────┘

防护措施

威胁防护措施
XSSCSP、输入过滤、输出编码、HttpOnly Cookie
CSRFToken、SameSite Cookie、Referer 检查
点击劫持X-Frame-Options、CSP frame-ancestors
中间人攻击HTTPS、HSTS、证书固定

19. 如何实现前端代码安全?

难度:⭐⭐⭐(高级)
标签:#安全 #代码保护

参考答案要点

代码保护方案

方案说明效果
代码混淆变量名压缩、控制流扁平化增加阅读难度
Source Map 保护不部署到生产环境防止源码泄露
WebAssembly核心逻辑用 C++/Rust 编写提高逆向难度
域名绑定代码校验域名防止盗用
动态加载核心代码动态获取减少静态分析

配置示例

JAVASCRIPT
// vite.config.js
export default {
  build: {
    sourcemap: false, // 不生成 source map
    minify: "terser",
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true,
      },
      mangle: {
        properties: true, // 混淆属性名
      },
    },
  },
}

七、复习建议

重点题目清单

必会题目(⭐⭐⭐ 高频)

  1. 微前端实现方案和选型
  2. qiankun/Module Federation 原理
  3. 组件库设计(主题定制、按需加载)
  4. 性能监控系统设计
  5. 前端工程化体系

重点掌握(⭐⭐ 常考)

  1. 低代码平台设计
  2. 错误监控和埋点
  3. Monorepo 架构
  4. CI/CD 流程
  5. 前端安全架构

加分项(⭐ 了解)

  1. 代码保护方案
  2. 灰度发布策略
  3. 多租户架构

面试技巧

  1. 结合实际项目:描述你在项目中如何应用这些架构
  2. 画图说明:架构图、流程图能更好表达思路
  3. 权衡利弊:每种方案都有优缺点,要会分析
  4. 关注前沿:了解最新的架构趋势(如 Rspack、Turbopack)

最后更新于: 2026-02-27