◆

Sass inspect 函数:查看值与 Map 内容

2023-02-02 01:370

Sass 是编译期语言,我们没法像调 JS 那样打个断点看变量。变量算错了、map 合并后结构不对,往往只能靠盯着最终 CSS 反推,很费劲。inspect() 就是 Sass 给的调试出口:把任意值转成它的字符串表示,塞进一个随便起名的 CSS 属性里,编译一次就能在产物中看到这个值到底长什么样。

它和普通的值输出有个关键区别:保留类型信息。直接把 null 写进属性值,Sass 会认为这条声明无效、整条丢掉;用 inspect(null) 就能实实在在看到 null 这几个字。字符串的引号也是同理,inspect('sans-serif') 会把引号一起保留下来,让我们分得清手上拿的是带引号字符串还是不带引号的标识符。这在排查「为什么两个看起来一样的值 == 判断却是 false」时很有用——十有八九就是引号或单位的差别。

作用

输出一个值的字符串表示形式

示例

下面这四行覆盖了几种常见类型:null、由空格分隔的列表、带引号的字符串、以及 map。属性名 test-one 这些都是我随便起的,只为了让值能出现在编译产物里,不需要是合法的 CSS 属性。

.test {
  test-one: inspect(null); // "null"
  test-two: inspect(10px 20px 30px); // "10px 20px 30px"
  test-three: inspect('sans-serif'); // "'sans-serif'"
  test-four: inspect(
    (
      'width': 200px,
    )
  ); // "('width': 200px)"
}

编译后

.test {
  test-one: null;
  test-two: 10px 20px 30px;
  test-three: 'sans-serif';
  test-four: ('width': 200 px);
}

对照编译结果能看出,inspect 把每种类型都还原成了源码里的样子。map 那一项输出成 ('width': 200px) 这种带括号的形式,这正是 map 在 Sass 里的字面写法。如果不套 inspect 直接把 map 写进属性值,Sass 会直接报错说 map 不是合法的 CSS 值,根本编译不过去。

输出一个 map 的值

有时候 map 进行一系列的操作后,可能不知道 map 变成什么样了,这时候就可以使用 inspect 去查看经过改变的 map 值

map 是最需要 inspect 的场景。map.merge、map.set、map.deep-merge 这些操作都返回一份新的 map,链式调几次之后到底有哪些键、值被谁覆盖了,光看代码很难确认。尤其是做主题配置时,默认 map 和用户传入的 map 合并,一旦某个键名写错,表现就是样式静默不生效——map.get 取不到键返回 null,null 又会让整条声明被丢弃,前后一点报错都没有。这时候 inspect 一下合并结果,问题立刻现形。

下面用 map.merge 往 $test-map 里塞一个新键,再 inspect 出来看:

@use 'sass:map';

$test-map: (
  name: 'wfly',
  age: 18,
);
$test-map-merge: map.merge(
  $test-map,
  (
    money: 99999999999999999999,
  )
);

.test-inspect {
  person: inspect($test-map-merge);
}
.test-inspect {
  person: (name: 'wfly', age: 18, money: 100000000000000000000);
}

结果里有个细节值得留意:源码写的 money 是 99999999999999999999,输出却变成了 100000000000000000000。这不是 inspect 的问题,而是 Sass 的数字底层用的是双精度浮点数,这个位数已经超出了它能精确表示的整数范围,读进来时就已经被舍入了。日常写样式碰不到这个边界,但它提醒我们 inspect 展示的是 Sass 内部实际持有的值,不是我们源码里敲的字面文本。

另外提一句,第二段示例开头的 @use 'sass:map' 是新版模块系统的写法,map.merge 这类带命名空间的函数必须先 @use 才能调用。老的全局 map-merge 虽然还能用,但已经标记为废弃了。

和 @debug 的区别

inspect 返回的是一个字符串,得依附在某条 CSS 声明上才能看到,所以它会污染产物,调完记得删。如果只想在编译时往终端打一行日志、不影响输出的 CSS,用 @debug 更合适:

@use 'sass:map';

$theme: (
  primary: #409eff,
);
@debug map.get($theme, primary); // 编译时在控制台输出
@debug $theme; // 直接打 map,不需要套 inspect

@debug 可以写在任意位置,包括规则块外面,而 inspect 必须写在属性值里,也就必须待在某个选择器内部。我一般这样分工:想确认某个中间变量的值就用 @debug;想让某个值和它对应的选择器一起呈现出来对照,才用 inspect。

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVESass inspect 函数:查看值与 Map 内容加载中