编程进阶网 编程进阶网
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • Android提升进阶

  • iOS开发和进阶

  • Web开发和进阶

    • README
    • HTML工具手册

    • CSS样式与布局

    • JavaScript核心

    • TypeScript入门

    • Vue高级进阶

    • Web工程化实践

      • 前端工程化概述
        • 1. 案例引入:当项目从 10 个文件变成 1000 个
        • 2. 前端工程化的四个核心维度
        • 3. 模块化:从全局变量到 ESM
          • 3.1 蛮荒时期:全局变量与命名空间
          • 3.2 CommonJS:Node.js 的模块化
          • 3.3 AMD:浏览器端的异步模块
          • 3.4 ES Module:标准答案
          • 3.5 各方案对比
        • 4. 构建工具:为什么需要"打包"?
          • 4.1 一段没有构建工具的"现代"代码
          • 4.2 构建工具做什么
          • 4.3 三大构建工具演进
        • 5. 包管理器:npm / yarn / pnpm
          • 5.1 npm 的依赖地狱
          • 5.2 锁文件:确保团队环境一致
          • 5.3 pnpm:更快更省空间
          • 5.4 依赖类型速查
        • 6. 工程化工具链全景
        • 7. 速查表
      • Webpack构建实战
      • Vite构建实战
      • 代码规范与质量
      • 前端性能优化
  • Linux应用开发

  • IoT智能硬件开发

  • Apps
  • Web开发和进阶
  • Web工程化实践
杨充
2026-06-23
目录

前端工程化概述

# 01.前端工程化概述

从手写 script 标签到现代化构建体系——理解前端工程化的演进脉络、核心问题与解决范式。

# 1. 案例引入:当项目从 10 个文件变成 1000 个

# 2015 年,一个"小项目"的文件数量:
js/
  jquery.min.js      # 第三方库
  app.js             # 主逻辑(800行)
  utils.js           # 工具函数(200行)

# 2023 年,同样业务的项目:
src/
  components/BaseButton.vue
  components/UserCard.vue
  ...(还有 80+ 个组件)
  composables/useAuth.ts
  stores/user.ts
  ...(还有 30+ 个模块)

# 问题来了:
# 1. 这些文件之间的依赖关系怎么管理?
# 2. CSS/图片/字体/TS 文件怎么"打包"到一起?
# 3. 开发时怎么做到修改代码后 0.3 秒就看到效果?
# 4. 生产环境怎么压缩到 200KB 以内?

前端工程化要解决的就是这四个核心问题。本文提供全景概览,后续各篇深入展开。


# 2. 前端工程化的四个核心维度

                 ┌──────────────────────┐
                 │     前端工程化        │
                 └──────────┬───────────┘
          ┌─────────┬───────┼───────┬─────────┐
          ▼         ▼       ▼       ▼         ▼
    ┌─────────┐ ┌──────┐ ┌───────┐ ┌──────┐ ┌──────┐
    │ 模块化  │ │构建  │ │ 规范  │ │ 测试  │ │ 部署  │
    │ CJS/ESM │ │打包  │ │Lint   │ │Jest  │ │CI/CD │
    │ TS集成  │ │编译  │ │Format │ │E2E   │ │容器化│
    │ 依赖    │ │优化  │ │GitHook│ │      │ │监控  │
    └─────────┘ └──────┘ └───────┘ └──────┘ └──────┘

# 3. 模块化:从全局变量到 ESM

# 3.1 蛮荒时期:全局变量与命名空间

// 2005 年——所有脚本挂 window
// <script src="jquery.js"></script>
// <script src="app.js"></script>
// <script src="utils.js"></script>
window.$ = jQuery;           // 全局污染
window.MY_APP = {};          // 手动"命名空间"
window.MY_APP.utils = {};    // 嵌套命名空间——但本质还是全局变量

问题:依赖顺序必须手动管理,变量名冲突,无法 Tree Shaking。

# 3.2 CommonJS:Node.js 的模块化

// a.js
module.exports = { foo: 1 };

// b.js
const a = require('./a');
console.log(a.foo);  // 1

特点:同步加载(适合 Node),动态 require,运行时解析;不能在浏览器中直接使用。

# 3.3 AMD:浏览器端的异步模块

// RequireJS 时代
define(['jquery', 'utils'], function($, utils) {
    return { init: function() {} };
});

特点:异步加载,但语法冗长,依赖前置声明。

# 3.4 ES Module:标准答案

// 静态导入——编译时确定依赖关系
import { ref, computed } from 'vue';
import type { User } from './types';

// 动态导入——运行时按需加载
const module = await import('./heavy-component.vue');

// 静态结构 → Tree Shaking 成为可能
// 编译时分析 → 构建工具可以精确定位依赖

# 3.5 各方案对比

方案 加载方式 TreeShaking 浏览器 Node 现状
全局变量 手动 ❌ ✅ ✅ 被淘汰
CommonJS 同步 require ❌ ❌ ✅ Node 传统
AMD 异步 define ❌ ✅ ❌ 被淘汰
ES Module 静态 import ✅ ✅ ✅ 标准

# 4. 构建工具:为什么需要"打包"?

# 4.1 一段没有构建工具的"现代"代码

<!-- 浏览器无法直接识别这些文件 -->
<script type="module">
    import { ref } from 'vue';              // ❌ 找不到模块
    import style from './app.css';          // ❌ 浏览器不支持 CSS import
    import logo from './logo.png';          // ❌ 浏览器不支持图片 import
    import { fetchUser } from '@/api/user'; // ❌ 路径别名浏览器不理解
</script>

# 4.2 构建工具做什么

源码(开发者写的)→ 构建工具 → 产物(浏览器能运行的)

转换内容:
  .vue/.tsx  → .js              语法转换
  .scss      → .css             样式编译
  @/api/user → ./src/api/user   路径解析
  import()   → 代码分割         按需加载
  console.log → (移除)          压缩优化
  图片 > 8KB  → base64 / URL     资源处理

构建结果(dist/):
  index.html                     入口 HTML
  assets/index-[hash].js         主 JS bundle
  assets/vendor-[hash].js        第三方库 bundle
  assets/index-[hash].css        样式文件
  assets/logo.[hash].png         图片资源

# 4.3 三大构建工具演进

2012  Grunt   ─→  任务运行器(手动配置每个转换步骤)
2014  Gulp    ─→  流式构建(比 Grunt 快)
2014  Webpack ─→  bundler 时代(一切皆模块,loader/plugin 生态)
2020  Vite    ─→  ESM 原生支持(开发环境 0 打包,毫秒级启动)

Webpack 的核心贡献:提出 "一切皆模块" 的理念,通过 Loader 处理非 JS 文件,Plugin 扩展构建流程。

Vite 的核心创新:开发环境不打包,利用浏览器原生 ESM;生产环境用 Rollup 打包。


# 5. 包管理器:npm / yarn / pnpm

# 5.1 npm 的依赖地狱

项目 A 依赖 lodash@4.17.0
项目 A 同时依赖 dep-b,而 dep-b 依赖 lodash@3.10.0

npm v2:
  node_modules/
    A/
      node_modules/lodash@4.17.0   ← 嵌套,目录超深
    dep-b/
      node_modules/lodash@3.10.0   ← 嵌套,重复安装

npm v3+:
  node_modules/
    lodash@4.17.0                   ← 扁平化(提升到顶层)
    dep-b/
      node_modules/lodash@3.10.0   ← 版本冲突时保留嵌套

# 5.2 锁文件:确保团队环境一致

package.json      → "lodash": "^4.17.0"   语义化范围
package-lock.json → "lodash": "4.17.21"   精确版本(提交到 Git)

# 为什么需要锁文件?
# A 电脑安装时为 4.17.21
# 一周后 ^4.17.0 可能已经更新到 4.17.25
# B 电脑安装时会安装 4.17.25——团队不一致!
# 锁文件确保:所有人安装相同的依赖树

# 5.3 pnpm:更快更省空间

npm/yarn:每个项目独立安装 node_modules(100 个项目 → 100 份依赖副本)
pnpm:    全局存储 + 硬链接(100 个项目 → 1 份存储 + 硬链接)

优势:
  1. 磁盘节省 50%+
  2. node_modules 非扁平化(更严格——防止幽灵依赖)
  3. 安装速度更快

# 5.4 依赖类型速查

{
  "dependencies": {
    "vue": "^3.4.0"        // 生产需要
  },
  "devDependencies": {
    "vite": "^5.0.0",      // 仅开发需要
    "typescript": "^5.3.0",
    "eslint": "^8.0.0"
  },
  "peerDependencies": {
    "vue": "^3.0.0"        // 宿主项目需要安装(插件库常用)
  }
}

# 6. 工程化工具链全景

开发阶段                   构建阶段                    部署阶段
┌──────────┐    ┌──────────┐    ┌──────────┐
│ ESLint   │    │ Webpack  │    │ Docker   │
│ Prettier │───→│ / Vite   │───→│ / Nginx  │
│ TS Check │    │ 编译打包  │    │ CDN/OSS  │
└──────────┘    └──────────┘    └──────────┘
     │               │               │
     │               └─ 代码分割      └─ 静态资源
     │                  TreeShaking     Gzip 压缩
     │                  CSS 提取        缓存策略
     │                  JS 压缩
     │                  SourceMap
     │
     └─ Git Hooks (Husky)
        提交前 Lint (lint-staged)
        Commit Message (Commitlint)

# 7. 速查表

维度 工具 一句话
模块化 ESM (import/export) 标准答案,浏览器+Node 通用
构建 Vite (新) / Webpack Vite 开发快,Webpack 生态全
包管理 pnpm 最快最省空间,严格依赖
代码规范 ESLint + Prettier 查错 + 格式化
Git Husky + lint-staged 提交前自动检查
CI/CD GitHub Actions / Jenkins 自动化测试和部署

工程化的本质:不是某个工具,而是一套从源码到生产环境的可控、可复现、可优化的流程体系。


下一篇:02.Webpack构建实战

上次更新: 2026/06/24, 14:17:21
Vue工程化实践
Webpack构建实战

← Vue工程化实践 Webpack构建实战→

最近更新
01
CSS选择器入门
06-23
02
CSS定位与层级
06-23
03
CSS盒模型详解
06-23
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 鄂ICP备2024073355号-1 | 鄂ICP备2024073355号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式