Đây là thuật toán đơn giản cho @import <import_arg>;
. Điều này bắt nguồn từ việc đọc mã nguồn cho SASS và chạy các thử nghiệm của riêng tôi.
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
Lưu ý cho ngắn gọn, tôi đang sử dụng Ruby File#dirname
, File#basename
cũng như File#expand
mà là giống như Node.js của path.resolve
. Tôi đang sử dụng mã giả giống Ruby nhưng nó vẫn có nghĩa là mã giả.
điểm chính:
- Không có trật tự ưu tiên. Thay vì thực hiện một thứ tự ưu tiên, SASS bỏ cuộc khi có một số ứng cử viên có thể. Ví dụ: nếu bạn đã viết
@import "x"
và nói cả hai số x.scss
và _x.scss
tồn tại, thì khi đó sass sẽ ném một lỗi mơ hồ. Tương tự, nếu cả hai x.scss
và x.sass
tồn tại thì lỗi mơ hồ được ném.
- Đường dẫn tải được thử từ thứ tự 'từ trái sang phải'. Chúng cung cấp một root hoặc base để giải quyết các import từ (tương tự như cách UNIX sử dụng $ PATH để tìm các file thực thi). Thư mục làm việc hiện tại luôn được thử trước. (Mặc dù hành vi này will change 3,2-3,4)
- đường dẫn tải luôn cố gắng bất kể bạn sử dụng
./
hoặc ../
- Trong một tập tin sass, các file .css thường xuyên cannot be imported
Nếu bạn muốn biết thêm chi tiết , Tôi khuyên bạn nên đọc mã nguồn của SASS:
import
phương thức sass/lib/sass/tree/import_node.rb
. Trên các dòng 53-56, bạn có thể thấy tương tự cho vòng lặp như một bên trong hàm search
trong mã giả của chúng ta.
Importers::Base
lớp trừu tượng sass/lib/sass/importors/base.rb
. Các ý kiến của tập tin này khá tiện dụng.
- phương thức
find_real_file
sass/lib/sass/importors/filesystem.rb
. Dòng 112-126 thực hiện chức năng possible_files
của chúng tôi. Dòng 156 kiểm tra chỉ có một kết quả phù hợp. Nếu không có dòng 167 ném một lỗi mơ hồ, dòng khác 183 chọn một tập tin phù hợp.
Chỉnh sửa: Tôi không hài lòng với câu trả lời trước đây của mình vì vậy tôi đã viết lại một chút rõ ràng hơn. Thuật toán bây giờ xử lý một cách chính xác dấu gạch dưới trong tên tệp (thuật toán trước đó không). Tôi cũng đã thêm một số điểm chính để giải quyết các câu hỏi khác mà OP hỏi.
Nguồn
2015-12-18 22:25:47
Bạn nhận ra rằng Sass là nguồn mở và bạn có thể tự mình tìm ra điều này, đúng không? – cimmanon
@cimmanon yep. Bạn không nghĩ rằng có bất kỳ giá trị trong nó hiện có trong mã giả quá? – callum