使用 SASS 时,如何从不同目录导入文件?

Posted

技术标签:

【中文标题】使用 SASS 时,如何从不同目录导入文件?【英文标题】:When using SASS how can I import a file from a different directory? 【发布时间】:2011-09-24 01:03:24 【问题描述】:

在 SASS 中,是否可以从另一个目录导入文件?例如,如果我有这样的结构:

- root_directory
    - sub_directory_a
        - _common.scss
        - template.scss
    - sub_directory_b
        - more_styles.scss

template.scss 可以使用@import "common" 导入 _common.scss,但是 more_styles.scss 是否可以导入 _common.scss?我尝试了一些不同的方法,包括 @import "../sub_directory_a/common"@import "../sub_directory_a/_common.scss",但似乎没有任何效果。

【问题讨论】:

【参考方案1】:

这是一半的答案。

查看Compass,您可以使用它将_common.scss 放在partials 文件夹中,然后使用@import common 将其导入,但它适用于每个文件。

【讨论】:

我认为 Miikka 的回应确实是我所追求的,但现在我也对 Compass 感到好奇。部分目录是否特定于特定项目?或者,无论使用 Compass,放在 partials 目录中的文件都可以“全局”使用吗?【参考方案2】:

您可以使用 Ruby 代码中的-I 命令行开关或:load_paths 选项将sub_directory_a 添加到Sass 的加载路径。因此,如果您从 root_directory 运行 Sass,请执行以下操作:

sass -I sub_directory_a --watch sub_directory_b:sub_directory_b

那么你可以简单地在more_styles.scss中使用@import "common"

【讨论】:

Chain -I 标志以包含多个目录,例如sass -I sub_directory_a -I sub_directory_c --watch sub_directory_b:sub_directory_b【参考方案3】:

更新:请先考虑Mikka's answer - 如果您只对包含子目录感兴趣,它应该可以正常工作。我的回答是针对包含other目录而不是子目录,但也适用于这些目录。但是:这不是惯用的方式。


看起来对 SASS 的一些更改使您最初尝试做的事情成为可能:

@import "../subdir/common";

我们甚至让它适用于位于c:\projects\sass 的一些完全不相关的文件夹:

@import "../../../../../../../../../../projects/sass/common";

只需添加足够多的../ 以确保您最终会到达驱动器根目录并且一切顺利。

当然,这个解决方案远非漂亮,但我无法从完全不同的文件夹导入工作,既不使用 I c:\projects\sass 也不将环境变量 SASS_PATH 设置为(来自::load_paths reference)相同的值。

【讨论】:

它“远非漂亮”!但是这个答案得到了很多赞成。这真的被认为比-I 更好吗?如果该路径名发生更改,则会进行大量搜索和替换;它需要与共享 .scss 的任何人相同的本地文件夹结构 我建议完全忽略这个答案。不幸的是,这是许多 SO 问题之一,这些问题的回答不正确。如果您希望您的代码容易破解,请使用它。如果您想要一个强大的解决方案,请参阅下面的答案。【参考方案4】:

我遇到了同样的问题,我通过添加文件路径找到了解决方案,例如:

@import "C:/xampp/htdocs/Scss_addons/Bootstrap/bootstrap";

@import "C:/xampp/htdocs/Scss_addons/Compass/compass";

【讨论】:

虽然之前已经给出了类似的答案,但绝对路径是特定于服务器的一般答案(当然,您确实说过“喜欢”)。【参考方案5】:

Gulp 将负责查看您的 sass 文件并使用 includePaths 添加其他文件的路径。 示例:

gulp.task('sass', function() 
  return gulp.src('scss/app.scss')
    .pipe($.sass(
      includePaths: sassPaths
    )
    .pipe(gulp.dest('css'));
);

【讨论】:

【参考方案6】:

我遇到了同样的问题。从我的解决方案中我进入了这个。所以这是你的代码:

- root_directory
    - sub_directory_a
        - _common.scss
        - template.scss
    - sub_directory_b
        - more_styles.scss

据我所知,如果您想将一个 scss 导入另一个 scss,它必须是部分的。当您从不同的目录名称导入您的more_styles.scss_more_styles.scss。然后将其导入您的template.scss,就像@import ../sub_directory_b/_more_styles.scss 一样。它对我有用。但正如你提到的../sub_directory_a/_common.scss 不工作。这是template.scss 的同一目录。这就是它不起作用的原因。

【讨论】:

【参考方案7】:

使用 webpack 和 sass-loader 我可以使用 ~ 来引用项目根路径。例如,假设 OPs 文件夹结构并且您位于 sub_directory_b 内的文件中:

@import "~sub_directory_a/_common";

文档:https://github.com/webpack-contrib/sass-loader#resolving-import-at-rules

2021 年编辑:现在不推荐使用 ~,上面的链接显示:

使用 ~ 已被弃用,可以从您的代码中删除(我们建议 它),但出于历史原因,我们仍然支持它。为什么你可以 去掉它?加载器将首先尝试将 @import 解析为相对 小路。如果无法解析,则加载程序将尝试解析 @import 在 node_modules 中。

【讨论】:

这似乎是从node_modules/ 导入的,而不是从项目的根目录导入的。 在使用包含 sass-loader 的 Angular CLI 时,我必须将 "sub_directory_a" 添加到我的 includePaths 并使用 @import "common"; 语法。 同意 Splaktar。来自 sass-loader 文档:webpack 提供了一种高级机制来解析文件。 sass-loader 使用 Sass 的自定义导入器功能将所有查询传递给 webpack 解析引擎。因此,您可以从 node_modules 导入您的 Sass 模块。只需在它们前面加上一个 ~ 来告诉 webpack 这不是一个相对导入......重要的是只在它前面加上 ~,因为 ~/ 解析到主目录。 请注意,~/ 似乎并不指代我的主目录。或我尝试测试的任何目录。有什么方法可以实际尝试找出这是指的地方吗?? 警告:不推荐使用~:github.com/webpack-contrib/…【参考方案8】:

所选答案没有提供可行的解决方案。

OP 的做法似乎不规律。共享/公共文件通常位于标准样板目录partials 下。然后,您应该将 partials 目录添加到配置导入路径中,以便在代码中的任何位置解析部分。

当我第一次遇到这个问题时,我认为 SASS 可能会给你一个类似于 Node 的 __dirname 的全局变量,它保留了当前工作目录的绝对路径 (cwd)。不幸的是,它没有,原因是因为无法对 @import 指令进行插值,因此您无法执行动态导入路径。

根据SASS docs.

你需要在你的 Sass 配置中设置:load_paths。由于 OP 使用 Compass,我将按照文档 here 进行操作。

您可以按照目的使用 CLI 解决方案,但为什么呢?将其添加到config.rb 会更方便。使用 CLI 覆盖 config.rb 是有意义的(例如,不同的构建场景)。

因此,假设您的 config.rb 位于项目根目录下,只需添加以下行: add_import_path 'sub_directory_a'

现在@import 'common'; 可以在任何地方正常工作。

虽然这回答了 OP,但还有更多。

附录

您可能会遇到想要以嵌入式方式导入 CSS 文件的情况,也就是说,不是通过 CSS 提供的开箱即用的 vanilla @import 指令,而是实际 将 CSS 文件内容与您的 SASS 合并。还有另一个question,答案没有定论(该解决方案不能跨环境工作)。那么解决方案就是使用this SASS 扩展。

安装后,将以下行添加到您的配置中:require 'sass-css-importer',然后在代码中的某处添加:@import 'CSS:myCssFile';

请注意,必须省略扩展才能使其正常工作。

但是,当我们尝试从非默认路径导入 CSS 文件并且add_import_path 不尊重 CSS 文件时,我们会遇到同样的问题。因此,要解决这个问题,您需要在配置中添加另一行,这自然是相似的:

add_import_path Sass::CssImporter::Importer.new('sub_directory_a')

现在一切都会很好。

附: 我注意到sass-css-importer 文档表明除了省略.css 扩展外,还需要CSS: 前缀。我发现它无论如何都有效。有人发起了issue,到目前为止仍未得到答复。

【讨论】:

【参考方案9】:

导入具有不同相对位置的嵌套导入的.scss 文件将不起作用。建议的最高答案(使用大量 ../)只是一个肮脏的 hack,只要您添加了足够的 ../ 以到达项目部署操作系统的根目录,它就可以工作。

    添加目标 SCSS 路径作为 SCSS 编译器的搜索目标。 这可以通过将 stylesheets 文件夹添加到 scss 配置文件中来实现,这是您正在使用的框架的功能,

config.rd 处使用:load_paths 用于基于指南针的框架(例如rails)

scss-config.json 使用以下代码为fourseven/meteor-scss


  "includePaths": [
    "/node_modules/ionicons/dist/scss/"
  ]

    使用绝对路径(相对于相对路径)。

例如,使用fourseven/meteor-scss,您可以使用 突出显示 根据以下示例,您的项目的顶层

@import "/node_modules/module-name/stylesheet";

【讨论】:

【参考方案10】:

要定义要导入的文件,可以使用所有文件夹的通用定义。您只需要知道它与您定义它的文件有关。更多关于导入选项的示例,您可以查看here。

【讨论】:

【参考方案11】:

考虑使用 includePaths 参数...

“解析 SASS @imports 时,SASS 编译器使用 loadPaths 中的每个路径。”

https://***.com/a/33588202/384884

【讨论】:

【参考方案12】:

node-sassnode.js 的官方 SASS 包装器)提供了一个命令行选项 --include-path 来帮助满足此类要求。

示例:

package.json:

"scripts": 
    "build-css": "node-sass src/ -o src/ --include-path src/",

现在,如果您的项目中有一个文件 src/styles/common.scss,您可以使用 @import 'styles/common'; 在项目中的任何位置导入它。

更多详情请参考https://github.com/sass/node-sass#usage-1。

【讨论】:

只是一个警告,从 2022 年开始,node-sass 已被弃用 npmjs.com/package/node-sass【参考方案13】:

如果在 Visual Studio 中使用 Web Compiler,您可以在 compilerconfig.json.defaults 中添加 includePath 的路径。那么就不需要一定数量的../,因为编译器会使用 includePath 作为查找导入的位置。

例如:

"includePath": "node_modules/foundation-sites/scss",

【讨论】:

【参考方案14】:

最好的方法是使用 sass-loader。它以 npm 包的形式提供。 它解决了所有与路径相关的问题,并使其变得超级简单。

【讨论】:

以上是关于使用 SASS 时,如何从不同目录导入文件?的主要内容,如果未能解决你的问题,请参考以下文章

Gulp-sass 无法编译 scss 文件

如何使用 webpack 从项目根目录导入外部文件?

如何使用 gulp 从 node_modules 导入 bootstrap 4 sass/scss

React,Sass,从 .scss 文件导入 img 时出错

Sass中如何导入文件

如何从 node_modules 文件夹导入 sass 主题模块