Help us understand the problem. What is going on with this article?

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

はじめに

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

名称 説明
Sprockets Rails3.1から導入されたアセットパイプライン。app/assetsディレクトリでアセットを管理する
Webpacker Rails6から導入された、WebpackというバンドラをRails用にラップしたgem

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

環境

  • Ruby 2.7.0
  • Rails 6.0.2

起きたこと

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

$ rm -rf app/assets

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

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が終了したようです。
だが待ってほしい。これまでこんなエラー出てこなかったぞ?

原因

こちらのページによると、どうやら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 inapp/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にも同様のエラー報告がありました。

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に以下のコードを追記します。

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

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

$ 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ガイドに書いてありますが、この--skip-sprocketsapplication.rbの変更と一部のgemを除外してくれるだけです。

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

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

これに関しては、GitHubのRailsにも以下の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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした