Ecco un algoritmo semplificato per @import <import_arg>;
. Questo deriva dalla lettura del codice sorgente per SASS e dall'esecuzione dei miei test.
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
Nota per brevità, sto usando di Ruby File#dirname
, File#basename
così come File#expand
che è come Node.js di path.resolve
. Sto usando uno pseudocodice simile a Ruby ma è comunque destinato a essere pseudocodice.
Punti chiave:
- Non c'è un ordine di precedenza. Piuttosto che implementare un ordine di precedenza, SASS rinuncia quando ci sono diversi possibili candidati. Ad esempio, se hai scritto
@import "x"
e dici che esistono entrambi x.scss
e _x.scss
, allora sass genererà un errore di ambiguità. Allo stesso modo, se esistono entrambi x.scss
e x.sass
, viene generato un errore di ambiguità.
- I percorsi di caricamento vengono provati dall'ordine 'sinistra a destra'. Forniscono una radice o una base per risolvere le importazioni da (in modo simile a come UNIX usa $ PATH per trovare gli eseguibili). La directory di lavoro corrente viene sempre provata per prima. (Anche se questo comportamento will change 3,2-3,4)
- percorsi di carico sono sempre cercato indipendentemente dal fatto che si è utilizzato
./
o ../
- In un file sass, normali file css cannot be imported
Se volete maggiori dettagli , mi sento di raccomandare la lettura del codice sorgente del SASS:
- il metodo di
sass/lib/sass/tree/import_node.rb
import
. Sulle righe 53-56 è possibile vedere lo stesso ciclo come quello all'interno della funzione search
nel nostro pseudocodice.
- il
Importers::Base
classe astratta sass/lib/sass/importors/base.rb
. I commenti di questo file sono abbastanza utili.
- il metodo
find_real_file
di sass/lib/sass/importors/filesystem.rb
. Le righe 112-126 implementano la nostra funzione possible_files
. La linea 156 verifica che ci sia una sola corrispondenza. Se non c'è, la riga 167 genera un errore di ambiguità, altrimenti la riga 183 preleva il file corrispondente.
Edit: Non ero felice con la mia precedente risposta così ho riscritto per essere un po 'più chiaro. Algorithm ora gestisce correttamente i caratteri di sottolineatura nel nome file (l'algoritmo precedente non l'ha fatto). Ho anche aggiunto alcuni punti chiave che rispondono alle altre domande poste dall'OP.
fonte
2015-12-18 22:25:47
Ti rendi conto che Sass è open source e che potresti provare a scoprirlo da solo, giusto? – cimmanon
@cimmanon sì. Non credi che ci sia qualche valore in esso presente anche nello pseudocodice? – callum