> 之前開發 SCSS 的過程中,會用 `@import` 來引入其他 SCSS 檔案的樣式。不過,最近得知 `@import` 是舊的用法,容易出問題,且已被棄用;而 `@use` 是 Sass 官方推薦的新方法,設計得更安全、模組化。 > > > 以下會說明: > > 1. `@import`、`@use` 的介紹 > 2. `@use` 的偷懶用法 > 3. SCSS 與 JavaScript 語法比較 ## `@import`:全域引入容易污染 `@import` 的會導致檔案裡的變數、mixin、function 等全部會進入**全域作用域**,所有其他檔案也能看到,這就很容易發生命名衝突。 而且,同一個檔案如果被多次引入,也會多次產出內容,導致 CSS 重複,這在大型專案中特別麻煩。 首先有個變數: ```scss // _variables.scss $main-color: red; ``` 再來有個檔案,裡面沒引入該變數: ```scss // components/_card.scss .card { background: $main-color; } ``` 最後打包時,打包檔案有引入變數,結果可以順利使用! ```scss // style.scss @import 'variables'; @import 'components/card'; body { color: $main-color; } ``` 這種寫法很直接,但由於易導致汙染問題,[Sass 官方已在 2024 年 10 月 17 日棄用 @import](https://sass-lang.com/blog/import-is-deprecated/)。 ## `@use`:區隔良好的模組化設計 相較之下,`@use` 是為了解決 `@import` 帶來的混亂而設計的。[根據 Sass 官方文件](https://sass-lang.com/documentation/at-rules/use/#differences-from-import),`@use` 的設計有幾個特別的原則: 1. **變數、mixin、function 只在當前檔案有效**,不會污染全域。 2. **每個檔案只會被載入一次**,避免重複產生 CSS。 3. **`@use` 必須寫在檔案開頭**,不能寫在樣式規則裡。 4. **每條 `@use` 只能引入一個檔案**,不像 `@import` 可以一次列很多。 5. **引入路徑必須加上引號**,即使你是用縮排式語法也一樣。 簡單來說,它會預設幫你把導入的內容包在一個**命名空間(namespace)**裡,只在當前檔案有效,也不會影響到其他地方。 ```scss // style.scss @use 'variables'; // 預設以檔名作為命名空間,此處即是「variables」 body { color: variables.$main-color; } ``` 如果要自己指定命名空間也可以。 ```scss // style.scss @use 'variables' as v; // 手動給予命名空間 body { color: v.$main-color; } ``` 這樣的寫法清楚又安全,變數一看就知道是從哪裡來的,也避免不同檔案之間互相干擾。而且 `@use` 對於同一個檔案的引入會自動去重,只會載入一次,不怕重複產出 CSS。 ## `@use as *`:偷懶小技巧,也要慎用 有些時候你可能會覺得一直打 `variables.$main-color` 很煩,這時你可以使用 `as *`,把模組的內容全部「打開」,讓變數、mixin 可以直接使用: ```scss @use 'variables' as *; body { color: $main-color; } ``` 雖然寫起來方便,但這樣其實就跟 `@import` 一樣會**失去命名空間的保護**,也可能導致命名衝突。建議這種寫法**只用在集中管理的總入口檔案**(如 `main.scss`),且事前明確整理好所有要暴露的資源。 當你在 `main.scss` 中整理好所有模組後,若希望其他檔案能透過 `main.scss` 一次取得所有東西,就必須使用 `@forward` ,再出口引入的樣式。 ```scss // main.scss @forward './colors'; @forward './mixins'; @forward './reset'; @forward './base'; ``` 這樣其他檔案就可以寫: ```scss @use 'main' as *; ``` 並取得所有經過 `@forward` 的變數與函式。`@forward` 的行為就像是在建立一個「再出口模組」,讓你統一管理整個專案的樣式 API。 ### 實務建議 - 如果是多人協作或大型專案,請**堅持使用 `@use` 並保留命名空間**。 - 若你有一個整理好的主入口檔案(例如 `main.scss`),可以在其中使用 `@forward` 統整資源,再用 `@use 'main' as *` 引入,這是較為穩健的偷懶方式。 - 除非你非常確定控制範圍,不建議到處使用 `as *`,避免難以追蹤來源與錯誤。 ## SCSS 與 JavaScript 語法比較 `@use` / `@forward` 與 JavaScript 的 `import` / `export` 概念有點像,類比起來更好懂,因此整理成下面對照表: | Sass | JavaScript | 說明 | | | --- | --- | --- | --- | | `@use 'xxx';` | `import * as xxx from './xxx.js';` | 引入一個模組,有命名空間保護 | | | `@forward 'xxx';` | `export * from './xxx.js';` | 把某個模組「轉出口」給別人用 | | | `@use 'xxx' as *;` | `import * from 'xxx';`(不加命名空間) | 全部打開,不建議大量使用 | | | 沒有命名空間就直接使用變數 | JavaScript 全域變數 | 可能導致衝突或來源不明的狀況 | | | `@import` | 像舊版 JS 沒有模組系統 | 所有東西都攤在一起,很混亂 | | ## 總結 > 舊專案可維持用 `@import`,但新專案一定要用 `@use`。 對沒接觸過這語法的人來說,可利用 JavaScript 的 `import` / `export` 的概念來理解其功用。 >