阅读视图

发现新文章,点击刷新页面。

🚨 2025 最该淘汰的 10 个前端 API!

1. 为什么要“告别”?

  • 规范已打 🚩 Deprecated:浏览器随时下架,埋得越深爆得越惨
  • 性能/体积/安全:老 API 常阻塞线程、无权限模型、包体积爆炸
  • 面试必问:能讲清“为什么不用 + 怎么迁”是高分项

以下 10 组案例,95% 的代码库还能搜到,但官方文档早已不建议使用


2. 一图速览

# 过时 API / 库 典型场景 官方替代 浏览器支持
1 document.execCommand 富文本、复制 navigator.clipboard 96%
2 同步 XMLHttpRequest 导出 Excel fetch / axios 98%
3 escape/unescape URL 编码 encodeURIComponent 100%
4 String.substr 截后缀 slice/substring 100%
5 Event.keyCode 回车 13 Event.key 97%
6 window.event IE 全局事件 事件参数 e 100%
7 trimLeft/trimRight 去空白 trimStart/trimEnd 98%
8 showModalDialog 阻塞弹窗 <dialog> 已移除
9 Moment.js 日期格式化 date-fns / luxon / Temporal 95%
10 jQuery DOM & Ajax 原生 ES6+ / React / Vue 98%

3. 逐个详解 & 最小迁移代码

document.execCommand —— 富文本 & 剪贴板

问题:W3C 停止维护,行为差异大,有 XSS 风险
替代navigator.clipboard(基于 Promise + 权限 API)

// 老
document.execCommand('copy');

// 新
await navigator.clipboard.writeText('hello');

低端机兜底:降级回 execCommand


② 同步 XMLHttpRequest —— 冻结主线程

问题:官方强烈不建议;Chrome 已报 Deprecation 警告
替代fetch(异步 + Stream)

// 老
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api', false);   // 同步
xhr.send();

// 新
const res = await fetch('/api');
const data = await res.json();

escape/unescape —— 非标准百分号编码

问题:中文变 %u4E2D%u6587,+/@ 不编码
替代encodeURIComponent

escape('中文+abc');          // %u4E2D%u6587+abc
encodeURIComponent('中文+abc'); // %E4%B8%AD%E6%96%87%2Babc

String.substr(start, length) —— 语义混乱

问题:ECMA-262 标为 legacy
替代slice(支持负数索引)

const ext = fileName.slice(fileName.lastIndexOf('.'));

Event.keyCode —— 数值随布局变化

问题:UI Events spec 已废弃
替代Event.key(可读字符串)

document.addEventListener('keydown', e => {
  if (e.key === 'Enter') { /* 回车 */ }
  if (e.key === 'Escape') { /* ESC */ }
});

window.event(IE 全局事件)

问题:非标准,严格模式直接报错
替代:事件参数 e

btn.onclick = (e) => {
  console.log(e.target);   // 足够
};

trimLeft/trimRight —— 命名不统一

问题:ECMA 2020 起官方别名改为 trimStart/trimEnd
迁移

str.trimStart(); // 去左
str.trimEnd();   // 去右

showModalDialog —— 同步阻塞弹窗

现状Chrome 43 起已移除
替代:原生 <dialog>(非阻塞 + 可样式化)

<dialog id="d">
  <p>Hi</p>
  <button onclick="d.close()">关闭</button>
</dialog>
<script>d.showModal();</script>

⑨ Moment.js —— 66 KB 的“日期巨头”

问题:2020 起官方进入维护模式,不再加新功能;包体积大
替代

  • date-fns(tree-shaking,按需引)
  • luxon(时区友好)
  • Temporal(原生草案,2025 已 Chrome 95+ 实验旗)
// Moment
moment().format('YYYY-MM-DD');

// date-fns
import { format } from 'date-fns';
format(new Date(), 'yyyy-MM-dd');

⑩ jQuery —— “百万网站”历史债

现状:BuiltWith 统计全球 Top 1M 网站 78% 仍引用,但新立项使用率 < 6%(State of JS 2024)
替代

  • DOM:querySelector + addEventListener
  • Ajax:fetch
  • 动画:Web Animations API / CSS transition
  • 链式:可选链 ?. + 空值合并 ??
// jQuery
$('#btn').click(() => $.get('/api', console.log));

// 原生
document.querySelector('#btn')
        .addEventListener('click', () => fetch('/api').then(r => r.json()).then(console.log));

4. 老项目如何“无痛”批量扫描

  1. ESLint 官方插件
    npm i -D eslint-plugin-deprecation
    一键标出所有 @deprecated 调用
  2. jscodeshift 脚本
    substrslicekeyCodekey 全项目自动替换
  3. Can I use + Babel 插件
    确认替代 API 的最低浏览器版本,再决定要不要兜底

5. 结论 & 行动清单

动作 优先级
新代码直接不用左侧 API 🔴 必须
老代码lint 报错codemod回归测试 🟡 1 个 Sprint
剪贴板、网络、日期优先迁,ROI 最高 🟢 本周

把这篇文章丢进团队 Wiki,下次 Code Review 再看到 execCommandMoment.js,就能有理有据地拒绝了。


6. 参考资料

: 51CTO《2025 年该淘汰的五个 JavaScript 库》2024-12
: 稀土掘金《2025 年该淘汰的 5 个 JavaScript 库》2024-12
: CSDN《这些过时的前端技术请不要再继续学了!》2023-10
: 21CTO《2025 年你应该告别的 5 个 JavaScript 库》2024-12
: 知乎专栏《2024 总结下前端现状!》2025-02

如果对你有帮助,点个「赞」再走呗~

🔥🔥🔥Vue部署踩坑全记录:publicPath和base到底啥区别?99%的前端都搞错过!

引言

在Vue项目开发和部署过程中,很多开发者都会遇到这样的困扰:本地开发时一切正常,但项目打包部署到服务器后却出现白屏、资源加载失败、路由跳转异常等问题。这些问题的根源往往在于路径配置不当。本文将深入解析Vue项目中的两个重要配置项:vue.config.js中的publicPath和Vue Router中的base,通过实际案例帮助您彻底理解它们的区别与联系。

一、认识publicPath与base

1.1 publicPath是什么?

publicPath是Vue CLI项目中vue.config.js的配置项,用于指定应用部署的基本URL路径。它决定了打包后静态资源(JS、CSS、图片等)的引用路径。

官方定义:部署应用包时的基本 URL。用法和 webpack 本身的 output.publicPath 一致,但是 Vue CLI 在一些其他地方也需要用到这个值,所以请始终使用 publicPath 而不要直接修改 webpack 的 output.publicPath

1.2 base是什么?

base是Vue Router的配置项,用于指定应用的基路径。当单页应用部署在非根目录时,需要通过设置base来确保路由的正确解析。

官方定义:应用的基路径。例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 "/app/"

二、两者的核心区别

特性 publicPath base
作用对象 静态资源路径 路由路径
配置位置 vue.config.js Vue Router配置
影响范围 资源加载 路由跳转
默认值 '/' '/'
使用场景 资源引用路径 路由匹配路径

2.1 功能差异详解

publicPath主要解决的是"资源在哪里"的问题:

  • 影响打包后index.html中引用的JS、CSS等资源路径
  • 决定开发环境下静态资源的访问路径
  • 控制webpack输出资源的公共路径

base主要解决的是"路由怎么匹配"的问题:

  • 为所有路由路径添加前缀
  • 确保路由在子目录部署时能正确解析
  • 影响路由的跳转和匹配逻辑

三、实际案例分析

3.1 案例背景

假设我们有一个Vue项目,包含两个页面:

  • 首页(Home):/
  • 关于页面(About):/about

项目需要部署到服务器的子目录/my-app/下,服务器地址为http://example.com

3.2 无任何配置的问题

部署情况:项目打包后部署到http://example.com/my-app/

访问结果

  • 访问http://example.com/my-app/:页面空白,控制台报错Failed to load resource: the server responded with a status of 404
  • 资源加载路径:http://example.com/js/app.js(错误,少了/my-app/)
  • 路由跳转:点击路由链接时路径为http://example.com/about(错误,少了/my-app/)

问题分析

  1. 资源加载失败:因为publicPath默认为/,资源引用路径为绝对路径,直接从域名根目录查找
  2. 路由跳转异常:因为base默认为/,路由路径没有包含子目录前缀

3.3 只配置publicPath

配置代码

// vue.config.js
module.exports = {
  publicPath: '/my-app/'
}

部署结果

  • 资源加载:http://example.com/my-app/js/app.js(正确)
  • 路由跳转:仍然为http://example.com/about(错误)

问题分析: 资源加载问题解决了,但路由跳转仍然有问题,因为base还未配置。

3.4 只配置base

配置代码

// router/index.js
const router = new VueRouter({
  mode: 'history',
  base: '/my-app/',
  routes: [...]
})

部署结果

  • 资源加载:http://example.com/js/app.js(错误)
  • 路由跳转:http://example.com/my-app/about(正确)

问题分析: 路由跳转问题解决了,但资源加载仍然有问题,因为publicPath还未配置。

3.5 同时配置publicPath和base

完整配置

// vue.config.js
module.exports = {
  publicPath: '/my-app/'
}

// router/index.js
const router = new VueRouter({
  mode: 'history',
  base: '/my-app/',
  routes: [...]
})

部署结果

  • 资源加载:http://example.com/my-app/js/app.js(正确)
  • 路由跳转:http://example.com/my-app/about(正确)
  • 页面访问:http://example.com/my-app/(正常显示)

四、进阶配置技巧

4.1 环境区分配置

// vue.config.js
module.exports = {
  publicPath: process.env.NODE_ENV === 'production' 
    ? '/my-app/' 
    : '/'
}

// router/index.js
const router = new VueRouter({
  mode: 'history',
  base: process.env.NODE_ENV === 'production' 
    ? '/my-app/' 
    : '/',
  routes: [...]
})

4.2 使用环境变量

# .env.production
VUE_APP_PUBLIC_PATH=/my-app/
VUE_APP_ROUTER_BASE=/my-app/
// vue.config.js
module.exports = {
  publicPath: process.env.VUE_APP_PUBLIC_PATH || '/'
}

// router/index.js
const router = new VueRouter({
  mode: 'history',
  base: process.env.VUE_APP_ROUTER_BASE || '/',
  routes: [...]
})

4.3 相对路径配置

在某些特殊场景下,可以使用相对路径:

// vue.config.js
module.exports = {
  publicPath: './'
}

注意:使用相对路径有局限性,不推荐在使用HTML5 history模式或构建多页面应用时使用。

五、常见问题排查

5.1 白屏问题

症状:页面空白,控制台显示资源加载404错误 排查步骤

  1. 检查浏览器开发者工具中的Network标签
  2. 确认资源请求路径是否正确
  3. 检查publicPath配置是否与部署路径一致

5.2 路由刷新404

症状:路由跳转正常,但刷新页面显示404 原因:服务器未配置history模式Fallback 解决方案

  • Nginx配置:
location /my-app/ {
  try_files $uri $uri/ /my-app/index.html;
}

5.3 资源路径错误

症状:部分资源加载失败,路径明显错误 排查方法

  1. 检查资源引用是否使用绝对路径
  2. 确认publicPath配置正确
  3. 检查是否有硬编码的路径

六、最佳实践建议

6.1 配置原则

  1. 同时配置:子目录部署时,publicPath和base必须同时配置
  2. 保持一致:两者的路径值应该保持一致
  3. 环境区分:开发环境和生产环境使用不同配置
  4. 避免硬编码:使用环境变量管理路径配置

6.2 部署 checklist

  • 确认部署路径
  • 配置publicPath
  • 配置base
  • 检查路由模式(hash/history)
  • 配置服务器重写规则(history模式)
  • 测试资源加载
  • 测试路由跳转
  • 测试页面刷新

七、总结

理解publicPath和base的区别与联系,对于Vue项目的正确部署至关重要:

  • publicPath解决的是资源加载路径问题
  • base解决的是路由匹配路径问题
  • 子目录部署时,两者需要同时配置且保持一致
  • 通过环境变量管理不同环境的配置

掌握这两个配置项的使用,可以避免90%以上的Vue项目部署问题。希望本文能帮助您在今后的项目开发中,更加游刃有余地处理路径配置相关的挑战。

参考资料

🧙‍♂️ 老司机私藏清单:从“记事本”到“旗舰 IDE”,我只装了这 12 个插件

前几天有同学问我:
“你 VSCode 里都装了哪些插件?为什么写代码那么快?”
我把正在用的 12 款全部扒出来,分 3 类、附「前后对比」代码片段,
让你 5 分钟看懂它们到底解决了什么痛点。
(⭐=几乎必装,△=按需取用)

一、代码质量 & 格式化

插件 市场关键词 对比片段
Prettier – Code formatter esbenp.prettier-vscode 一键把“能跑”变“能看」
ESLint dbaeumer.vscode-eslint 实时红线+自动修复
Code Spell Checker streetsidesoftware.code-spell-checker 拒绝 getUesrInfo typo

演示 1:Prettier + ESLint 双剑合璧

// 保存前(手写随意)
function getUserInfo(   id,token){
    const url='/api/user/'+id+'?token='+token
    return fetch(url).then(res=>res.json()).then(data=>{
    console.log('数据',data)
        return data
    })
}

// 保存后(Prettier 自动)
function getUserInfo(id, token) {
  const url = `/api/user/${id}?token=${token}`;
  return fetch(url)
    .then((res) => res.json())
    .then((data) => {
      console.log('数据', data);
      return data;
    });
}

ESLint 同时把「未使用变量」「缺少分号」全部修好,0 条红线。

演示 2:Code Spell Checker
当你手滑打出 getUesrInfo,波浪线立刻出现,鼠标悬停提示
"Uesr" is a misspelling of "User",一键修正。

二、前端框架 & 智能提示

插件 市场关键词 对比片段
Vue - Official vue.volar <template> 高亮+类型提示
ES7+ React/Redux/React-Native snippets dsznajder.es7-react-js-snippets 3 秒生成组件骨架
Icon Fonts idleberg.icon-fonts 图标类名自动补全

演示 3:Vue - Official
输入 <scr 立即提示 <script setup lang="ts">,跳转定义直达 defineProps<{}> 类型声明。

演示 4:ES7 Snippets
新建 Header.jsx → 敲 rafceTab

import React from 'react';

const Header = () => {
  return <div>Header</div>;
};

export default Header;

全程 1.5 秒,格式直接按 .prettierrc 来。

演示 5:Icon Fonts
输入 bi-alarm 自动补全 <i class="bi bi-alarm"></i>,并给出图标预览,少翻 80% 文档。

三、效率 & 可视化小工具

插件 市场关键词 对比片段
GitLens eamodio.gitlens 行级 blame+分支图谱
Tabnine tabnine.tabnine-vscode AI 整行补全
Turbo Console Log chakrounanas.turbo-console-log 调试日志“带 GPS”
Live Server ritwickdey.liveserver 右键 HTML 秒起服务
Draw.io Integration hediet.vscode-drawio 在编辑器里画架构图
CodeSnap adpyke.codesnap 代码一键变高清图

演示 6:GitLens
在任意行 hover,即刻出现
张三, 2 天前 · feat: 增加用户接口 —— 代码历史一目了然。

演示 7:Tabnine
const [sortOrder, set → 10 ms 内补全
const [sortOrder, setSortOrder] = useState('asc');
本地+云端模型,断网也能用。

演示 8:Turbo Console Log
选中变量 userListCtrl+Alt+L

console.log('🚀 ~ file: Home.jsx:42 ~ useEffect ~ userList:', userList);

文件名、行号、函数名一次性带齐,定位 BUG 直接跳转。

演示 9:Live Server
右键 index.htmlOpen with Live Server → 浏览器自动打开 localhost:5500,保存即刷新。

演示 10:Draw.io Integration
新建 architecture.drawio → 拖拽画微前端架构 → 导出 .drawio.svg,直接贴 README,放大不失真。

演示 11:CodeSnap
选中一段 TypeScript → 一键生成 4K 圆角截图,13 种主题可选,复制即可贴 Keynote/博客。

一键配置小抄(给读者的福利)

.vscode/settings.json

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": ["source.fixAll.eslint"],
  "turboConsoleLog.addSemicolonInTheEnd": true,
  "liveServer.settings.port": 5500,
  "gitlens.currentLine.enabled": true
}

把上面文件扔进仓库根目录,新人 Clone 后重启 VSCode,即刻拥有同款体验。

12 款全在这,一个都没少

类别 插件
格式化 Prettier、ESLint、Code Spell Checker
框架提示 Vue - Official、ES7 Snippets、Icon Fonts
效率工具 GitLens、Tabnine、Turbo Console Log、Live Server、Draw.io、CodeSnap

装好它们,VSCode 直接从「记事本」升级成「前端旗舰 IDE」。
如果你还有私藏神器,评论区反向安利,一起把生产力拉满!

❌