cal*_*lum 6 sass node-sass libsass
Node.js用于解析require()调用的算法在伪代码中非常清楚地记录.
萨斯的@import声明我需要同样的事情.
我知道,@import 'foo'将尝试基本名称的各种组合foo,并_foo与扩展.scss,并.sass在同一目录中进口文件,以及相对于任何配置的"负载路径"的......但什么样的顺序,这些都试过,即什么如果有多个文件可以满足@import?以a开头./还是../影响它是否尝试加载路径?还有其他事情会尝试我没有涉及吗?.css文件怎么样?
该指南并未说明"Sass很聪明,并会为您解决问题".该参考文档进入更详细,但还是不拼出来的解决步骤.
任何人都可以在伪代码中提供它使用的确切算法吗?
这是一个简化的算法@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
Run Code Online (Sandbox Code Playgroud)
请注意,为了简洁起见,我使用的是Ruby File#dirname,File#basename以及File#expand类似Node.js的path.resolve.我正在使用类似Ruby的伪代码,但它仍然是伪代码.
关键点:
@import "x"并说两者x.scss并且_x.scss存在,那么sass会抛出歧义错误.同样地,如果这两个x.scss和x.sass再存在时引发的多义性错误../或../如果您想了解更多细节,我建议您阅读SASS的源代码:
import方法sass/lib/sass/tree/import_node.rb.在第53-56行,您可以看到与search我们的伪代码中函数内部相同的for循环.Importers::Base抽象类sass/lib/sass/importors/base.rb.这个文件的评论非常方便.find_real_file方法sass/lib/sass/importors/filesystem.rb.第112-126行实现了我们的possible_files功能.156行检查只有一个匹配.如果没有,则第167行引发歧义错误,否则第183行选择一个匹配的文件.编辑:我对我之前的回答感到不满意,所以我把它改写得更清楚一些.算法现在可以正确处理文件名中的下划线(以前的算法没有).我还添加了一些关键点来解决OP提出的其他问题.