できない.dev

PostCSS で @import が展開されず 1 ファイルにまとまらない

@import の展開には postcss-import が必要で、しかもプラグイン配列の先頭に置かないと後続のプラグインが読み込み先の CSS を見られない。
登録と順序の 2 点を確認する。

公開:

要約

PostCSS は標準では @import を展開しません。
CSS の @import はブラウザが実行時に解決する仕様なので、ビルド時に 1 ファイルへまとめたい場合は postcss-import を入れます。

そして、このプラグインは配列の先頭に置く必要があります。

// postcss.config.js
export default {
  plugins: {
    "postcss-import": {},
    autoprefixer: {},
  },
};

よくある原因

  1. プラグインが入っていない: PostCSS 本体は CSS を解析して変換する土台であり、@import の解決は担当しない。
    出力にも @import がそのまま残る。
  2. 配列の途中に置いている: 公式リポジトリは「This plugin should probably be used as the first plugin of your list. This way, other plugins will work on the AST as if there were only a single file to process」と書いている。
    後ろに置くと、それより前のプラグインは読み込み先の CSS を見ないまま処理を終える。
    Autoprefixer をこの順序で外すと、読み込んだファイルにだけプレフィックスが付かない状態になる。
  3. @import の位置が後ろすぎる: CSS の仕様上、@import@charset@layer を除くすべてのルールより前に書く必要がある。
    他のルールの後ろに置いた @import は無効になる。
  4. パスが解決できていない: 相対パスの誤りや、パッケージ側の style / main フィールドの指す先が無い場合に、その記述だけが展開されずに残る。

解決策

1. postcss-import を先頭に置く

導入して、配列の先頭に置きます。

npm install -D postcss-import
// postcss.config.js
export default {
  plugins: {
    "postcss-import": {},
    "postcss-nesting": {},
    autoprefixer: {},
  },
};

配列記法の場合も順序の考え方は同じです。

import postcssImport from "postcss-import";
import autoprefixer from "autoprefixer";
 
export default {
  plugins: [postcssImport(), autoprefixer()],
};

2. @import をファイルの先頭にまとめる

有効な位置に書かれているかを確認します。

/* src/app.css */
@import "./reset.css";
@import "./tokens.css";
 
:root {
  --color-bg: #0b0b0c;
}

次のように途中へ書いたものは、ブラウザでも展開されません。

body {
  margin: 0;
}
 
@import "./reset.css"; /* ここでは無効 */

3. パッケージの読み込み方を確認する

node_modules 配下のパッケージは、パッケージ名だけで書けます。
公式リポジトリの説明では、モジュールを読み込むとき index.csspackage.jsonstyle / main フィールドが指すファイルを探します。

@import "normalize.css";

~ を付ける記法は webpack の css-loader 側の慣習で、postcss-import では不要です。

4. 出力を見て確かめる

ビルド後の CSS に @import が残っていれば、展開されていません。

npx postcss src/app.css -o dist/app.css
grep -n "@import" dist/app.css

何も出なければ展開できています。
設定ファイル自体が読み込まれていない可能性もあるので、そのときは /postcss/config-not-loaded-esm/ を確認してください。

この記事は役立ちましたか?