File locations Javascript vs Stylesheet in Rails 7 - ruby-on-rails

In a new default Rails 7 application using the import maps functionality, Javascript is stored in app/javascript, while CSS is located in app/assets/stylesheets. Not only are they located at different hierarchy levels, but javascript is singular, while stylesheets is plural.
I'm looking for sources that explain these divergent locations and pluralization decisions. Searches through Rails Guides and API documentation have turned up nothing, but support talk on the Rails repo suggests that docs are still being actively updated.
On the surface this seems really shortsighted, but I want to make sure I'm not missing something before I go messing with the defaults.

app/assets is used by sprockets. This is rails asset pipeline. Preprocessing, minification, compilation etc. app/assets/javascripts was a thing before javascript took over the world, and had to be given its own separate directory.
app/javascript was used by webpacker to avoid mixing it with sprockets processing. This is javascript pipeline that does what sprockets does, process, compile, minify etc. A way to bring javascript build tools into rails. Singular referring to "javascript" language not "javascripts" as in collection of js files (I guess).
Both of these directories can have css and js assets, just processed and compiled by completely different tools.
In rails 7, app/javascript is used by jsbundling-rails that comes with different js build tools, like, esbuild and webpack. After javascript is done its job, bundles go into app/assets/build where sprockets treats it as any old js or css file.
With importmaps there is really no processing but app/javascript is the logical place for it. To use importmaps, all the files in app/javascript have to be precompiled by sprockets for use in production:
// app/assets/config/manifest.js
//= ../../javascript .js
and app/javascript has to be in Rails.application.config.assets.paths:
config.assets.paths << Rails.root.join("app/javascript")
This is what importmap-rails does, among other things. In case you want to relocate anything back to app/assets.
Here is a short overview of who lives where:
app/
├─ assets/ # used by sprockets-rails, everything else hooks into it
│ ├─ build/ # compiled assets (jsbundling-rails, cssbundling-rails, tailwindcss-rails)
│ ├─ config/ # precompile `build/` if any of these three ^ are used
│ │ # or precompile `app/javascript/` if importmap-rails is used
│ ├─ stylesheets/ # used by cssbundling-rails, tailwindcss-rails
│ └─ javascripts/ # not used in rails 7, but any directory can be added to `assets/`,
│ # just add it to precompilation manifest as well https://stackoverflow.com/q/72305291/207090
└─ javascript/ # used by jsbundling-rails, importmap-rails and anything node related.
└─ controllers/ # used by stimulus-rails
Also, rails gems themselves use app/assets/javascripts to ship any js files.

Related

Trigger webpacker compile when file outside javascript folder changes

I've run into an issue with webpacker in my rails app during development. Webpacker should also compile when some of the related config files change, but doesn't since they aren't in the app/javascript folder.
Is there to have webpacker also watch additional files for changes?
More detailed:
I load my css through webpacker. For this I'm using TailwindCSS and postCSS. I tend to change the tailwind config file (located in the application root) quite a bit, to automatically generate additional utilities and/or variant.
However, when I change the tailwind config file it doesn't trigger webpacker to recompile on the next page load. It only recompiles when I change one of the files in the app/javascript folder - even if it is just adding an extra blank line. I would like to avoid having to manually trigger webpacker to recompile.
I have changed nothing to the Rails defaults for webpacker.
In config/webpacker.yml, you want to add files and directories to the resolved_paths section.
resolved_paths:
- app/assets
- tailwind.config.js
There’s more information in this article https://rossta.net/blog/why-does-rails-install-both-webpacker-and-sprockets.html

Ruby on rails files setup

I have some doubts about the folders on which I should put the public files.
We got at the root path a folder called public and some other folders in app (rails 5.0.1 for me), let me show you the ones which sound strange for me:
app/assets/ (images | javascripts | stylesheets)
app/views/pages
After reading multiple tutorials and existing public projects, I saw that some people put his web template in public (js, css and images included).
Yet, in my case, because of I have seen it few times too and found it logic, I have put my template in assets separating my js, sass (in my case) files, and images in the folders already created by the RoR generator.
Additionnal, it seems logic for me to put my files in assets because my main layout gonna take my template files in assets with the framework default API. The following line works for me and gonna load my app/assets/stylesheets/ app.css.scss file
<%= stylesheet_link_tag 'app', media: 'all', 'data-turbolinks-track': 'reload' %>
Hope someone could explain what's the better way, I'm beginner with Rails, thanks.
app/assets/
This is where you put custom assets (images, js/css scripts that you own and custom to your application)
vendor/assets/
This is for third party libraries that you use in your app (carousel js plugin, etc)
.
├── app
│   ├── assets (custom assets specific to your app) 
├── public (static-files like error pages, favicon, etc which does not change much)
├── vendor
│   └── assets (third party libraries that your app uses)
Precompiled Assets
Add all the paths to your assets (images, js/css files) used in your application in assets precomile path in config/initializers/assets.rb (application.css and application.js are included by default)
All the assets when precompiled with
bundle exec rails assets:precompile
This generates public/assets directory with all the assets configured in your precompile path as readily servable static assets which are then served to your application responses.

Wrapping a set of stylesheets and javascript in a Ruby Gem with post build step to drop into right place

We have a very complex library for styles and scripts that is maintained by a collaborative team. This code is a large set of less, javascript, font and image files that is built using grunt and a number of modules installed with NPM.
What I want to do is have a post operation step in a gem that does this build and then copies the resulting files to the appropriate places.
Is there a way for this to happen in the Gem installation process itself so that I am not dependent on having to run a rake task or something.
I am trying to be as unobtrusive as possible on the existing project since it is part of a large enterprise wide initiative and is used by many other projects that are not rails etc.
File structure is rather cumbersome and I can't re-arrange, at least without running the npm install and grunt task.
You don't need to copy files at all.
Once such assets gem installed from Gemfile, it's assets path is available in app's assets lookup path. So you can use it directly in application.css and application.js, as well as image files.
Suppose your gem 'foo' structure is like this
foo
-lib
--foo
-vendor
--assets
---javascripts
----foobar.js
Then in your application.js you can do this
//= require foobar
Same is true for application.css.
You can keep the js build logic in gem, and only put the built foobar.js under vendor, so in Rails you only need to require one file.

Assets and third parts libs in Rails 4

I'm using now third part libs, it's jquery plagins and there no gems for their. For instance, one from them has this structure:
-plugin
|- css
|- plugin.css
|- js
|-plugin.js
|-image1.jpg
|-image2.jpg
plugin.css file includes codes like this: background-image: url('../metro/add.png')
Where I must put it's plugin and how correct include it in the assets?
I would suggest to use the index file technique (look at 2.1.2) for dealing with asset-pipeline and plugins. Another option is to include your plugin directory in the asset pipeline , like this ( in your config/application.rb):
config.assets.paths << Rails.root.join("app", "plugin")
After that you should :
rename plugin's directories
css to stylesheets;
js to javascripts ;
create directory named images and place .jpg files there;

Why three assets directory generated in rails 3.1 and higher

Can anyone explain what the use of the following directories is?
app/assets/
lib/assets/
vendor/assets/
These directories are all a part of Rails' Asset Pipeline.
Conceptually, the app/assets directory is for your application assets (for instance, the stylesheets and images for your application). lib/assets is for all of the code that you've written that stands alone from your rails app (javascript library, maybe). vendor/assets is meant to house all third party libraries (e.g. jQuery).
All of these paths are included by default in the asset pipeline. This means that their contents can be included into other files using sprockets, concatenating automatically into one file (javascript or css), reducing the number of requests and thus the loading time. The asset pipeline can also compile your coffeescript and minify your javascript for production.

Resources