SCSS中下划线变量(如$_color-primary)并非私有,仅是命名习惯;真正实现私有性的是@use模块系统,其默认不导出$_开头变量,而@import会全局平铺所有内容导致污染。

SCSS 里加下划线的变量(比如 $_color-primary)不是私有变量,它只是个命名习惯;真能防污染的是 @use + 模块作用域,不是下划线本身。
为什么 $_variable 在 @import 下完全不私有
用 @import 引入文件时,所有内容——包括 $_color-warning、$color-success、@mixin reset——全被平铺进当前作用域。编译器根本不看下划线,$_color-warning 和 $color-warning 对它来说没区别。
- 你写
@import 'colors';后,直接写color: $_color-warning;是合法且能编译通过的 - IDE 跳转会指向多个同名定义,根本分不清哪个是“本意”
- 两个模块都
@import 'mixins',里面都有$_base-padding,后加载的会静默覆盖前一个 - 构建工具可能重复输出同一段 CSS,因为
@import不做去重
怎样让 $_variable 真正不可访问
只有在 @use 模块系统中,$_ 开头的变量才默认不导出。这是 Sass 语言级行为,不是约定。
-
@use 'colors';后,colors.$color-primary可用,colors.$_color-warning直接报错Undefined variable - 想暴露某个
$_变量?必须显式@forward 'colors' with ($_color-warning: #ffc107),但一般没必要 -
@use 'colors' as *;也不会把$_color-warning挂到全局,它依然不可见 - 如果同时混用
@import 'colors'和@use 'colors',前者会把所有变量倒进全局,彻底破坏后者建立的私有性
文件名带下划线(_colors.scss)和变量名带下划线($_color)是两回事
_colors.scss 的下划线是 Sass 编译器识别 partial 文件的硬性规则:它不会被单独编译成 CSS;而 $_color 的下划线只是开发者自己写的字符,编译器完全无视。
立即学习“前端免费学习笔记(深入)”;
- 你删掉
_写成colors.scss,Sass 构建工具(如 Webpack、Vite)可能把它当成入口文件单独输出空 CSS 或报错 - 你把变量改成
$color_warning,只要用了@use,它照样默认导出;改成$_color-warning,也照样默认不导出 -
-和_在 SCSS 变量名里等价:$border_color和$border-color是同一个变量 - 真正起隔离作用的是
@use 'colors'这条语句本身,不是文件名或变量名里的符号
最容易被忽略的一点:私有性只存在于模块之间。一旦你在某个文件里 @use 'colors',又在同一文件里写了 @use 'buttons',这两个模块内部的 $_ 变量彼此完全不可见——但如果你在 buttons.scss 里偷偷 @import 'colors',整个封装就失效了。模块系统的约束力,只对遵守它的人有效。


















