这是一个简化的算法@import <import_arg>;
。这是通过阅读 SASS 的源代码和运行我自己的测试得出的。
def main(import_arg)
let dirname = File.dirname(import_arg)
let basename = File.basename(import_arg)
if import_arg is absolute ... # omitted as this is a rare case
else return search(dirname, basename)
end
# try resolving import argument relative to each path in load_paths
# 1. If we encounter an unambiguous match, we finish
# 2. If we encounter an ambiguous match, we give up
# see: https://stackoverflow.com/a/33588202/3649209
def search(dirname, basename)
let cwd = operating system current working directory
let load_paths = paths specified via SASS_PATH env variable and via --load-path options
let search_paths = [cwd].concat(load_paths)
for path in search_paths
let file = find_match(File.expand_path(basename, path), basename)
if (file != false) return file
end
throw "File to import not found or unreadable"
end
def find_match(directory, basename)
let candidates = possible_files(directory, basename)
if candiates.length == 0
# not a single match found ... don't give up yet
return false
else if candidates.length > 1
# several matching files, ambiguity! ... give up
# throw ambiguity error
throw "It's not clear which file to import"
else
# success! exactly one match found
return candidates[0]
end
end
# NB: this is a bit tricky to express in code
# which is why I settled for a high-level description
def possible_files(directory, basename)
# if `basename` is of the form shown on the LHS
# then check the filesystem for existence of
# any of the files shown on the RHS within
# directory `directory`. Return the list all the files
# which do indeed exist (or [] if none exist).
# LHS RHS
# x.sass -> _x.sass, x.sass
# x.scss -> _x.scss, x.scss
# x -> x.scss, _x.scss, x.sass, _x.sass
# _x -> _x.scss, _x.sass
end
为简洁起见,我使用的是 Ruby 的File#dirname
,File#basename
以及File#expand
类似于 Node.js 的path.resolve
。我正在使用类似 Ruby 的伪代码,但它仍然是伪代码。
关键点:
- 没有优先顺序。SASS 没有实施优先顺序,而是在有多个可能的候选者时放弃。例如,如果你写了
@import "x"
并说两者都x.scss
存在_x.scss
,那么 sass 会抛出一个歧义错误。类似地,如果两者都x.scss
存在,x.sass
则会引发歧义错误。
- 从“从左到右”的顺序尝试加载路径。它们提供了一个根或基础来解析导入(类似于 UNIX 使用 $PATH 查找可执行文件的方式)。当前工作目录总是首先尝试。(尽管此行为将从 3.2更改为 3.4)
- 无论您是否使用
./
或../
- 在 sass 文件中,无法导入常规 .css 文件
如果您想了解更多详细信息,我建议您阅读 SASS 的源代码:
编辑:我对以前的答案不满意,所以我将其重写为更清晰一些。算法现在可以正确处理文件名中的下划线(以前的算法没有)。我还添加了一些关键点来解决 OP 提出的其他问题。