3. 静态资源迁移:HTML结构迁移、CSS样式迁移、JavaScript脚本迁移、图片与字体文件处理
静态资源迁移,说白了就是把旧项目里的「皮肉」搬到新环境里。很多人觉得这步就是复制粘贴,结果上线后页面崩得亲妈都不认识。我见过最离谱的一次,团队花了两周迁移,最后发现所有图片路径都写死了绝对路径,部署到子目录下全变404。
这一章,咱们把静态资源拆成四块来讲:HTML、CSS、JavaScript、图片与字体。每块都有坑,每块也都有套路。
核心原则:迁移不是搬运,是适配。新环境可能有不同的域名、不同的目录结构、不同的协议(HTTP→HTTPS),所有资源引用都必须跟着变。
3.1 HTML结构迁移
HTML迁移看起来最简单,但最容易出问题。我习惯先把页面结构拆成三部分:骨架、内容、引用。
- 骨架:DOCTYPE、html、head、body 这些标签,基本不用动。
- 内容:文本、表格、列表等,注意编码问题。旧项目可能是 GBK,新环境统一 UTF-8,中文乱码就来了。
- 引用:CSS 的 link、JS 的 script、图片的 img、字体的 link 或 @font-face。这些是迁移的重灾区。
举个例子,旧项目里可能有这样的引用:
<link rel="stylesheet" href="/css/style.css">
<script src="/js/app.js"></script>
<img src="/images/logo.png" alt="Logo">
如果新环境部署在子路径 /portal/ 下,这些绝对路径就全废了。要么改成相对路径,要么用 <base> 标签统一指定基准 URL。
我的习惯:在 head 里加一行 <base href="/portal/">,所有相对路径都基于这个基准解析。但要注意,<base> 会影响页面内所有相对链接,包括锚点,用之前一定要测试。
3.2 CSS样式迁移
CSS 迁移的坑,我踩过不少。最典型的有三个:
- 路径问题:CSS 里引用的图片、字体,比如
background-image: url('../images/bg.png'),路径是相对于 CSS 文件本身的。如果 CSS 文件位置变了,路径就得跟着改。 - 兼容性问题:旧项目可能用了只有 IE 才支持的写法,比如
filter属性。新环境如果是现代浏览器,这些代码可以直接删掉。 - 优先级冲突:多个 CSS 文件合并后,选择器优先级可能发生变化。我之前遇到过,迁移后某个按钮颜色变了,查了半天发现是两个文件里都有
.btn定义,顺序变了导致覆盖关系变了。
怎么解决?我建议分三步走:
- 第一步:用工具(比如 PurgeCSS)清理无用样式,减少迁移量。
- 第二步:把所有
url()引用提取出来,统一替换路径。可以用正则,也可以用 Webpack 的css-loader自动处理。 - 第三步:在浏览器里逐页对比新旧样式,重点关注字体、颜色、间距、布局。
我曾经踩过的坑:迁移一个老项目时,CSS 里用了 @import url('http://old-domain.com/css/common.css')。新环境是 HTTPS,浏览器直接阻止了混合内容加载。所有 @import 必须改成相对路径或同协议路径。
3.3 JavaScript脚本迁移
JavaScript 迁移,说白了就是处理三件事:依赖、路径、兼容性。
| 问题类型 | 典型表现 | 解决方案 |
|---|---|---|
| 依赖缺失 | 控制台报错 Uncaught ReferenceError: xxx is not defined |
检查所有 script 标签顺序,确保依赖库先加载 |
| 路径错误 | AJAX 请求 404,或图片/文件加载失败 | 全局搜索硬编码的 URL,替换为动态路径或配置变量 |
| API 兼容性 | 旧 API 在新浏览器中被废弃(如 document.all) |
用 polyfill 或重写为现代 API |
| 跨域问题 | XMLHttpRequest 被 CORS 策略阻止 | 后端配置 CORS 头,或使用 JSONP(已不推荐) |
我个人习惯在迁移前先做一次「依赖审计」。打开旧项目的页面,在控制台里看 Network 面板,把所有加载的 JS 文件列出来,搞清楚加载顺序和依赖关系。然后在新环境里按同样的顺序引入。
如果项目用了模块化(比如 RequireJS、CommonJS),迁移时要注意模块路径。举个例子:
// 旧项目路径
define(['lib/jquery', 'app/utils'], function($, utils) { ... });
// 新环境路径可能变了
define(['/portal/lib/jquery', '/portal/app/utils'], function($, utils) { ... });
这种时候,我建议用路径映射(paths config)统一管理,而不是一个个改。
一个小技巧:在全局定义一个 window.BASE_URL = '/portal/',所有动态生成的 URL 都拼接这个变量。以后换路径,改这一个地方就行。
3.4 图片与字体文件处理
图片和字体,说白了就是「静态资源」里的重头戏。它们体积大、数量多、路径散,迁移起来最烦人。
图片处理
图片迁移我分四步走:
- 收集:用爬虫或手动扫描,找出所有图片引用。包括 HTML 里的
<img>、CSS 里的background-image、JS 里动态创建的new Image()。 - 复制:把图片文件按原目录结构复制到新环境。注意保持目录层级一致,否则路径全得改。
- 优化:迁移过程中顺便做一次压缩。我常用 imagemin 批量处理,能省 30%-50% 的体积。
- 验证:用工具(比如 broken-link-checker)扫描所有图片链接,确保没有 404。
注意:有些图片是用户上传的,存储在服务器本地或云存储上。迁移时不能只复制文件,还要更新数据库里的路径字段。我曾经漏掉这一步,结果用户头像全挂了,被投诉了一整天。
字体处理
字体迁移相对简单,但有个坑:字体文件通常有版权限制。迁移前先确认字体是否允许在目标域名下使用。
字体引用的常见方式有两种:
- @font-face:在 CSS 里定义,引用 .woff、.woff2、.ttf 等文件。
- Google Fonts / 第三方 CDN:通过
<link>引入外部字体。
如果是自托管字体,迁移时注意两点:
- 字体文件路径要更新,和图片一样处理。
- 不同浏览器需要的字体格式不同(WOFF2、WOFF、TTF、EOT),确保所有格式都复制过去了。
如果是第三方 CDN 字体,迁移时建议改成自托管。为什么?因为第三方 CDN 可能被墙、可能慢、可能突然改版。我见过一个项目,迁移后 Google Fonts 加载失败,页面字体全变成默认宋体,设计稿直接废了。
我的建议:把字体文件下载到本地,用 @font-face 引用。虽然多了几百 KB 的体积,但稳定性和可控性高得多。
3.5 知识体系总览
下面这张图,把静态资源迁移的核心流程和关键节点串起来了。你可以把它当作迁移时的检查清单。
嗯,这张图基本把这一章的内容都串起来了。你迁移的时候,可以对着它一项一项检查,不容易漏。
3.6 迁移后的验证清单
最后,我整理了一份验证清单。每次迁移完,我都会逐条过一遍:
- HTML:所有页面能正常渲染,没有乱码,没有标签未闭合。
- CSS:样式与旧环境一致,没有丢失的样式,没有意外的覆盖。
- JavaScript:控制台无报错,所有交互功能正常,AJAX 请求返回正确数据。
- 图片:所有图片能正常显示,没有 404,没有跨域错误。
- 字体:字体加载正确,没有 FOIT(Flash of Invisible Text)或 FOUT(Flash of Unstyled Text)。
- 性能:资源加载速度可接受,没有不必要的重定向。
一个小建议:用浏览器的开发者工具,在 Network 面板里过滤 404 和 500,能快速定位所有失败的资源请求。我每次迁移完都会跑一遍这个检查,省时省力。