🧭
Sass: @import全盛の既存プロジェクトを最短で@use移行する実践ガイド(破壊しない段階移行)
「@import だらけで変数が何度も展開されてウザい…」「でも一括置換で壊したくない…」
そんな現場向けに、ほぼ一括で @use へ移行できる橋渡し(互換)方式をまとめました。
ビルドを壊さずに段階的に"真の @use 流儀"へ寄せていきます。
TL;DR(結論)
-
いきなり全置換は危険:
@useは名前空間付きで、裸の$var/@includeが使えなくなるため。 -
まずは
@forwardを使った「バレル(index)」を作成し、
各所の複数@importを 1行の@use ... as *に置換 → 既存の書き味を保持。 - その後、時間のある箇所から
as *をやめて名前空間化(衝突・多重展開から卒業)。
🔍 事前チェック(ここだけは見て)
-
テーマ系の変数に
!defaultを付けておく(将来with (...)で上書き可能にするため)
// /_base/_variables.scss
$brand-color: #0a0 !default;
$space-s: 8px !default;
- 割り算 / を将来直す方針(当面は放置でも可だが、警告源)
- 置き換え先:
@use "sass:math";→math.div(10px, 2)
- 置き換え先:
1) 「バレル(再エクスポート)」を作る
💡 バレルとは?
複数のモジュールを1つのファイルにまとめて再エクスポートする手法です。
JavaScriptのindex.jsと同じ考え方で、インポート文をシンプルにできます。
/_base/_index.scss を新規作成し、よく使うベース資産を @forward で束ねます。
// /_base/_index.scss
@forward "variables";
@forward "mixins";
@forward "functions"; // あれば
これにより、下流は index を 1回使うだけで、variables/mixins などをまとめて参照できます。
2) 既存の @import を「ほぼ一括」で @use 化
Before(よくあるやつ)
@import "../_base/variables";
@import "../_base/mixins";
// ...その他いろいろ
After(1行に集約)
@use "../_base/index" as *;
-
as *により、従来どおり$brand-colorや@include media-spを「裸」で使えます。 - つまり ビルドを壊さず
@useへ移行可能(まずは"挙動の互換"を得る)。
ポイント:
@useは同一モジュールを1回しか評価しないため、多重展開・重複CSSが解消されます。
3) "真の @use 流儀"へ段階移行
余裕が出た箇所から、as * をやめて 名前空間を導入します。
@use "../_base/index" as base;
.button {
color: base.$brand-color;
@include base.media-sp {
font-size: 14px;
}
}
テーマ上書きが必要な場合は、エントリ付近で with (...) を使います(変数側に !default 必須):
// theme-entry.scss(例)
@use "../_base/variables" with (
$brand-color: #f33
);
@use "../_base/mixins";
🧩 一括置換の正規表現メモ(サンプル)
プロジェクトごとにパス深度が違うため、よくあるパターンを複数用意しておくと一撃で置換しやすいです。
以下は VS Code の「正規表現モード」を想定。
2行セットの import を 1行の use に
Find:
^\s*@import\s+["']\.\.\/_base\/variables["'];\s*\n\s*@import\s+["']\.\.\/_base\/mixins["'];\s*$
Replace:
@use "../_base/index" as *;
パス深度違い(../../_base/... など)も同様にパターンを用意。
あるいは、(_base/variables|_base/mixins) でグルーピングして全体を index に置換する方法もアリ。
📂 フォルダ設計の勘所(例)
sass/
├─ _settings/ // トークン(色/余白/タイポ等)
├─ _mixins/ // mediaや関数群
├─ _base/ // variables/mixins/functions + _index.scss
├─ _module/ // ユーティリティ(.mod-***)
├─ _layout/ // レイアウト(.l-***)
└─ app.scss // エントリ
🚧 ありがちハマりポイント
- 変数の上書きができない? →
!default+with (...)をセットで。 - 割り算の警告 →
@use "sass:math"+math.div()に。 -
as *はダメ? → 「まず壊さない移行」ではアリ。最終的に外す方向で。 - 同じ index を複数回
@use?→ 評価は1回だけ。安心。
🎯 サンプル:@import 全盛の既存ファイルを救う
Before
@import "../_base/variables";
@import "../_base/mixins";
.card {
color: $brand-color;
@include media-pc { padding: 20px; }
}
After(互換フェーズ)
@use "../_base/index" as *;
.card {
color: $brand-color; // 互換維持
@include media-pc { padding: 20px; }
}
After(本移行フェーズ)
@use "../_base/index" as base;
.card {
color: base.$brand-color;
@include base.media-pc { padding: 20px; }
}
✅ チェックリスト
-
_base/_index.scssを作り、@forwardでvariables/mixinsを束ねた -
@importを@use "../_base/index" as *;に置換 - 出力CSSが重複していないか確認
- 触る箇所から
as *を外し、名前空間化 - 必要なら
!default + with (...)でテーマ上書き - 将来の
math.div置換計画を立てた
Discussion