node-sassを導入したらherokuにデプロイできなくなった

木内智史之介(シャッチョー)
ミンカさんけっこんしてくださいおねがいします(ズザー SEGAさん、DIVAの筐体ください(ズザー

あれ、herokuにデプロイできない!

react+reduxで開発中のアプリが、急にherokuにデプロイできなくなりました。
werckerでログを確認してみると、下記のようなログが出力されて、デプロイが失敗しています。(buildは通ってる)

Module build failed: Error: ENOENT: no such file or directory, scandir ‘/tmp/build_e81a776262c3c5270a8ed7b8fb4a580a/client/node_modules/node-sass/vendor’

そういえば、node-sassをインストールした

css関係を、glamorで書いていたのですが、CSS in JSを実際に試してみた感想としては、「いろいろつらいな」でした笑。

何がつらいって、やはり、jsでstyleを書くにあたっての文法上の制約というか、

import css from 'glamor';
const style = css({
backgroundColor: '#999999',
WebkitTapHighlightColor: transparent,
});

という、シンプルな内容でも、

  • ”-(ハイフン)”が使用できないので、camelCaseで記述する
  • ベンダープリフィックスはハイフンから始まるので大文字開始になる
  • 文字列を値に入れる場合は「”」や「’」で括らなくてはならない

という、JSとしては当たり前の、しかしcssでは当たり前ではなかったことがたくさん出てきます。

CSS in JSは、サクッとstyleを充てたい時などには重宝しますが、プロジェクト全体のスタイル管理としては「ないな」というのが正直な感想です。
そう思った瞬間に、「css modules」への乗せ替えを着手しました。

css modulesで行くにしても、cssは慣れ親しんだsassで書きたい!

そのタイミングで「node-sass」のインストールを行ったのです。

ローカルでの挙動は問題ない

glamorからの移行作業もおおむね完了し、ローカルでの挙動は問題なかったので、コミットし、pushした訳です。
ビルドも成功して、いざdeployという段で、先ほどのエラーが発生します。

あれ〜おかしいなあ〜なんか変だな〜

と、小一時間頭を抱えました。

おそらくheroku上のキャッシュが問題

ローカルでは大丈夫、けどheroku上で動作しない、という状況から、 おそらくheroku側にstoreされてるnode_modules周りのキャッシュが悪さをしているのだろうと、 予測をします。

heroku repo pluginのインストール、からのキャッシュ削除!

$ heroku plugins:install heroku-repo
$ heroku repo:purge_cache -a appname

これで、キャッシュが削除されました。

さあdeployだ!

さて、キャッシュがクリアされた状態で、再度deployを試してみます。

すると…無事成功です!

しかし

キャッシュクリア後初回のdeployしか成功しませんでした

なぜや!なぜなんや! 毎回キャッシュをクリアするのだけはいやだ…

node-sass関係の問題をいろいろ調べてみた

調べてみると、似たような状況の方はちらほらいたようです。僕だけじゃなかった。ほっ。

Error: ENOENT: no such file or directory, scandir ‘**/node_modules/node-sass/vendor’ #1579

xzyfer commented on 22 Jun 2016 In this case, running npm install again doesn’t fix the issue because npm thinks it is installed. This is why you must run npm rebuild node-sass.

ふむ。npm rebuild node-sassを実行すればいけるんか?!

deployコマンドにnode-sassのrebuildを追加

package.json

"scripts": {
"build:production": "NODE_ENV=production npm rebuild node-sass; webpack --config webpack.config.js",
},

本番向けのビルドでは常にnode-sassをrebuildするようにしてみました。

これで、常にdeployが成功するようになりました。

今夜もぐっすり眠れそうです。
Have a good night !