JS 压缩
JS 压缩就是在不改变运行结果的前提下,删掉 JavaScript 里的注释、缩进和换行,把局部变量名缩短成单个字母,让 .js 文件变小、加载更快。本工具用 webpack / Vite 同款的 terser 内核,把代码压成一行,/*! 版权注释保留,可选删除 console;代码只在你的浏览器里处理,不上传也不执行。
请粘贴 JavaScript 代码,或点「填入示例」先看效果。
🔒 代码在你的浏览器内压缩,未上传任何服务器,也不会被执行;只记住压缩选项,代码内容不落盘。
如何使用JS 压缩
JS 怎么压缩:在上方文本框粘贴 JavaScript,或把 .js / .mjs / .cjs 文件拖进来(浏览器本地处理、代码不上传),也可以先点「填入示例」看效果。
默认开着「精简代码」「缩短变量名」「保留版权注释」,粘贴即出结果;要去掉 console.log 就勾「删除 console」,代码类型保持「自动识别」即可。超过 100KB 时改为点「开始压缩」。
核对体积账本:压缩前后字节数、节省比例与 gzip 估算,以及按普通脚本还是 ES 模块压缩;确认无误后点「复制结果」或「下载 .min.js」。
关于JS 压缩的常见问题
- JS 压缩会上传我的代码吗?
- 不会。JS 压缩全程在你的浏览器里完成,压缩引擎在后台线程(Web Worker)里运行,代码不发到任何服务器,内网项目、后台脚本都可以放心粘。本工具也不会执行你的代码,只把它当文本解析后重新输出。页面只把开关偏好记在本机 localStorage,代码内容和结果一律不落盘。
- 手机上能用 JS 在线压缩吗?
- 能。JS 在线压缩是纯网页实现,手机、平板、电脑浏览器打开即用,免安装免注册。窄屏上输入框、开关和结果框上下排列,每个开关整行都可以点;压缩完可以直接复制结果,或下载成 .min.js 文件。
- JS 压缩后代码会不会出错?
- 默认只启用 terser 的安全规则,普通脚本的顶层函数名、变量名不改,对象属性名永远不改,绝大多数代码压缩后照常运行。会受影响的主要是三类写法:依赖函数名或类名(Function.name、constructor.name)的代码,请勾「保留函数名与类名」;依赖 fn.toString() 读源码文本的代码,压缩后文本必然不同;把一段直接用 script 标签引用的脚本按 ES 模块压缩,没被导出的顶层代码会被删掉,请把代码类型改成「普通脚本」。
- JS 压缩能防止别人看懂代码吗?
- 不能把它当加密用。JS 压缩只是把局部变量名缩短成单个字母、删掉注释和空白,属性名、字符串和整体逻辑都还在;把结果贴进 JS 格式化就能恢复缩进与结构,只是局部变量名回不来。本工具不做字符串加密、控制流打乱这类混淆,也不能保证别人读不懂。
- JS 压缩为什么提示语法错误?
- 本工具先把代码完整解析成语法树再压缩,只要有一处语法错误就会停下,并告诉你第几行第几列。最常见的三个原因:从聊天软件或文档复制代码时带进了中文全角标点(可用全角半角转换批量换回);粘的是 TypeScript 或 JSX,需要先编译;代码复制不完整,结尾少了括号。
- JS 压缩支持 TypeScript 和 JSX 吗?
- 不支持,请先用 tsc、Babel 或 Vite 编译成 JavaScript 再来压缩。本工具只认浏览器能直接运行的标准 JavaScript,ES2022 以后的新语法都支持,例如 class 私有字段、static 块、可选链、空值合并与 BigInt;识别到类型注解或 JSX 标签时,报错卡会直接提示先编译。
- JS 压缩能保留版权注释吗?
- 能。以 /*! 开头的注释,以及含 @license、@preserve、@copyright 的注释默认保留,这与 webpack、Vite 的惯例一致;保留的注释后面会换一行,所以默认档结果通常是两行。关掉「保留版权注释」则全部注释都删除。
- JS 压缩能删掉 console.log 吗?
- 能,勾选「删除 console」即可去掉 console.log。注意它会删掉所有 console 调用,包括 console.error 和 console.warn,上线前要确认没有依赖它们输出的错误日志;这一项依附于「精简代码」,关掉精简代码时它不可勾选。
- JS 压缩能省多少体积?开了 gzip 还要压吗?
- 用本页「填入示例」那份脚本实测:755 字节压到 419 字节,省 44.5%;各自 gzip 之后是 554 字节对 358 字节,仍然少 35.4%。服务器开了 gzip 时收益会变小但不归零,两者可以叠加;而且浏览器解析的是解压后的文本,代码越短解析越快。
- 为什么 JS 压缩不改顶层变量名?
- 普通脚本的顶层函数和变量是全局的,别的 script 文件或 HTML 里的 onclick 可能正在按名字调用它们,改名就会报找不到。只有按 ES 模块压缩时,模块作用域是私有的,顶层名字才会一起缩短。
- JS 压缩后函数名变了怎么办?
- 勾选「保留函数名与类名」。默认情况下内层函数可能被改名或去名,例如 inner.name 会从 inner 变成空字符串;自定义错误类按 constructor.name 判断类型、按类名注册组件、日志里打印函数名的代码都需要开这一项,代价是结果略大一点。
- JS 压缩最大支持多大的文件?
- 单次上限 2MB(按 UTF-8 字节计),常见的业务脚本与第三方库都够用。100KB 以内边输入边压缩;超过 100KB 会关掉自动压缩,改为点「开始压缩」;大文件在后台线程处理、页面不卡,超过 30 秒会自动停止并提示拆分。
JS 代码压缩的每个开关做了什么
JS 代码压缩分两层:删注释、去空格、压成一行是恒开的;其上的五个开关各管一件事,可以单独开关对比结果。
| 开关 | 作用 | 默认 | 什么时候改 |
|---|---|---|---|
| 精简代码 | 常量折叠、删掉永远不会执行的分支和 debugger、合并连续声明、false 写成 !1 | 开 | 只想去注释去空格、保持代码结构时关掉 |
| 缩短变量名 | JS 变量名压缩:函数内部的局部变量与参数改成 a、b、c,顶层名字与属性名不动 | 开 | 代码里用 eval 读局部变量时无需关,terser 会自动跳过那个作用域 |
| 保留版权注释 | 保留 /*! 开头与含 @license、@preserve 的注释 | 开 | 确定不需要许可声明、追求最小体积时关掉 |
| 删除 console | 去掉 console.log、console.error 等全部 console 调用 | 关 | 上线前想去掉 console.log 时开;依附于精简代码 |
| 保留函数名与类名 | 不缩短、不丢弃函数与类的名字 | 关 | 用了 err.constructor.name 判断错误类型、按类名注册组件时开 |
| 中文转 \u 转义 | 把字符串里的中文写成 \uXXXX,结果纯 ASCII | 关 | 脚本被 GBK 页面引用、或 script 标签没写 charset 导致中文乱码时开 |
所有开关都只是 terser 安全规则集的子集:不开 unsafe 系列、不做属性名混淆、不做多遍压缩。 想要更激进的压缩,请在自己的构建工具里配置并充分测试。
普通脚本和 ES 模块,JS 压缩的结果为什么不同
「代码类型」默认自动识别:顶层出现 import / export 声明、或用了顶层 await 时按 ES 模块压缩,否则按普通脚本。 两者的差别会直接体现在结果里:
| 普通脚本 | ES 模块 | |
|---|---|---|
| 顶层函数名、变量名 | 不改(可能被别的脚本或 onclick 调用) | 一起缩短(模块作用域是私有的) |
| 没被用到的顶层代码 | 保留 | 删掉(没被导出也没被用到就是无用代码) |
| with 语句、010 这类八进制写法 | 可以用 | 报错(模块恒为严格模式) |
| 怎么判断自己是哪种 | script 标签直接引用、没有 import / export | script type="module"、或代码里有 import / export |
同一段 var used = 1; function unused(){}:按普通脚本压缩得到 var used=1;function unused(){};按 ES 模块压缩得到空结果,因为 used 和 unused 都没被导出、也没被用到。如果你的脚本是直接用 script 标签引用的,遇到「压缩结果为空」就把代码类型改成「普通脚本」。
JS 压缩成一行:示例前后对比
页面里「填入示例」用的就是下面这份 27 行的购物车脚本:
/*! 小鹿tools 示例脚本 v1.0 | MIT */
// 计算购物车总价(演示用)
const TAX_RATE = 0.06;
const DEBUG = false;
function calcTotal(items, coupon) {
let total = 0;
for (const item of items) {
total += item.price * item.count;
}
if (DEBUG) {
console.log("调试:", total);
}
const discount = coupon ? coupon.amount : 0;
return Math.max(total - discount, 0) * (1 + TAX_RATE);
}
/* 把金额格式化成 "¥ 1,234.50" 这样的字符串 */
function formatPrice(value) {
return "¥ " + value.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
const cart = [
{ name: "笔记本", price: 12.5, count: 2 },
{ name: "钢笔", price: 30, count: 1 },
];
console.log(`合计:${formatPrice(calcTotal(cart, null))}`);
默认档(精简代码 + 缩短变量名 + 保留版权注释)的结果,版权注释后换一行,其余压成一行:
/*! 小鹿tools 示例脚本 v1.0 | MIT */
const TAX_RATE=.06,DEBUG=!1;function calcTotal(c,t){let o=0;for(const t of c)o+=t.price*t.count;const n=t?t.amount:0;return 1.06*Math.max(o-n,0)}function formatPrice(c){return"¥ "+c.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g,",")}const cart=[{name:"笔记本",price:12.5,count:2},{name:"钢笔",price:30,count:1}];console.log(`合计:${formatPrice(calcTotal(cart,null))}`);只删空白和注释(精简代码、缩短变量名都关)的结果:
/*! 小鹿tools 示例脚本 v1.0 | MIT */
const TAX_RATE=.06;const DEBUG=false;function calcTotal(items,coupon){let total=0;for(const item of items){total+=item.price*item.count}if(DEBUG){console.log("调试:",total)}const discount=coupon?coupon.amount:0;return Math.max(total-discount,0)*(1+TAX_RATE)}function formatPrice(value){return"¥ "+value.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g,",")}const cart=[{name:"笔记本",price:12.5,count:2},{name:"钢笔",price:30,count:1}];console.log(`合计:${formatPrice(calcTotal(cart,null))}`);| 版本 | 字节 | 节省 | gzip 后字节 |
|---|---|---|---|
| 压缩前 | 755 | — | 554 |
| 默认档 | 419 | 44.5% | 358 |
| 只删空白和注释 | 544 | 27.9% | 414 |
| 默认档 + 删除 console | 358 | 52.6% | 319 |
对比两份结果能看到 JS 压缩具体做了什么:普通注释删掉而 /*! 注释保留;顶层的 calcTotal、formatPrice、cart 名字不变,参数 items、coupon 与局部变量缩短成单个字母;DEBUG 恒为 false,整段调试分支被删掉;(1 + TAX_RATE) 折叠成 1.06;字符串、正则和模板字符串原样。 最后一行的 console.log(`合计:…`) 是这段脚本唯一的输出,勾选「删除 console」后它也会被删—— 这正是「删除 console」要慎用的原因。
JS 压缩后出问题怎么排查
| 现象 | 原因 | 怎么办 |
|---|---|---|
| 按类名判断错误类型失效、日志里函数名变成空 | 内层函数和类被改名或去名 | 勾「保留函数名与类名」 |
| 读 fn.toString() 的代码结果不对 | 压缩后源码文本必然不同 | 这类代码不适合压缩,或单独拎出来不压 |
| 压缩结果为空、页面上的按钮全失效 | 一段普通脚本被按 ES 模块压缩,顶层代码被当成无用代码 | 把代码类型改成「普通脚本」 |
| 页面上的中文变成乱码 | 页面或 script 标签不是 UTF-8 编码 | 勾「中文转 \u 转义」,结果与页面编码无关 |
| 线上报错没有日志 | 开了「删除 console」,console.error 也一起删了 | 关掉「删除 console」重新压缩 |
JS 压缩工具能做什么、不做什么
英文资料里这件事叫 JS minify,工具叫 JS minifier 或 JavaScript compressor,搜 minify javascript online 找到的都是同一类工具;本页的压缩内核是 terser,JS 压缩不上传、也不执行你的代码。很多人问 JS 怎么压缩、JS 压缩混淆是不是一回事: 压缩只缩短局部变量名,并不是加密。
粘错了内容时报错卡会给出下一步:JSON 请用 JSON 格式化校验(自带压缩成单行),样式表请用 CSS 压缩,整份网页请用 HTML 压缩,中文全角标点请先用 全角半角转换 换回半角;要把压缩过的代码重新展开,用 JS 格式化。