[Rails6][sprockets4.0.0]Sprocketsを無効にするためにapp/assetsフォルダ以下を削除すると、Sprockets::Railtie::ManifestNeededErrorが出た

# はじめに
Railsが用意しているjavascript, css, 画像などのアセットを管理するGemに、`Sprockets`と`Webpacker`があります。
この2つを軽く説明すると、

|名称|説明|
|:-----------|:------------|
|Sprockets|Rails3.1から導入されたアセットパイプライン。`app/assets`ディレクトリでアセットを管理する|
|Webpacker|Rails6から導入された、[Webpack](https://webpack.js.org/)というモジュールバンドラをRails用にラップしたgem|

WebpackerはSprocketsとの共存を考えて設計されており、Sprockets, Webpackerどちらも使うことを想定しています。
ただまあどちらもアセットを管理するgemなわけで、ややこしくなるしどちらか1つだけ使えばいいのでは？と僕は考えています。
以前作成した[Asobi](https://qiita.com/sasakura_870/items/1eb666c80c4ceb815dd8)というWebアプリでも、Webpackerでアセットを管理したので、最終的にSprocketsが管理する`app/assets`ディレクトリを丸ごと削除しました。
次のWebアプリでもWebpackerを使う予定だったので、`app/assets`を削除したのですが…

# 環境
- Ruby 2.7.0
- Rails 6.0.2

# 起きたこと
`Sprockets`を使わないようにするための手順はいくつかありますが、最終的に`app/assets`というディレクトリは完全にいらなくなります。
なので最初に`app/assets`を削除しました。

```bash
$ rm -rf app/assets
```

試しにここで`rails s`でRailsを起動しました。
ここでは正常にRailsサーバが起動すると思ったのですが…

```bash
WARNING: Nokogiri was built against LibXML version 2.9.10, but has dynamically loaded 2.9.4
=> Booting Puma
=> Rails 6.0.2.1 application starting in development
=> Run `rails server --help` for more startup options
Exiting
Traceback (most recent call last):

# 中略...

/Users/user/rails_test/vendor/bundle/ruby/2.7.0/gems/sprockets-rails-3.2.1/lib/sprockets/railtie.rb:105:in `block in <class:Railtie>': Expected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)
But did not, please create this file and use it to link any assets that need
to be rendered by your app:

Example:
  //= link_tree ../images
  //= link_directory ../javascripts .js
  //= link_directory ../stylesheets .css
and restart your server
```

どうやら`app/assets/config/manifest.js`が無いため`Sprockets::Railtie::ManifestNeededError`というエラー出て`rails s`が終了したようです。
だが待ってほしい。これまでこんなエラー出てこなかったぞ？

# 原因
[こちらのページ](https://www.redmine.org/issues/32223)によると、どうやらSprocketsのバージョンが`4.0.0`になってから起きるようになったエラーのようです。
> Redmine doesn't start with Sprockets::Railtie::ManifestNeededError if sprockets 4.0.0 is installed.
>>
>>$ bin/rails c
>>Traceback (most recent call last):
>>    28: from bin/rails:4:in `<main>'
>>    27: from bin/rails:4:in `require'
>>.
>>.
>>.
>>/Users/maeda/redmines/gems/ruby/2.6.0/gems/sprockets-rails-3.2.1/lib/sprockets/railtie.rb:105:in `block in <class:Railtie>': Expected to find a manifest file in `app/assets/config/manifest.js` (Sprockets::Railtie::ManifestNeededError)
>>But did not, please create this file and use it to link any assets that need
>>to be rendered by your app:
>>
>>Example:
>>  //= link_tree ../images
>>  //= link_directory ../javascripts .js
>>  //= link_directory ../stylesheets .css
>>and restart your server

`Redmine doesn't start with Sprockets::Railtie::ManifestNeededError if sprockets 4.0.0 is installed.`と書いてありますね。

[Sprocketsのissue](https://github.com/rails/sprockets/issues/643)にも同様のエラー報告がありました。

> Actual behavior
> An error is thrown since 4.0, this didn't occur on 3.7.2:
>
>> rake aborted!
>>  Sprockets::Railtie::ManifestNeededError: Expected to find a manifest file in `app/assets/config/manifest.js`
>>  But did not, please create this file and use it to link any assets that need
>>  to be rendered by your app:
>>
>>  Example:
>>    //= link_tree ../images
>>    //= link_directory ../javascripts .js
>>    //= link_directory ../stylesheets .css
>>  and restart your server
>

3.7.2では起きなかったエラーとのことで、やはりSprockets 4.0.0から起きているエラーのようです。

# 対処法
## `Sprockets`のバージョンを3.7.2に下げる
バージョン4.0.0から起きているのであれば、バージョンを3.7.2に下げれはエラーが解消されるはず！
まずは`Gemfile`に以下のコードを追記します。

```Gemfile
# Sprockets4.0だと、app/assetsディレクトリを削除するとSprockets::Railtie::ManifestNeededErrorが発生する
gem 'sprockets', '~> 3.7.2'
```

そして`bundle update`を実行します。(bundle installじゃないよ)
改めて`rails s`を実行すると、無事エラーが解消されました。

```bash
$ rails s
WARNING: Nokogiri was built against LibXML version 2.9.10, but has dynamically loaded 2.9.4
=> Booting Puma
=> Rails 6.0.2.1 application starting in development
=> Run `rails server --help` for more startup options
/Users/user/rails_test/vendor/bundle/ruby/2.7.0/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/stack.rb:37: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/user/rails_test/vendor/bundle/ruby/2.7.0/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/static.rb:110: warning: The called method `initialize' is defined here
Puma starting in single mode...
* Version 4.3.1 (ruby 2.7.0-p0), codename: Mysterious Traveller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://127.0.0.1:3000
* Listening on tcp://[::1]:3000
Use Ctrl-C to stop
```

## `rails new`のオプションの`--skip-sprockets`を指定する

`rails new`のオプションに`--skip-sprockets`というものがあります。
これを指定してRailsアプリを作成すると、`config/application.rb`のrequireが一部変化します。

```application.rb
# --skip-sprocketsを指定した場合
require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_mailbox/engine"
require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
# require "sprockets/railtie"
require "rails/test_unit/railtie"


# 指定しない場合、この1文のみ記述される
require 'rails/all'
```

`require "sprockets/railtie"`がコメントアウトされています。
この状態であれば、`app/assets`ディレクトリを削除しても`Sprockets::Railtie::ManifestNeededError`は発生しません。

### 余談 : `--skip-sprockets`を指定してもSprocketsはインストールされる
[Railsガイド](https://railsguides.jp/asset_pipeline.html)に書いてありますが、この`--skip-sprockets`は`application.rb`の変更と一部のgemを除外してくれるだけです。

```Gemfile
# Railsガイドで説明されている、除外されるgem
gem 'sass-rails'
gem 'uglifier'
gem 'coffee-rails'
```

上記の除外されるgemのリストにSprocketsはありません。
そう、`--skip-sprockets`オプションでSprocketsを使わないRailsアプリを作成しても、**Sprocketsはインストールされます。更に`app/assets`も生成されます。**

これに関しては、[GitHubのRails](https://github.com/rails/rails/issues/29749)にも以下のissueが投げられています。

> The `app/assets` folder, and its underlying structure, is created, despite the fact that dropping stylesheets into `app/assets/stylesheets` no longer causes them to be loaded. This is misleading, at best.

つまり、「`--skip-sprockets`を指定したら`app/assets`を作らないようにした方が誤解がないのでは？」というissueが**3年前に**投げられています。
でも3年経っても変化はないので、恐らくこの状況を変えるつもりはないのでしょう。

# まとめ
`Sprockets`を使わないのであれば、`Sprockets`のバージョンを`3.7.2`に落としましょう。
もしくは`rails new`のオプションで`--skip-sprockets`を指定しましょう。

# 参考文献
https://www.redmine.org/issues/32223
https://github.com/rails/sprockets/issues/643
https://github.com/rails/rails/issues/29749
https://railsguides.jp/asset_pipeline.html