sass 无法直接读取 json 文件,必须通过构建脚本(如 node.js)将 json 转为 _themes.scss 变量文件后导入;动态主题应改用 js 注入 css 自定义属性配合 var() 使用。

Sass 本身不能读取 JSON 文件
Sass 编译器(无论是 Dart Sass、Node Sass 还是 LibSass)在运行时完全不接触文件系统,@import 和 @use 只能加载已知路径的 .scss 或 .sass 文件,无法解析或读取 .json。你写的 @use "config.json" 会直接报错:Error: Can't find stylesheet to import。
所谓“动态读取 JSON”,本质是构建阶段的预处理动作——必须由外部工具(如 Node.js 脚本、Vite 插件、Webpack loader)提前把 JSON 内容转成 Sass 可识别的变量结构,再让 Sass 加载那个生成的 _generated.scss。
正确做法:用构建脚本生成 Sass 变量文件
假设你有一个 themes.json:
{
"primary": "#007bff",
"secondary": "#6c757d",
"spacing": {
"sm": "0.25rem",
"md": "0.5rem",
"lg": "1rem"
}
}
你需要一个 Node.js 脚本(比如 scripts/generate-scss.js)来读取它,并输出为 src/styles/_themes.scss:
该脚本核心逻辑是:解析 JSON → 遍历键值 → 拼接 $theme-primary: #007bff; 类样式声明 → 写入文件。生成后,你在主文件中 @use "styles/themes" as theme; 就能用 theme.$primary 了。
- 不要把 JSON 放在
src/下却期望 Sass 直接读 —— 构建工具不会自动做这层转换 - 生成的
_themes.scss必须以_开头,否则会被当作入口文件编译成独立 CSS - 嵌套对象(如
spacing)需扁平化为$spacing-sm等变量,Sass 不支持原生对象解构
替代方案:用 CSS 自定义属性桥接 JSON 数据
如果 JSON 数据需要运行时变更(比如用户切换主题),硬编码进 Sass 变量就失效了。此时应放弃“Sass 生成规则”的思路,改用 JavaScript 注入 CSS 自定义属性:
先在 JS 中读取 JSON,然后设置 document.documentElement.style.setProperty('--primary', data.primary);Sass 中直接使用 color: var(--primary);。
-
var(--primary)可以被 Sass 编译通过,但不能参与lighten()、mix()等函数运算 —— 这些函数只认编译期静态值 - 若需在 Sass 中做颜色变换,只能把变换逻辑移到 JS 层计算好再传入 CSS 变量,或保留两套:一套 Sass 编译时主题(用于静态组件),一套 CSS 变量(用于动态切换)
- 这种 JS + CSS 变量的组合,才是现代前端真正“动态”的落地方式,Sass 在这里只负责消费,不负责生成
常见错误与性能提醒
有人尝试用 @import url("themes.json") 或 fetch() 放在 Sass 里,这完全无效 —— Sass 不是运行时环境,没有网络请求能力,也没有 JSON 解析 API。
另一个坑是:在 Webpack/Vite 中配置了 JSON loader,却误以为它会自动注入到 Sass 上下文 —— 它只影响 JS 模块,对 Sass 无感。必须显式调用构建脚本生成中间文件,或使用专用插件(如 vite-plugin-sass-json)。
最后注意:频繁重写 _generated.scss 会触发整个 Sass 重新编译,开发时建议加文件 hash 或仅在 JSON 变更时才生成,避免无谓的构建开销。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











