「Next.js の dev server が突然固まる」「git status が秒単位で固まるようになった」「Python の venv が壊れる」「Rust の target/ が勝手に消える」——もしあなたの開発プロジェクトが ~/Desktop または ~/Documents 配下に置かれているなら、犯人はコードでもフレームワークでもなく macOS の iCloud Desktop & Documents Sync かもしれない。
これは Node.js 固有の問題ではない。言語・フレームワークを問わず、Mac で開発する全員が踏む可能性のある地雷だ。しかも日本語圏ではこの問題を正面から扱った記事がほぼ無く、「Next.js 遅い」で検索しても webpack や Docker の話ばかりヒットして本当の原因に辿り着けない。
この記事では、なぜ iCloud Desktop Sync が開発環境を壊すのか、その根本原因を4層に分解した上で、言語別の被害事例と brctl コマンドを使った診断方法、そして3段階の対策を解説する。
よくある症状:言語は違っても原因は同じ
以下の症状のうち、どれか1つでも心当たりがあれば、iCloud が原因の可能性が高い。
- Node.js / Next.js: dev server が突然固まる、HMR が効かない、
next buildがENOENT: no such file or directoryで落ちる - Python:
python -m venvで作った仮想環境が数日後に壊れる、ModuleNotFoundErrorが唐突に出る - Rust:
cargo buildがキャッシュを使わず毎回フル再ビルドになる、target/のサイズが iCloud 容量を圧迫する - Go:
go buildが異常に遅い、module cache が破損する - Git:
git statusが秒単位で固まる、fatal: bad objectで履歴が壊れる、git fsckが警告を出す - Xcode / Flutter: ビルドが途中で失敗する、
DerivedDataやPodsが勝手に消える - 共通症状: Mac を起動直後にプロジェクトを開くと数十秒〜数分間 Finder やエディタがフリーズする
これらは一見バラバラに見えるが、根本原因は全て同じだ。
犯人: iCloud Desktop & Documents Sync + ストレージ最適化
macOS には iCloud Desktop & Documents Sync という機能がある。システム設定の「Apple ID → iCloud → iCloud Drive → デスクトップと書類フォルダ」がこれだ。これを ON にすると、~/Desktop と ~/Documents 配下の全ファイルが iCloud Drive に同期される。
問題なのは 「Mac のストレージを最適化」が同じ画面でデフォルト ON になっている点だ。この機能は、OS が「最近アクセスされていない」と判断したファイルをローカル実体から削除し、iCloud 上にのみ残す挙動を取る。必要になった瞬間に再ダウンロードして復元する仕組みで、これを dataless 化(または evict)と呼ぶ。
この仕組み自体は、写真やドキュメントのような「たまにしか開かないファイル」には便利だ。しかし開発プロジェクトに適用されると、次の4つのメカニズムを通じて地獄の扉を開く。
根本原因の4層:言語非依存で壊れる理由
1. dataless 化によるランダムなファイル消失
OS から見て「ユーザーが Finder で開いてない」ファイルは evict 候補になる。node_modules/ の中身、venv/ の中身、target/debug/ のビルド成果物、.git/objects/ の pack ファイル——ユーザーが直接クリックしないファイルこそが最も evict されやすい。
dataless 化されたファイルは、アクセスされた瞬間に同期ダウンロードが走る。数万ファイルある node_modules が一斉に evict されると、npm run dev の起動時に数分〜十数分のフリーズが発生する。
2. fsevents / ファイル監視の破綻
Next.js や Vite、webpack、turbopack、chokidar は全て macOS の FSEventStream API(fsevents) を使ってファイル変更を監視している。
dataless ファイルに対してファイル監視を張ると、watcher が stall したり、誤発火したり、イベントを取りこぼしたりする。HMR が効かない、保存しても反映されない、ビルドが途中で止まる——こうした症状の多くはこれが原因だ。
3. symlink のサポート不備
iCloud Drive は symlink(シンボリックリンク)を完全にはサポートしていない。同期の過程で symlink が実体化されたり、壊されたり、権限が変わったりする。これが特に刺さるのは以下のケースだ。
- pnpm の node_modules: pnpm は hard link と symlink を多用するため、iCloud 配下では一撃で壊れる
- Python の venv:
venv/bin/pythonは Python 本体への symlink で、これが壊れると venv が起動しない - Homebrew の Cellar:
/usr/localではなく開発ディレクトリ内に置いた場合 - Xcode の Pods: CocoaPods も内部で symlink を使う
4. 拡張属性(xattr)の剥奪
macOS は拡張属性(com.apple.quarantine, com.apple.metadata:* など)をファイルに付与している。iCloud を経由して同期されたファイルは、この xattr の一部が落ちることがある。
影響を受けるのは署名検証、コード実行許可、Gatekeeper の判定など。特にビルドツールが生成したバイナリや、ダウンロードしたアセットで問題が起きやすい。
言語・ツール別の被害事例
ここまで読んで「自分が使ってる言語は大丈夫か?」と不安になったはずだ。言語別に具体的な被害を整理する。
Node.js / Next.js / Vite
最も被害が派手で、英語圏では既に専用の CLI ツール(nosync-icloud, nocloud)まで存在する。
Error: ENOENT: no such file or directory, open '/Users/you/Desktop/app/node_modules/next/dist/compiled/...'
これは node_modules 配下のファイルが dataless 化された状態でアクセスされ、同期 DL が間に合わなかった場合に出る典型的なエラーだ。.next/ や .vite/ のビルドキャッシュも同様に evict される。
Python(venv / Poetry / uv)
$ source venv/bin/activate
$ python
zsh: ./venv/bin/python: bad interpreter: no such file or directory
venv の bin/python が Python 本体への symlink だったが、iCloud 同期で壊れたパターン。site-packages/ 内の .pyc ファイルが evict されると ModuleNotFoundError が唐突に出る。Poetry や uv も同じ問題を抱える。
Rust(Cargo)
target/ ディレクトリは 1 プロジェクトで簡単に数 GB を超える。iCloud 容量を圧迫するだけでなく、evict されると incremental build が効かず毎回フル再ビルドになる。しかも symlink を多用する target/doc や target/release が壊れる。
Go
$GOPATH/pkg/mod が ~/go にあれば直接の被害はないが、プロジェクト内に vendor/ を置いている場合は同じ被害を受ける。Go は独自の module cache を持つので、cache 内の ZIP が evict されると go mod download が失敗する。
Git(全言語共通の地雷)
これは言語に関係なく全プロジェクトが踏む。.git/objects/ 配下のオブジェクトファイル(特に .git/objects/pack/*.pack)が evict されると、次のような症状が出る。
fatal: bad object HEAD
error: object file .git/objects/ab/cdef... is empty
fatal: loose object abcdef... (stored in .git/objects/ab/cdef...) is corrupt
Git の pack ファイルは数百 MB になることもあり、dataless 化の最有力候補だ。一度 .git が壊れると修復は非常に面倒で、最悪 clone し直しになる。
Xcode / Flutter / CocoaPods
Apple 自身が Xcode プロジェクトを iCloud Drive 配下に置くことを非推奨にしている。Flutter も公式ドキュメントで同様に警告している。DerivedData, Pods/, .dart_tool/, ios/Flutter/ などが全て被害を受ける。
Docker Desktop
~/Desktop 配下のディレクトリを volume mount するとさらに悲惨だ。iCloud → macOS ファイルシステム → Docker の仮想化レイヤーという多段同期が発生し、I/O が実用にならない速度まで劣化する。
自分が踏んでいるか確認する:brctl コマンド
macOS には brctl(bird control の略、bird は iCloud 同期デーモン)という CLI ツールが標準で入っている。これで dataless 化の状態を確認できる。
# プロジェクトディレクトリが iCloud 管理下にあるか確認
brctl status ~/Desktop/my-project
# dataless 化されているファイルを一覧
brctl download ~/Desktop/my-project/node_modules # 強制的に全部DL
# iCloud 管理下にあるディレクトリを再帰的にチェック
find ~/Desktop/my-project -type f -exec ls -lO {} \; | grep dataless
ファイルのフラグに dataless が含まれていれば、それはローカル実体が無く雲の中にしかない。ls -lO の出力で dataless フラグを持つファイルが大量に見つかったら、確実に被害を受けている。
また、Finder で ~/Desktop を開いてファイル名の横に雲マーク(↓付きクラウドアイコン)が表示されていれば、そのファイルは evict 済みだ。
対策:3段階で根治する
対策は「根本解決」「妥協解決」「応急処置」の3段階がある。おすすめは 1(根本解決) だ。
対策1(推奨): 開発ディレクトリを iCloud の外に出す
最も確実で、二度とこの問題に悩まされない方法。~/code, ~/dev, ~/src など ~/Desktop と ~/Documents の外 に開発用ディレクトリを作り、全プロジェクトを移動する。
mkdir -p ~/code
mv ~/Desktop/my-project ~/code/my-project
cd ~/code/my-project
# node_modules は作り直すのが安全
rm -rf node_modules
npm install
~/code のようなホームディレクトリ直下のパスは iCloud Desktop & Documents Sync の管轄外なので、同期も dataless 化も発生しない。
VS Code や Cursor の「最近開いたプロジェクト」は一度クリアされるが、これは一時的な代償だ。
対策2: iCloud Desktop & Documents Sync を OFF にする
開発以外にも ~/Desktop を使っているが、同期は不要な場合。システム設定から以下の手順で OFF にできる。
- システム設定を開く
Apple ID→iCloud→iCloud Drive- 「オプション」をクリック
- 「デスクトップと書類フォルダ」のチェックを外す
注意点として、OFF にすると iCloud 上のファイルが 一度ローカルから消える ように見える。実際には ~/Library/Mobile Documents/ 配下に残っているので、必要なファイルは手動で ~/Desktop に戻す必要がある。事前に別の場所にバックアップを取っておくと安全だ。
対策3(応急処置): .nosync 拡張子でフォルダを除外する
iCloud は .nosync で終わる名前のファイル/フォルダを同期対象から除外する 特殊ルールを持っている。これを利用して、node_modules だけを除外できる。
cd ~/Desktop/my-project
mv node_modules node_modules.nosync
ln -s node_modules.nosync node_modules
node_modules.nosync が実体で、node_modules はそれへの symlink。iCloud は .nosync ディレクトリを無視するため同期されない。
同じ手法で target.nosync, venv.nosync, .git.nosync なども作れる。ただし .git を symlink にすると一部の Git ツールが動かなくなる ため、Git ディレクトリに対してはこの手法は避けた方が良い。
この方法は「Desktop から離れたくない」場合の応急処置として有効だが、プロジェクトが増えるたびに手動で対応する必要があるのでスケールしない。nosync-icloud のような CLI ツールで自動化する選択肢もある。
「私は ~/Desktop で開発してる、おかしい?」への回答
全くおかしくない。以下の理由から、非常に多くの macOS 開発者がこの罠に無自覚に落ちている。
- iCloud Desktop & Documents Sync は macOS のセットアップ時にデフォルト ON を推奨される。多くのユーザーは何も考えずに ON のまま使っている
~/Desktopと~/Documentsは最も直感的な作業場所であり、ここにプロジェクトを置くのはごく自然- 症状が出るまで iCloud が原因だと気付けない。dev server が遅ければ webpack を疑い、git が壊れれば自分の操作ミスを疑う。まさか OS の同期機能が犯人とは思わない
- 英語圏では有名な問題だが、日本語の情報が極端に少ない。「Next.js 遅い」で検索しても Docker や webpack の話ばかり出てくる
Apple Developer Forums にもこの問題の専用スレッドがあり、プロの iOS/macOS エンジニアでも踏んでいる。恥じる必要は全くないが、気付いた今日が対策のタイミングだ。
まとめ:開発環境を守る iCloud 対策チェックリスト
□ プロジェクトが ~/Desktop または ~/Documents 配下にないか確認する
→ 配下にあれば iCloud Desktop & Documents Sync の管轄範囲
□ システム設定で「Mac のストレージを最適化」がデフォルト ON になっている
→ dataless 化(evict)が自動発生している可能性が高い
□ brctl status <path> で iCloud 管理下か確認する
→ ls -lO で dataless フラグを持つファイルが大量にあれば被害確定
□ 開発ディレクトリを ~/code や ~/dev など iCloud 管轄外に移動する(推奨)
→ 同期も dataless 化も発生しない、根本解決
□ Desktop を使い続けたい場合は Desktop & Documents Sync を OFF にする
→ 事前にバックアップを取ってから切り替える
□ 応急処置として node_modules.nosync + symlink で除外する
→ プロジェクトが多い場合はスケールしないので注意
□ .git ディレクトリは nosync 化しない
→ Git ツールの一部が symlink 化された .git に対応していない
Node.js、Python、Rust、Go、Xcode——どの言語で開発していても、~/Desktop や ~/Documents 配下にプロジェクトを置いている限り、この問題は等しく襲ってくる。フレームワークのアップデートで直る類の問題ではないので、開発ディレクトリを iCloud の外に出すのが最も確実な予防策だ。
もし今、原因不明の dev server フリーズや git 破損に悩まされているなら、まず brctl status でプロジェクトの状態を確認してみてほしい。案外、あなたのコードは最初から壊れていなかったのかもしれない。
