@forward 是“接口门禁”而非“导出开关”,只控制外部可访问的成员及其命名空间,不将变量注入当前模块;转发需显式声明 show 或 as,本文件定义的内容默认不被转发,多处转发同名成员会冲突,函数改名不改变其内部作用域。

直接说结论:@forward 不是“导出开关”,而是“接口门禁”——它不把内容搬进来,只决定哪些成员能从你这个文件被看见、以什么名字、在哪个命名空间下被调用。
为什么@forward后变量还是undefined
根本不是路径写错或拼写错误,而是误以为 @forward "colors" 会让 $primary-color 自动出现在当前模块里。它不会。它只告诉“外面的人”:如果你 @use "theme",那你可以访问 colors 模块的成员——但前提是,你得明确告诉 Sass 哪些成员能被看到。
-
@forward "colors" as *;→ 外部@use "theme" as *可直接用$primary-color -
@forward "colors" as color-*;→ 外部必须写color-primary-color - 如果
_theme.scss里自己定义了$spacing-md: 16px;,但只写了@forward "colors",那这个$spacing-md根本不会被转发出去——@forward默认只转发它@use进来的成员,不转发本文件定义的内容
多个@forward导致"name is already used"错误
这是编译器在严格阻止命名冲突,不是 bug。比如 components/button 和 components/card 都转发了 $radius-sm,Sass 就会报错,哪怕值一样。
- 典型触发场景:入口
index.scss同时@forward "utils/spacing"和@forward "components/card",而两者都含$radius-sm - 用
show精确控制时漏重命名也会冲突:@forward "a" show $radius-sm;+@forward "b" show $radius-sm; - 解决只有两个办法:
— 统一由基础层(如core/vars)提供该变量,其他模块只引用不转发
— 用with显式改名:@forward "a" with ($radius-sm as $a-radius);
如何让组件库同时支持@use "kit"和@use "kit" as *
单靠一个 @forward 不行。入口文件(如 index.scss)必须组合 @use + @forward,且自身不能定义任何新变量或 mixin。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
@use "core/variables" as core; @use "utils/mixins" as utils; @forward "core/variables" as core-*; @forward "utils/mixins" as utils-*;
- 这样使用者可选:
—@use "index" as i;→ 用i.core-primary-color
—@use "index" as *;→ 直接用$primary-color和@include text-truncate - 关键点:入口文件只是“中转站”,所有逻辑必须下沉到子模块;否则转发规则会失控,比如你在
index.scss里加了一行$tmp: 12px;,它不会被自动转发,还会干扰依赖链
@forward 转发函数时with改名却报Undefined function
这不是改名失败,而是作用域没跟上。改名只影响出口签名,不改变函数内部对其他变量的查找路径。
- 例如你把
color.scale-lightness()转发为lighten-color(),但它内部用了未被转发的$colors,就会报错 -
with只重命名,不重绑定作用域 —— 函数运行时仍查找它原始模块里的变量 - 调试建议:先删掉
with,用原始名测试是否能跑通;确认是依赖缺失后,再在with中一并重映射:@forward "color" with ($colors as $colors); - 最容易被忽略的一点:转发函数时,
with改名只影响调用签名,不影响函数内部对其他未转发成员的引用


















