在sass/scss中@import跟@use的区别

1,470 阅读2分钟

新版将弃用 Sass @import 规则和全局内置函数,如果使用@import报错的话可以使用@use或者@import url('')来替代.

@use@import 的区别

  1. 功能与现代性
    • @import是早期的引入方式,比如全局命名冲突、难以管理等,已被标记为即将废弃
    • use是 SCSS 最新推荐的模块系统,增强了模块化和作用域管理。
  2. 作用域
    • @import会将引入文件中的所有内容(变量、函数、混合器等)直接放在全局作用域中,可能会造成命名冲突等问题。
    • @use会引入文件的内容,通过 @use 引入的 SCSS 文件中的样式会被识别并直接生效,但会把所有的变量、函数和混合器限制在一个命名空间下,例如:
        // utils.scss 
        $primary-color: #3498db;
        
        // test.scss
        @use './utils.scss';   // 这时默认使用的是文件名作为命名空间
        body { color: utils.$primary-color; }
        
        // test2.scss
        @use './utils.scss' as u;  // 可以通过 `as` 自定义命名空间
        body { color: u.$primary-color; }
        
        // test3.scss
        @use './utils.scss' as *;   // 如果确实需要不使用命名空间,可以使用 `*`(不推荐)
        body { color: $primary-color; // 直接使用 }
    
  3. 代码复用与优化
    • @use会确保文件只会被加载一次,即使是在多个地方引用也不会重复执行
    • @import会在每次引入文件时都会重复编译该文件的内容,可能导致性能问题
  4. 问题
    • 当别的文件引用当前文件时,使用@use引入的文件里的变量等不能使用
    // base.scss
    $padding:22px;
    
    // forward.scss
    @use "base.scss";
    
    // main.scss
    @use "forward" as *;
    p { padding:$padding; }  // 会报`Error: Undefined variable.`
    
    • 为何会出现这个问题是因为会把所有的变量、函数和混合器限制在一个命名空间下,所以@use 主要用于在当前模块中使用其他模块
    • 而要解决这个问题可以使用@forward,@forward 主要用于模块间的转发
       // base.scss
       $padding:22px;
    
       // forward.scss
       @forward "base.scss";
    
       // main.scss
       @use "forward" as *;
       p { padding:$padding; }  // 不会报错
    
    • 关于@forward更多的用法可以看这里

@import@import url()的区别

  1. 语法
    • @import "style.scss";这是scss引入方式,用于导入scss文件.
    • @import url("style.css");这是纯css导入方式,用于导入外部css文件或资源(ps:在html/css文件中只能导入css文件,在vue中可以导入scss文件,原因是<style lang="scss"> 的环境会被构建工具预处理,工具会解析和处理这些 @import 语句).
  2. 编译
    • SCSS 编译器在遇到 @import "" 时会尝试解析为 SCSS 文件。
    • @import url("") 不会被 SCSS 编译器解析,而是直接传递给生成的 CSS 文件。

总结建议

建议优先使用@use替代@import