Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When running assets:precompile, Propshaft includes individual digested files for all CSS / JS instead of only bundles #227

Open
nickjj opened this issue Dec 27, 2024 · 4 comments

Comments

@nickjj
Copy link

nickjj commented Dec 27, 2024

Hello,

I'm using Rails 8 with Propshaft v1.1.0 along with jsbundling and cssbundling where esbuild is doing the bundling.

After running assets:precompile in production mode the following files are created in public/:

image

The concern here is all of the JS and CSS files. When I was using Sprockets, only the application-xxx.js and application-xxx.css files were created but with Propshaft it's generating digested files for everything.

Based on the Propshaft documentation I thought maybe since bundling is happening with esbuild I could set:

Rails.application.config.assets.excluded_paths << ["app/assets/stylesheets", "app/javascript"]

But this resulted in the same outcome where the excess JS and CSS files were created.

What am I doing wrong?

Edit: this is happening with Sprockets too

Here's the same project but using Sprockets:

image

Is this possibly a Rails 8 change and has nothing to do with Propshaft? Unless I'm crazy (which is very possible), I don't recall all of these files being created in the past by Sprockets. Do we know why they're being created?

@midnight-wonderer
Copy link

I spotted three question marks, I could only help with some.

The digest is intended to be used with Cache-Control: immutable. I hope you already know this, I just provided the answer as feedback to your question.

Assuming that the inverse of this statement is what you want:

Propshaft includes individual digested files for all CSS / JS instead of only bundles

Have you read bypassing the digest step yet?
It is basically Propshaft's interface for working with other build tools (esbuild included); can it solve your problem?
Why or why not?

@theodorton
Copy link
Collaborator

theodorton commented Jan 7, 2025

The reason your excluded_paths config doesn't work is because you're not setting absolute paths. You'll need to use Rails.root.join. From the README:

You can however exempt directories that have been added through the config.assets.excluded_paths. This is useful if you're for example using app/assets/stylesheets exclusively as a set of inputs to a compiler like Dart Sass for Rails, and you don't want these input files to be part of the load path. (Remember you need to add full paths, like Rails.root.join("app/assets/stylesheets")).

@nickjj
Copy link
Author

nickjj commented Jan 8, 2025

The reason your excluded_paths config doesn't work is because you're not setting absolute paths.

Thanks, I missed that but I set that and it's still digesting everything in stylesheets and javascript dependencies.

For example it still produced this output:

image

The project I'm using doesn't even use Trix so I don't know where that's coming from, but that's a separate issue.

That output was with config.assets.excluded_paths += [Rails.root.join("app/assets/stylesheets"), Rails.root.join("app/javascript")].

The result I'm looking to get is:

  • I have all of my assets in the default CSS and JS locations with Rails using Tailwind and vanilla JS
    • This is working
  • I am using esbuild to bundle that
    • This is working
  • I want Propshaft to only produce application-abc123.js and application-abc123.css digests based on the bundles esbuild created instead of producing a bunch of individually digested CSS / JS files
    • This is not working
  • I still want Propshaft to perform digest replacements in CSS / JS assets (such as url and RAILS_ASSET_URL("..."))
    • This is not working

You can reproduce this in my Rails starter app project at: https://github.com/nickjj/docker-rails-example

To run it in production mode you'd modify the .env file and set these:

export COMPOSE_PROFILES=postgres,redis,web,worker,cable
export RAILS_ENV=production
export NODE_ENV=production
export DOCKER_WEB_VOLUME=./public:/app/public

Then docker compose up --build and check the public/ directory.

You can run ./run clean to clean out those assets and other temp files in between tests.

@theodorton
Copy link
Collaborator

The project I'm using doesn't even use Trix so I don't know where that's coming from, but that's a separate issue.

Most likely happening because you're loading actiontext (as part of rails/all). You can pick individual libraries to avoid this.

I want Propshaft to only produce application-abc123.js and application-abc123.css digests based on the bundles esbuild created instead of producing a bunch of individually digested CSS / JS files

The rationale for including all assets when precompiling is to support modern nobuild techniques that don't require you to use CSS and JS bundlers. This is one of the biggest changes from sprockets and I doubt it will change in the short term.

You can run bin/rails assets:reveal:full to get a full list of assets found in propshafts load path. For anything sourced from a gem you have three options:

  1. Comment out the require statement in application.rb to skip it (if it's part of Rails)
  2. Remove the gem
  3. Ignore the path

I still want Propshaft to perform digest replacements in CSS / JS assets (such as url and RAILS_ASSET_URL("..."))

This most likely happens because app/javascripts has been taken out of the load path. Propshaft must have access to dependencies in order to compute their digests as the files referring to them will get a digest that includes its dependencies. I'm not sure how well that works for already digested/built assets.

If you don't exclude app/javascripts and it's still not working, I would suggest that issue is reported separately.


Your main concern in this issue (that all files are included) is the expected behaviour at the moment, and there's an existing issue in #89.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants