postcss.config.js が ESM プロジェクトで読み込めずビルドが落ちる
package.json に type: module があると postcss.config.js は ES モジュールとして評価されるため、module.exports や require が使えず落ちる。
export default に書き換えるか拡張子を .cjs にする。
公開:
要約
module is not defined in ES module scope や require is not defined で PostCSS の設定読み込みが落ちるのは、package.json に "type": "module" があるためです。
この指定があると .js ファイルは ES モジュールとして評価され、module.exports も require も使えません。
設定を ES モジュールの書き方に直します。
// postcss.config.js
import autoprefixer from "autoprefixer";
export default {
plugins: [autoprefixer],
};よくある原因
"type": "module"とmodule.exportsの組み合わせ: Node.js はpackage.jsonのtypeで.jsの扱いを決める。moduleなら ES モジュールとして読むので、CommonJS の書き方は構文エラーになる。- 設定ファイル内の
require: プラグインをrequire("autoprefixer")で読み込んでいると、同じ理由で落ちる。 - 拡張子で明示していない:
.jsはpackage.jsonの設定に左右される。
チームでtypeを切り替えたときに、設定ファイルだけ取り残されることがある。 - TypeScript 版を置いた: postcss-load-config は
postcss.config.tsも探すが、その場合はtsxかjitiを peer dependency として自分で入れる必要がある。
解決策
1. export default 形式に書き換える
プラグインをオブジェクト記法で書く場合は、そのまま export default を付けます。
// postcss.config.js
export default {
plugins: {
autoprefixer: {},
},
};配列記法にすると、プラグイン関数を直接渡せてオプションも書けます。
// postcss.config.js
import autoprefixer from "autoprefixer";
export default {
plugins: [autoprefixer({ grid: "autoplace" })],
};2. 拡張子を .cjs にして CommonJS のまま使う
既存の設定を触りたくないときは、ファイル名を変えるだけで通ります。
postcss-load-config は postcss.config.cjs も探索対象にしています。
mv postcss.config.js postcss.config.cjs.cjs は type の値にかかわらず CommonJS として読まれるので、module.exports と require がそのまま使えます。
3. .mjs で ES モジュールを明示する
逆に、type を指定していないプロジェクトで ES モジュールとして書きたい場合は .mjs にします。
mv postcss.config.js postcss.config.mjs4. TypeScript の設定ファイルにはローダーを入れる
postcss.config.ts を使うなら、TypeScript を読める実行環境が要ります。
npm i -D tsxjiti でも同じ役割を果たします。
どちらも入れずに .ts の設定だけ置くと、設定が見つからないまま処理が進み、プラグインが一切適用されない状態になります。