使用 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-sass
(node.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 从 node_modules 导入 bootstrap 4 sass/scss