Tidy up Rails gems you do not use
This is an English traslation of my blog entry "年末なので Rails 依存関係の大掃除" which is for Ruby on Rails Advent Calendar 2022 in Japan. You might find useful Rails articles from developers in Japan.
Ruby on Rails declares itself as "a full-stack framework" on the top page. As mentioned, Rails actually is a full plate of common features to create Web applications. Therefore, it is required to install many many Ruby gems that your application may not need.
This year, I started Rails developer job and found that
- Unused gems consume 11 MB of 53 MB (21%). Not good since it slow down installation on my PC or CI.
- Meaningless vulnerability alert and automatic updates are even made to unused gems. Not good since we may miss important alert or updates.
I was concerned about these so I tried to tidy up unused Rails gems.
Assumption
All items should be satisfied.- Your codebase are already configured as Rails app (or Rails Engine)
- Gemfile.lock file is put under version control so same versions are used regardless of environment
- Enough test coverageso you will find issues caused removing gem
Steps to remove unused Rails gems
If we look into "rails" gem's gemspec file, we find that the "rails" gem depends on 12 gems. We are going to minimize this number.First, you find the "rails" gem delcration in Gemfile, like this:
gem 'rails', '7.0.4'
Replace it with the above-mentioned 12 gems:
RAILS_VERSION = '7.0.4'
gem 'actioncable', RAILS_VERSION
gem 'actionmailbox', RAILS_VERSION
gem 'actionmailer', RAILS_VERSION
gem 'actionpack', RAILS_VERSION
gem 'actiontext', RAILS_VERSION
gem 'actionview', RAILS_VERSION
gem 'activejob', RAILS_VERSION
gem 'activemodel', RAILS_VERSION
gem 'activerecord', RAILS_VERSION
gem 'activestorage', RAILS_VERSION
gem 'activesupport', RAILS_VERSION
gem 'railties', RAILS_VERSION
Then, run "bundle install" command and confirm that only the "rails" gem is removed from the Gemfile.lock file.
Then, repeat the below steaps for each of 12 gems.
- Remove `gem '...'`
- Run "bundle install" and confirm that the removed gem is gone from the updated Gemfile.lock.
- If the target gem is not removed, it indicates that the gem is used by other gem. Consider the other gem can be removed or not.
- Search your source and delete the relevant files or configs regarding the removed gem.
- For example, if we remove "actioncable" gem, search keywords should consider different cases or separators, such as "Action Cable" or "action_cable". I recommend search with "git grep" by regular expression. E.g.) git grep --extended-regexp --ignore-case "action.?cable"
- Run tests. Spot the issue and fix it.
- If everything is fine after the gem is removed, then commit it. Revert if issue sticks.
Example 1: Removing activejob gem
If
activejob gem is removed, you may see "NameError: unitiliazed constant
ActiveJob"
error". The error is happening if there are usage of class or modules
defined in the removed gem. E.g.) "class ApplicationJob <
ActiveJob::Base" with empty logic.
Example 2: Removing actionmailer gem
The actionmailer gem provides mail send feature. (actionmailbox gem for mail reception).
If you search the source code by the above mentiond regexp, like git grep --extended-regexp --ignore-case "action.?mailbox", the following files might hit.
- app/
- mailers/
- application_mailer.rb
- views/
- layouts/
- mailer.html.erb
- mailer.txt.erb
- config/
- environments/
- development.rb
- development.rb
Remove the relevant lines or files gor actionmailer. Then run tests and confirm there are no breakage.
Gems likely to be removed or not
- Likely to be removed. Your Rails app may not use some of those
- actioncable
- actionmailbox
- actionmailer
- actiontext
- activejob
- activestorage
- Less
likely. These are considred "core" of Rails and not likely to be
removed. You may delete those from Gemfile, but those will remain in
Gemfile.lock since some gems depend on those.
- actionpack
- actionview
- activerecord
- activemodel
- activesupport
- railties
Takeway
- rails gem is an aggregate of 12 gems, as of v7.0.4
- If "rails" gem in Gemfile is replaced with the minimum number of required gems, you can skip installing unused gems.
- In some cases, your bundle size can cut 10MB or more. And meaningless vulnerability alerts can be reduced.