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

  • 产品思考

  • 软实力

  • 开发流程

  • Git应用

  • 技术模版

  • 技术规范

  • markdown

  • mermaid

  • license

  • 博客部署

    • CloudBase 一键部署博客
    • 构建排雷指南
      • dev 为什么秒开,build 却总崩
      • 问题 1:JavaScript heap out of memory
        • 现象
        • 原因
        • 修复
      • 问题 2:SSR 包过大导致 JSON.stringify 溢出
        • 现象
        • 原因
        • 修复
      • 问题 3:代码块内 SFC 标签被误解析
        • 现象
        • 原因
        • 修复
      • 问题 4:同级文件编号重复
        • 现象
        • 原因
        • 修复
      • 完整构建命令
      • 内存优化清单
      • 为什么 dev 没这些事
  • 技术招聘

  • 测试经验

  • 技术
  • 博客部署
杨充
2020-07-18
目录

构建排雷指南

博客超过 1000 页后,VuePress v1 原生 npm run build 踩坑全记录。

# dev 为什么秒开,build 却总崩

              dev                           build
              ───                           ─────
编译范围      按需(访问哪页编译哪页)        全量(1000+页一次性干完)
SSR渲染       不生成                         每页生成服务端 HTML
代码优化      不压缩                         压缩/摇树/提取CSS/SourceMap
内存占用      低(几百MB)                    高(8GB 都不够)
输出文件      不写磁盘                       JSON.stringify(全部内容)
1
2
3
4
5
6
7

结论:博客体量超过 VuePress v1 原生 build 承载上限,需要工程手段兜底。


# 问题 1:JavaScript heap out of memory

# 现象

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
1
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed
1

# 原因

大量 Markdown 文件被全量加载到内存中编译。两个"大胖子"尤其耗内存:

  • 综合实战图片框架.md(120KB+)
  • JavaScript代码规范.md(95KB+)

Babel 在处理超 500KB 文件时会触发 deoptimised 警告,进一步加剧内存压力。

另外,增强代码(enhanceApp.js 中的安全防护)如果在服务端构建阶段执行(console.log + setInterval),会额外消耗内存。

# 修复

Step 1:package.json 中把 Node 内存上限提到 12GB,并开启 GC 优化:

{
  "scripts": {
    "build": "export NODE_OPTIONS='--localstorage-file=/tmp/vuepress-localstorage.json --optimize-for-size --max-semi-space-size=64' && node --max_old_space_size=12288 ./node_modules/.bin/vuepress build docs"
  }
}
1
2
3
4
5
参数 作用
--max_old_space_size=12288 堆上限 12GB
--optimize-for-size V8 编译优化倾向体积而非速度
--max-semi-space-size=64 限制年轻代空间,触发更频繁的小回收

Step 2:每次构建前清理缓存(VuePress 的 .temp 目录不会自动清理):

rm -rf node_modules/.cache docs/.vuepress/.temp node_modules/@vuepress/core/.temp
1

Step 3:config.ts 中关闭 SourceMap + 限制并行线程 + 启用 evergreen:

// docs/.vuepress/config.ts
module.exports = {
  evergreen: true,  // 只编译到 ES2015+,砍掉 IE11 polyfill

  chainWebpack(config, isServer) {
    if (isServer) {
      config.plugins.delete('vue-server-renderer-server-plugin')
    }
    config.devtool(false)      // 关闭 SourceMap(省 30% 内存)
    config.parallelism(2)      // 限制 2 线程(避免 8 核同时编译)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

Step 4:安全防护代码包进客户端判断,防止 build 阶段执行:

// docs/.vuepress/enhanceApp.js
if (typeof window !== 'undefined') {
  // 所有安全防护代码放在这里(console.log / setInterval / copy 拦截等)
}
1
2
3
4

# 问题 2:SSR 包过大导致 JSON.stringify 溢出

# 现象

RangeError: Invalid string length
    at JSON.stringify
    at /node_modules/vue-server-renderer/server-plugin.js:139
1
2
3

# 原因

SSR(服务端渲染)会将 1000+ 页的完整 HTML 全部塞到一个包里,再用 JSON.stringify 序列化。V8 引擎的字符串上限约 256MB,1000 页的渲染后 HTML 轻易怼穿天花板。

# 修复

注意:evergreen: true 单独使用不够,必须同时禁用 SSR。

完整配置:

// docs/.vuepress/config.ts
module.exports = {
  // Step 1: 只编译到 ES2015+,减少 polyfill
  evergreen: true,

  // Step 2: 禁用 SSR 服务端渲染
  chainWebpack(config, isServer) {
    if (isServer) {
      config.plugins.delete('vue-server-renderer-server-plugin')
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

代价:首屏 SEO 略差(百度可能抓不到 HTML 内容),但对技术博客影响有限。


# 问题 3:代码块内 SFC 标签被误解析

# 现象

SyntaxError: [@vue/compiler-sfc] Unexpected character '│'. (1:8)
    at vue-loader → markdown-loader → docs/17.Apps/03.Web/04.Vue高级进阶/01.基础入门.md
1
2

# 原因

VuePress 把每个 .md 文件封装成一个 Vue 组件:

<template> <!-- 渲染后的 markdown -->
<script>   <!-- 页面逻辑 -->
<style>    <!-- 页面样式 -->
1
2
3

当 markdown 代码围栏里出现 <script>、<template>、<style> 标签时(尤其在 ASCII 绘图中),Vue SFC 编译器会把它们当成组件的第二个 <script> 块来解析,导致语法错乱。

# 修复

用 HTML 实体替换代码围栏内的尖括号标签:

- │ <script setup lang="ts">        │
+ │ &lt;script setup lang="ts"&gt;   │
1
2

同时也适用于 <template> → &lt;template&gt;、</script> → &lt;/script&gt; 等。

排查方法:grep 搜索所有 .md 文件中代码围栏内的裸露标签:

grep -n '<script\|</script>\|<template\|</template>\|<style\|</style>' docs/**/*.md
1

# 问题 4:同级文件编号重复

# 现象

warning: 该文件 "xxx.md" 的序号在同一级别中重复出现,将会被覆盖
1

# 原因

Vdoing 主题要求同目录下文件编号(NN. 前缀)必须唯一。如果有两个 01. 开头的文件,后一个会覆盖前一个。

# 修复

检查该目录,合并或重命名重复编号的文件:

# 示例:发现两个 01. 前缀文件
01.面试准备.md          # 占位符
01.面试问题集锦.md      # 257行实文

# 修复:合并内容,保留唯一编号
mv 01.面试问题集锦.md 01.面试准备.md
1
2
3
4
5
6

# 完整构建命令

# 1. 清理缓存
rm -rf node_modules/.cache docs/.vuepress/.temp node_modules/@vuepress/core/.temp

# 2. 构建(12GB 内存上限 + GC 优化 + SourceMap 关闭)
npm run build

# 3. 部署
npm run deploy
1
2
3
4
5
6
7
8

# 内存优化清单

优化项 位置 预计节省
关闭 SourceMap config.ts → chainWebpack ~30%
限制并行 2 线程 config.ts → config.parallelism(2) ~40%
Node GC 激进回收 package.json → NODE_OPTIONS 减少碎片
安全代码仅客户端 enhanceApp.js → if (window) 消除 SSR 端泄漏
禁用 SSR config.ts → 删 server plugin 消除 JSON.stringify 溢出

# 为什么 dev 没这些事

维度 dev build
编译方式 懒加载,访问才编译 全量一次性
SSR 渲染 不执行 已禁用(chainWebpack)
SourceMap 生成(方便调试) 已关闭
并行线程 按需 限制 2 线程
内存峰值 几百 MB 4-12GB
单文件处理 按需 1000+ 篇全上

dev 是"来一桌上一桌",build 是"100 桌一起做"——厨房不炸才怪 ⚡

#VuePress#构建
上次更新: 2026/06/10, 10:26:15
CloudBase 一键部署博客

← CloudBase 一键部署博客

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式