A. SCSS 完整自學中文版文檔教程10_Sass的模塊化【Sass/SCSS 官方英文文檔翻譯整理】
Sass的模塊化詳解
Sass的模塊化主要通過@use指令來實現。@use載入的樣式表被稱為模塊(moles),Sass提供了許多內置模塊,包含有用的功能。
@use載入的模塊在編譯後只會輸出一次到css中,而使用@import多次引入同一模塊會反復輸出到css中。編譯後的css結果展示了這一點。
@use前面只能出現@forward或變數聲明,所有代碼只能出現在@use之後。載入模塊成員時,可以通過.、.()、@include .()來訪問。
使用@use載入的模塊成員只能在當前文件中訪問,若希望多文件共同訪問,可使用@forward規則通過一個共享文件轉發所有成員。@use將命名空間添加到成員名中,因此編寫簡單名稱如$radius或$width是安全的,這與舊的@import規則不同,後者鼓勵用戶編寫像$mat-corner-radius這樣的長名稱以避免與其他庫沖突,@use有助於保持樣式表的清晰和可讀性!
使用@use ... as ...語法可以來自定義命名空間名稱,@use ... as *語法則去除命名空間,但不建議這樣做,以免導致命名沖突。
私有成員可通過在模塊成員前使用-或_來隱藏,使其不暴露給其他文件訪問。
配置引入時,如果模塊中的變數使用了!default標志並有默認值,可在使用@use引入時配置自己的值來覆蓋默認值。
用@use ... with ...配置模塊非常方便,特別是在使用最初為使用@import規則而編寫的庫時,但不推薦用於更高級用例。若需一次配置很多變數,可通過傳遞一個map作為配置,或在模塊載入後更新配置,考慮寫一個mixin來設置變數,再寫另一個mixin來注入樣式。
使用@use "mole"引入模塊時,無需寫擴展名,程序會自動查找。在所有系統上,路徑分隔符統一使用/而不是反斜線\。當前目錄模塊不需要寫./。文件名以_開頭的Sass文件只打算作為模塊載入,而不是自己編譯,這些被稱為部分(partials),它們告訴Sass工具不要嘗試自己編譯這些文件。導入這些模塊時可以不用書寫_符號。
使用@use "directory"導入一個目錄時,編譯器會嘗試自動查找_index.scss或_index.sass文件。載入一個純CSS文件作為模塊時,不允許任何特殊的Sass特性(如variables, functions, mixins),為了避免作者一不小心把Sass寫進CSS中,所有Sass特性如果不是合法的CSS代碼將會報錯。否則,CSS將按原樣呈現,甚至可以被繼承(extend)!
當使用@use載入一個文件時,這個文件可以使用@forward來使另一個文件中的mixin、函數和變數可以暴露出去,通常用於跨多個文件組織Sass庫。@forward和@use使用方式相同,但作用卻完全不一樣。@forward的作用是轉發模塊成員,而不是引入成員到當前文件使用。載入一個模塊的成員通過@forward後,這些成員並不能在當前文件內訪問,而僅僅是將這些成員當作自己的成員對外暴露出去。例如,在a.scss中定義了變數$red,在b.scss中使用@forward "a.scss",但在b中無法訪問a.$red,但在另一個文件c.scss中使用@use "b.scss"後,可以通過b.$red訪問到a中定義的變數。如果想要在b.scss中使用變數,依然需要使用@use "a.scss"來引入變數,然後就可以訪問a.$red了。在b.scss文件中同時使用@forward和@use時,建議先寫@forward再寫@use,因為這樣,在c.scss中使用@use...with()配置的變數值會先生效,這樣b.scss引用的變數也是配置後的變數。@forward雖然對變數、mixin、函數等只能起轉發作用,但對其他樣式代碼和@use一樣,也會引入並編譯,所以在使用了@forward"mole"的文件中,就算沒有使用@use,也可以去繼承mole.scss的樣式。
當一個文件轉發多個文件中的成員時,在使用時可能會存在多個文件中的成員同名,這樣會導致編譯出現錯誤,就算沒有同名,也有可能在使用時不清楚到底是哪個模塊的成員。通過@forward "mole" as xxx-*可以給同一個模塊中的成員統一添加前綴。
默認情況下,@forward會將一個模塊中所有成員都轉發,如果只想轉發某些成員,或不想轉發某些成員,可以這樣書寫,各個成員通過逗號,分隔開,如果成員是變數,不能省略$符號。在轉發其他模塊的成員時,可以對成員進行配置,修改默認值,或者指定一個確定的值均可。
在 sass 中導入 css 文件時,不要顯示地寫出擴展名.css,只寫文件名即可。因為如果顯示地寫出擴展名.css,這用來表示是在導入純 css 文件,編譯器則不會去編譯@import語句,而是原封不動地輸出這條語句。如果將@import"a;"改為@import"a.css;",上面代碼編譯時會報錯:目標選擇器未找到,因為編譯器遇到@import"a.css";語句,它就會認為這是一條導入純 css 文件的語句,不需要在編譯階段處理它,而是用於運行時的導入。所以要去繼承這個文件中的選擇器是無法找到目標選擇器的。
在 sass 中導入 css 並編譯時,導入的 css 代碼塊將嵌套在該上下文中,這使得嵌套的@import對於將 CSS 塊定位到特定元素或媒體查詢非常有用。在嵌套@import 引入的文件中定義的頂級 mixins,函數,變數依然會被導入為全局的變數。在 sass 中導入 css 文件時,不要顯示地寫出擴展名.css,只寫文件名即可。如果顯示地寫出擴展名.css,這用來表示是在導入純 css 文件,編譯器則不會去編譯@import語句,而是原封不動地輸出這條語句。如果將@import"a;"改為@import"a.css;",上面代碼編譯時會報錯:目標選擇器未找到,因為編譯器遇到@import"a.css";語句,它就會認為這是一條導入純 css 文件的語句,不需要在編譯階段處理它,而是用於運行時的導入。所以要去繼承這個文件中的選擇器是無法找到目標選擇器的。
假設在index.scss中@import"b.scss",而b.scss中使用了@use"a.scss",在index.scss中可以訪問b.scss中的所有成員(包括私有成員),但無法直接訪問a.scss中的成員,除非b.scss中使用了@forward"a.scss"。
假設我們在維護一個sass庫,如果我們改成新的模塊系統(@use),我們會擔心那些之前使用@import的用戶會無法正常運行。為了解決這個問題,sass支持一種文件叫做「@import專用文件」,也就是這個文件只能通過@import導入,而無法通過@use來導入。給一個文件命名為.import.scss即可,這樣就能保持對@import的兼容,又能使用新的@use模塊系統。
使用@use導入模塊,如果模塊中使用了@import導入其他文件,index.scss無法訪問到a.scss中沒有被轉發的成員,但是a.scss中的所有樣式代碼依然會被全部導入。
在sass中導入css文件時,不要顯示地寫出擴展名.css,只寫文件名即可。因為如果顯示地寫出擴展名.css,這用來表示是在導入純css文件,編譯器則不會去編譯@import語句,而是原封不動地輸出這條語句。如果將@import"a;"改為@import"a.css;",上面代碼編譯時會報錯:目標選擇器未找到,因為編譯器遇到@import"a.css";語句,它就會認為這是一條導入純css文件的語句,不需要在編譯階段處理它,而是用於運行時的導入。所以要去繼承這個文件中的選擇器是無法找到目標選擇器的。
假設在index.scss中@import"b.scss",而b.scss中使用了@use"a.scss",在index.scss中可以訪問b.scss中的所有成員(包括私有成員),但無法直接訪問a.scss中的成員,除非b.scss中使用了@forward"a.scss"。
假設我們在維護一個sass庫,如果我們改成新的模塊系統(@use),我們會擔心那些之前使用@import的用戶會無法正常運行。為了解決這個問題,sass支持一種文件叫做「@import專用文件」,也就是這個文件只能通過@import導入,而無法通過@use來導入。給一個文件命名為.import.scss即可,這樣就能保持對@import的兼容,又能使用新的@use模塊系統。
使用@use導入模塊時,在模塊被第一次@import的語句前面,定義一個全局變數即可配置變數值而不使用默認值。模塊只會被載入一次,所以就算在第一次@import模塊後更改了配置(即使是間接的),再次@import模塊也不會使用修改的配置。如果通過@use或@forward去載入一個使用了@import的文件,將會載入到這個文件的所有公共成員及樣式,以及它@import導入的所有成員和代碼,相當於就是@import導入的文件的內容就像是直接寫在@import語句的位置一樣。