【Rails】Nokogiri関連のインストールエラーと戦うための方法 総集編【これでダメなら多分】

## 自己紹介
高等学校国語科の教員から転職後、物流×ITの株式会社ダイアログでWebエンジニアとして働きつつ、本アドベントカレンダーのDMMWEBCAMPでエンジニアメンターをしております[yuki](https://twitter.com/yuki82511988)と申します。

未経験からエンジニアを目指す方向けの質問回答や、個人メンターの相談も乗っておりますので、何かあったらDMでお願いします。

**最後にポエムの宣伝**

<blockquote class="twitter-tweet" width=”100px” height=”100px”><p lang="ja" dir="ltr">焼け石に水だとしても「未経験からwebエンジニアを目指すのはそんなに楽ではないのでは…？」<br><br>と疑うことをされた方向けに、『苦労して目指す』ことをテーマに自分の経験と今をまとめてみたいと思いました。<br><br>なるべく週一で、ただ白黒のテキストを綴っていこうと思います。<a href="https://t.co/eseTIXjaUZ">https://t.co/eseTIXjaUZ</a> <a href="https://t.co/X9WemoXQfR">pic.twitter.com/X9WemoXQfR</a></p>&mdash; yuki (@yuki82511988) <a href="https://twitter.com/yuki82511988/status/1322911830780518400?ref_src=twsrc%5Etfw">November 1, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

では本題へ。

## 本記事の概要
本記事は、Railsのプロジェクト作成時（bundle install時）に起こるGem:`nokogiri`関連のインストールエラーに関して、調査結果と対策をまとめたものになります。
自分でもこれ関連のエラーには非常に悩まされ、検索するたびに、`Rails nokogiri インストール　できない`といった内容で検索候補が表示されていたので、つまづきポイントなのかな？と思ったのが執筆の動機です。

さまざまなNokogiri関連の記事を拝見した上で、改めてまとめてみようと思いましたので、何かの参考になれば幸いです。

```
１、前提条件やNokogiriの説明
２、何故エラーが起こるのかエラー分と、原因の調査結果
３、実際の対策
```

といった流れで説明させていただきます。

### 前提条件や筆者の環境、読むとわかること
`rbenv 1.1.2-20-g143b2c9`
`ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin19]`
`Rails 6.0.3.3`
開発環境はローカル（Mac本体に直接構築）です。
RailsやGemfileをなんとなく知っている、rbenvやhomebrewを使っていることが前提条件です。

本記事を読んでいただくと、`Nokogiri`関連のエラー対策が分かります。


## そもそもNokogiriとは?Gemとは?
> 彼を知り己を知れば百戦殆からず　孫子 謀攻篇

ということでまず、`Nokogiri`が何者なのか掘り下げていきましょう。

### Nokogiriとは
🗒 [Nokogiri](https://nokogiri.org/tutorials/parsing_an_html_xml_document.html)（公式ドキュメント）
💻 [GitHubのソースコード](https://github.com/sparklemotion/nokogiri)

調べたところ、`Nokogiri`はRubyのGemで、スクレイピング（Webサイトから情報を抽出する）をする際に利用されるもののようです。

これは正直調査してわからなかったことなのですが、確認した限り、`Rails 5.2.4`系以上のバージョンでプロジェクトを作ろうとすると、自動的に`bundle install`対象になると思われます。こちらに関して詳しい方がいらしたら、コメントで教えてください。

ひとまず、最近のRailsのプロジェクトを作ろうとすると自動でインストールされるようです。

また、公式のGithubをみると、以下のようなことが書いてあります。

>**Requirements**
Ruby 2.4.0 or higher, including any development packages necessary to compile native extensions.
In Nokogiri 1.6.0 and later libxml2 and libxslt are bundled with the gem, but if you want to use the system versions:...

`Nokogiri`にはNative Extentionというものが関わっているようです。

### Native extentionとは（後でエラー対策の際にも関わってきます）
こちらは調べたところによると、ruby以外の言語にもgemが依存している際に、関連するその言語のライブラリをインストールしておく必要があるよといったもののようです。

具体的には、`Nokogiri`をインストールする際には以下のものが必要になるようですね。（公式Githubから引用）
>libxml2 >=2.6.21 with iconv support (libxml2-dev/-devel is also required)
libxslt, built with and supported by the given libxml2 (libxslt-dev/-devel is also required)

rubyの2.4.0以上では、自動的にこれらのライブラリは含まれているようです。ただ、何かしらの原因でインストールできていないと`Nokogiri`のインストール時にエラーが出ます。

## 想定されるエラー
さて、いよいよ~~敵~~`Nokogiri`を知ることができたので、想定されるエラーの説明です。

具体的には…

- 新規プロジェクトをRailsで立ち上げた際の`bundle install`でコケる
- これまで普通に起動できていたのに、`rails s`を行ったときにコケる

そしてそのメッセージが以下のような感じである。

```
# ①こんなの
Could not find nokogiri-<nokogiriのバージョン> in any of the sources
Run `bundle install` to install missing gems.

# ②もしくはこんなの
libiconv is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
    -----
    *** extconf.rb failed ***
    Could not create Makefile due to some reason, probably lack of necessary
    libraries and/or headers.  Check the mkmf.log file for more details.  You may
    need configuration options.

# ③あとはこんなの
An error occurred while installing nokogiri (nokogiriのバージョン), and Bundler cannot continue.
Make sure that `gem install nokogiri -v 'nokogiriのバージョン' --source 'https://rubygems.org/'` succeeds
```

もー嫌になりますよね。特に③、`gem install nokogiri -v 'nokogiriのバージョン' --source 'https://rubygems.org/'`を実行して、無事インストールされたのにもう一回`bundle install`すると全く同じエラーが出たことのある人はいませんか？

対策を考えていましょう。

### エラーのパターンと対策：関連するパッケージがインストールできていない
まず、可能性として「Native extentionとは」のところで説明させていただいた関連するライブラリがインストールできていない可能性があります。

そちらのライブラリを直接インストールすると解決する場合があるので、やってみましょう。

```
$ brew tap homebrew/dupes
$ brew install libxml2 libxslt libiconv
$ brew link --force libxml2 libxslt libiconv
```

その後

```
$ bundle config build.nokogiri --use-system-libraries
$ bundle install
```

いかがでしたでしょうか。これでもダメな場合、先に進んでください。

### エラーのパターンと対策：bundle install先の書き込み権限がない（？）

自分が何回か引っかかったケースとして、`bundle install`先のフォルダにアクセスする権限がなく、どんなにコマンドを実行しても書き込むことができなかったというものがありました。この場合は、なぜか直接`gem nokogiri`を指定して`sudo`で実行してもうまくいきませんでした。

ということで、書き込み権限を与えます。Gemfileのあるディレクトリで、以下を実行してみてください。

```
$ sudo chmod 666 Gemfile
$ sudo chmod 666 Gemfile.lock
$ bundle install
```
それでもダメなら、次へ。

## あんまり良くないが、とりあえず解決したい人向け（これで何度も解決しました。）
何人かに相談していただいて、一緒に悩んで試行錯誤した結果、一番こちらの方法で解決しましたが、暴力的なので責任は取れません。
どうにもこうにも解決せず、どうしてもすぐに解決したい場合ご利用ください。

**結論：現在使っているrubyをアンインストールし、再度インストールし、もう一度bundle installし直すことです。※もしくは、それが怖い場合は、新しいバージョンのrubyをインストールして今後はそちらを使っていきましょう。**

###再インストール編
まず、ターミナルでbashを使っている方は、`bash_profile`の方にrubyやbundle関係の変な記述がないかチェックしましょう。

```
$ vi ~/.bash_profile
```
私の場合、ruby関係の記述は以下の二行だけでした。責任は負い兼ねますが、余計なものは一旦削除してもいいかもしれません。

```text:.bash_profile
export PATH="~/.rbenv/shims:/usr/local/bin:$PATH"
eval "$(rbenv init -)"
```
そちらが確認できたら、rubyのバージョンを確認し、アンインストール、再インストール、キャッシュを消し、そのバージョンを今後は適用するようにコマンドを実行します。

```
$ ruby -v
$ rbenv uninstall [表示されたバージョン]
$ rbenv install [上と同じバージョン]
$ rbenv rehash 
$ rbenv local  [上と同じバージョン]
$ rbenv global [上と同じバージョン]

```
ここまで実行できたら、改めて`rails new`や直接`bundle install`などを実行してみてください。

### 新しいバージョンのrubyを入れる場合
上と同様、`.bash_profile`の確認後

```
$ rbenv install -l
$ rbenv install [一覧の中の好きなバージョン]
$ rbenv rehash 
$ rbenv local  [上と同じバージョン]
$ rbenv global [上と同じバージョン]

```
ここまで実行できたら、改めて`rails new`や直接`bundle install`などを実行してみてください。

## まとめ
いかがだったでしょうか。`nokogiri`関係のエラーは、さまざまな原因があり、それは他ライブラリのせいだったり、書き込み権限のせいだったり、はたまた色々やった結果`.bash_profile`のパス設定がおかしかったりなど、色々な要因があると思います。

最後は極端な方法になってしまいましたが、この記事が誰かの役に立ちますと幸いです。
以下にこれまで読んだ記事を参考記事として記載させていただきます。ぜひ併せてご覧ください。

#### 参考記事
- nokogiriのエラーに関して
[bundle install時にnokogiriエラー(nokogiriのバージョン1.10.4)](https://qiita.com/sasakura_870/items/5dc93e21c34c50b9114a)
[箱のプログラミング日記  bundle installでnokogiriのインストールエラー【Rails】](https://www.y-hakopro.com/entry/2020/08/19/104756)
[nokogiri を嫌いにならないで 〜インストール時のエラーを乗り越えろ〜](https://qiita.com/dskst/items/b1f073fcffeca3bc9fc6)
[bundle install時の nokogiriエラー備忘録](https://qiita.com/E-46/items/b1dc5807f8604952bf93)
[mocomoの勉強部屋 【ruby on rails】bundle configの設定とbundle installエラー](https://mocomo012.hatenablog.com/entry/2020/03/22/233056)

- アクセス権限に関して
[コジマノテック　【落とし穴】権限って大事だよね…。](https://kojimanotech.com/2018/05/15/42/)


- rubyのインストールに関して
[MacでのRuby環境構築2020](https://qiita.com/chihiro/items/efdf8b88865b7a93971f)

- その他
[Bundlerでビルドオプションを指定する](https://qiita.com/thunders/items/101c6b329830fb1fb27d)