当前位置:  开发笔记 > 编程语言 > 正文

Sass用于解析@import语句的算法是什么?

如何解决《Sass用于解析@import语句的算法是什么?》经验,为你挑选了1个好方法。

Node.js用于解析require()调用的算法在伪代码中非常清楚地记录.

萨斯的@import声明我需要同样的事情.

我知道,@import 'foo'将尝试基本名称的各种组合foo,并_foo与扩展.scss,并.sass在同一目录中进口文件,以及相对于任何配置的"负载路径"的......但什么样的顺序,这些都试过,即什么如果有多个文件可以满足@import?以a开头./还是../影响它是否尝试加载路径?还有其他事情会尝试我没有涉及吗?.css文件怎么样?

该指南并未说明"Sass很聪明,并会为您解决问题".该参考文档进入更详细,但还是不拼出来的解决步骤.

任何人都可以在伪代码中提供它使用的确切算法吗?



1> James Lawson..:

这是一个简化的算法@import ;.这是通过阅读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: /sf/ask/17360801/
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.scssx.sass再存在时引发的多义性错误.

从"从左到右"顺序尝试加载路径.它们提供了一个根或基础来解析导入(类似于UNIX使用$ PATH来查找可执行文件).始终首先尝试当前工作目录.(虽然此行为将从3.2 更改为3.4)

负载路径总是不管尝试是否使用./../

在sass文件中,无法导入常规.css文件

如果您想了解更多细节,我建议您阅读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提出的其他问题.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有