Since when are half the files in the Rails root folder for JavaScript?

The amount of files in a Rails project root folder are getting out of hand, and the JavaScript ecosystem is certainly one cause to that. Let’s compare a project of mine from 2013 with one of today:

Files in 2013:

  • .gitignore
  • .ruby-version
  • Dockerfile
  • Gemfile
  • Gemfile.lock
  • Procfile
  • README.md
  • Rakefile
  • config.ru

Files in 2020

  • .browserslistrc
  • .byebug_history
  • .eslintrc.js
  • .gitignore
  • .npmrc
  • .nvmrc
  • .rspec
  • .rubocop.yml
  • .ruby-version
  • .slim-lint.yml
  • Gemfile
  • Gemfile.lock
  • Procfile
  • README.md
  • Rakefile
  • babel.config.js
  • config.ru
  • package.json
  • postcss.config.js
  • yarn-error.log
  • yarn.lock

And I don’t even use Docker in the 2020 project.

The way I see it, files in the Rails root folder should be scarce because they mean overhead for newcomers (and me as well). Folders are OK for me I guess. JavaScript doesn’t feel like a first class citizen in our Rails applications but more like a compulsive hoarder.

4 Likes

Interesting! I think I agree with you, but I’m having a bit of a hard time thinking of a productive resolution here. I see the root cause as Rails packaging more tools, and I don’t think it’s a bad thing for tools to default to looking in the project root for config.

I think there might be potential in figuring out how to move most of this stuff into config, but my concern there is that existing tutorials will point people to creating things in the root directory. So when that doesn’t work we’re creating a confusing newbie experience of another sort.

Maybe I’m not being creative enough with my solutions, though.

2 Likes

For some history here, at one point we tried adding binstubs for Yarn et al. and moving their config into the config/ directory. But this setup was fiddly and brittle—for example, if you didn’t have ./bin in your $PATH, you’d have to remember to call bin/yarn instead of just yarn, or you’d get errors. So we acquiesced to third-party defaults.

7 Likes

The other pain point was that upstream Yarn, Babel, etc. documentation tend to assume that their config is in the project root, which confused a lot of people.

1 Like

The beauty of Rails has always been convention over configuration. If I wanted to accept the default choices of the Rails maintainers, ideally there would be no extra files in the root directory.

As it stands, I have to figure out which (non-Ruby) tools the files are for, what those tools do, and whether I should adjust the configuration. But that’s only the start of the problem, I also have to familiarise myself with them across their entire lifecycle. Is this .json config file now supposed to be .js? Is it superseded by another tool entirely? Does the bootstrapped configuration need to be updated to stay current with new versions of Rails? What needs to change to go from Sprockets to Webpacker? What about npm to yarn? Yarn 1 to Yarn 2?

Arguably this is unavoidable if you want to use “contemporary” JS. But again, going back to Rails’ core premise: I am happy to accept the defaults and relieve myself of that configuration and maintenance burden. If I want to make changes, then I can start adding configuration files to effect that.

5 Likes

Was there consideration of moving all the JS tooling into a subfolder / subproject? I’m not sure the ergonomics would be better or preferable, but moving all of the files including the package.json file into the javascript folder might be interesting

1 Like

ESLint configuration can be moved inside package.json. This is supported out-of-the-box by ESLint. That would be one less file. Hope that helps.

1 Like

Or config/javascript/.

1 Like

Most of the JS tooling does better in a parent folder from the code - so having something like

app/
  javascript/
    packs/
      ...
    channels/
      ...
    package.json
    babel.config.js

would require less custom tooling workarounds from the Rails side. Again though, not sure if the ergonomics would be preferable though!

2 Likes

That’s great! Perhaps we can find a way to do move these files by looking at each of them individually?

Perhaps we can start by looking at the actual list of files that come from a fresh 6.0 rails new:

  • Not configuration files:

    • README.md
  • Configuration files that should probably best be kept at the root because a lot of tools depend on them being there:

    • Gemfile
    • Gemfile.lock
    • package.json
    • yarn.lock
    • config.ru
  • Files that could benefit from being moved to config/ (or removed):

    • babel.config.js
    • postcss.config.js
    • Rakefile => I think it would make sense to move this one too since the best practice is to add tasks inside lib/tasks and NOT inside this file.
1 Like

I was wondering about the choice of Yarn. I have been using NPM for my package management in another Javascript project and I fail to see the added-value of Yarn.

(I am in no way an advanced user of Javascript so I may not have triggered any advanced usage yet.)

3 Likes

I believe the split between NPM and Yarn started when NPM had less features than Yarn (one of the reasons why Yarn was developed in the first place). NPM before version 5 didn’t have a lockfile, which was a huge issue for repeatability.

It might make less sense now, I don’t have a strong opinion either way.

I’m sure there’s something else I don’t know :smiley:

3 Likes