ThinkPHP6 子主题换肤时,我把 `__STATIC__` 改成 `__THEME__`,结果 CSS 里所有相对路径的字体文件集体"叛逃"到主站去了

小助手
小助手 版主圣羽星庭 勋望元宿志愿先锋
社区管理
站长杂谈 63 浏览 0 回复

上周给公司官网做深色模式切换,想着用模板继承套个子主题最干净。主站一套白底蓝字的默认皮肤,子主题覆写几个 `block` 就行,静态资源各自独立,理论上完美。

结果切过去一看,界面样式都对,但图标字体全变成了小方块。F12 一看,`woff2` 请求 404,路径居然指向了主站的 `__STATIC__/font/` 目录,可我明明在子主题里把 `__THEME__` 指向了完全不同的 CDN 前缀。

坑在这儿:CSS 文件里的 `url(../font/icon.woff2)` 是相对路径编译进去的。模板继承能帮你换 HTML 结构,但 CSS 内部的相对引用在编译阶段就写死了。我子主题的 `__THEME__` 只替换了外链 CSS 的加载地址,CSS 内容本身没被二次处理,里面的 `../` 照样往父级目录跳,一跳就跳回了主站资源池。

试过两个歪招。一是把字体改成绝对路径 `url(/theme/dark/font/icon.woff2)`,本地开发没问题,一上 CDN 又傻眼——CDN 回源路径和站点根目录往往不是一回事。二是想在 `webpack_mix` 或者 `vite` 里做路径重写,但 ThinkPHP6 默认那套资源发布流程根本不经过前端构建,直接 `php think publish` 把文件甩到 `public/static/` 完事。

最后用的法子有点脏但管用:子主题单独建一套完整的 `font/` 目录,CSS 里改成 `url(./font/icon.woff2)`,然后在 `config/view.php` 里给子主题注册独立的 `__FONT__` 别名,模板里用 `loadCss('__FONT__/css/dark.css')` 加载。这样 CSS 和字体文件同层级,相对路径不会乱窜,CDN 刷新时也只需要扫一个目录。

还有个副产品:原来 `php think view:clear` 只清模板缓存,不清浏览器缓存。我改了三版路径,自己看还是 404,后来才想起 CDN 边缘节点和本地浏览器双重缓存叠加,刷新键按烂了都没用。现在上线资源更新,先在文件名里塞时间戳,再手动推 CDN 刷新,最后 `Ctrl+F5` 三连,成了固定仪式。

模板继承这玩意儿,HTML 层面确实省代码,但一到静态资源的"物理路径"和"逻辑别名"交界的地方,就容易出这种跨层级的幻觉。现在我的子主题目录里,每个皮肤都自带完整的 `css/js/font/img` 四件套,宁可冗余,也不再赌相对路径的自觉性了。

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