模板里写死 `__STATIC__` 三年后,我才分清"编译时替换"和"运行时拼接"根本不是一回事

站长杂谈 25 浏览 0 回复 返回上级

上周帮朋友接手一个老项目,打开模板文件满眼的 `__STATIC__/css/style.css`,我下意识以为这是框架自带的常量替换。结果部署到子目录后,整站样式全挂,控制台一片 404。查了半天才发现,这玩意儿是前任站长在入口文件里自己 `define` 的,跟框架的 `__PUBLIC__` 井水不犯河水。

这事让我把这几年踩过的静态资源路径坑翻出来捋了一遍,发现根本问题是没搞清"谁负责拼路径"——框架、模板引擎、前端构建工具、CDN 回源策略,四个角色各有各的账本。

模板继承里的路径"传话游戏"

ThinkPHP 的 `{extend}` 继承本身不折腾路径,但块级覆盖的时候容易埋雷。比如基模板里写了:

<link rel="stylesheet" href="__CSS__/base.css">

子模板覆盖 `{block name="style"}` 时,如果顺手改成相对路径 `../css/page.css`,本地单文件预览没问题,一上线发现这页面嵌套层级变了,相对基准点跟着漂移。我现在强制约定:继承链里所有资源统一走框架解析的常量,禁止手写 `./` 或 `../`。

静态资源发布那道"隐形分水岭"

开发环境我用 `php think run`,`public` 目录直接当根;生产环境丢到服务器子目录,配了 Nginx alias。这时候 `__STATIC__` 如果定义成 `'/static/'`,子目录部署时绝对路径直接指向域名根,跟实际文件位置差了一个层级。

我的笨办法:配置里拆成两个键,`static_path` 给后端代码读,`static_url` 给模板用。子目录部署时 `static_url` 改成 `/project/static/`,`static_path` 保持绝对磁盘路径不动。模板里统一用 `{$Request.root}/static` 或者框架常量,绝不硬编码斜杠方向。

CDN 刷新后资源"假更新"

更隐蔽的是版本号问题。模板继承结构复杂后,基模板改了个 `base.css`,但子模板没动,CDN 刷新策略如果只按 URL 粒度走,基模板的缓存可能没清掉。我现在在构建环节给静态资源加哈希,模板里用 `{:asset('css/base.css')}` 自动映射到 `base.a3f2b1c.css`,文件名变了 CDN 必须回源。代价是每次发版要扫一遍模板替换引用,写了个 CLI 工具专门干这个脏活。

一个没解决的别扭事

UniApp 打包 H5 时,`static` 目录行为跟小程序完全不一样。H5 模式下 `static` 里的文件会原样复制到 `dist`,但模板继承体系里如果用了条件编译 ``,里面的资源路径在小程序端会被直接忽略,不会报错也不会打包,排查时很容易误以为是路径解析问题。我现在把跨端公共资源抽成独立目录,条件编译块里只放逻辑,不放资源引用。

说到底,静态资源路径这玩意,开发时越"透明"越容易埋雷。我现在新建项目第一件事,就是画一张"请求从浏览器到磁盘"的完整链路图,把每个环节的拼接规则标出来。这图通常画到第三层就会发现自己之前的理解有漏洞,但总比上线后让用户用 404 帮我排查强。

评论0
回复 · 0
还没有回复
微信客服 微信客服