rails / propshaft Goto Github PK
View Code? Open in Web Editor NEWDeliver assets for Rails
License: MIT License
Deliver assets for Rails
License: MIT License
Hi,
I wish to use https://github.com/lipis/flag-icons in my app. In my main .scss file I'm doing @import "flag-icons/sass/flag-icons";
but the flag images are not outputting.
From looking at the library, the file paths are being output like so:
@mixin flag-icon($country) {
.fi-#{$country} {
background-image: url(#{$flag-icons-path}#{$flag-icons-rect-path}/#{$country}.svg);
@if $flag-icons-use-square {
&.fis {
background-image: url(#{$flag-icons-path}#{$flag-icons-square-path}/#{$country}.svg);
}
}
}
}
Which results in compiled code of:
.fi-de {
background-image: url(../flags/4x3/de.svg);
}
Any ideas why this is not working?
Thanks,
Neil
Hi, first of all, thanks a lot for developing this new solution. We are using it in production and are quite happy. One issue we bump into quite frequently though is in development.
We use webpack and depend on dynamic chunk loading. That means that webpack needs to compile these chunks already with a hash and a ".digested" suffix. We also use LiveReload from webpack to refresh the page after each compilation automatically.
What we observed is that when we apply multiple changes in succession, then a dynamic chunk request might return a 410. We debugged the code and could see that the asset wasn't in the @cached_assets_by_path
. We also saw that propshaft clears the cache when any of the files in app/assets/builds
changes. We suspect that there is some kind of race-condition between webpack and propshaft, clearing the cache, compiling multiple times and refreshing the browser at the same time.
We also noted that the digested assets created by webpack accumulate over time which could also slow down the creations of cached_assets_by_path
. This accumulation happens also in production and doesn't get cleared by assets:clear
.
We tried to find a reproducible example but since it is likely a race condition it is very hard. We would appreciate any thoughts and pointers.
Hi All,
I've replaced Sprockets with Propshaft + Import Map combination and it worked great. However, there is one thing that is not working - when I change JS file, I need to run assets:precompile
(and restart server) to see changes in dev
environment.
I verified that on new Rails 7 project (created like this rails new myapp -a propshaft
) and it's the same situation.
Is there a way to configure propshaft
+ importmap-rails
to automatically handle this?
I'm testing an app with
and I'm getting
| Started GET "/assets/application-65a777c93a558c83762b4590df80548504aea999.css" for ::1 at 2021-11-04 14:44:49 -0300
|
| NoMethodError (undefined method `digested_path' for nil:NilClass):
|
| propshaft (0.2.0) lib/propshaft/compilers/css_asset_urls.rb:28:in `asset_url'
Is this supposed to work? Am I missing something? Any incompabilities?
#100 3903815 breaks chunking with esbuild when implemented as suggested here: #48
The reason is likely do the the fact that esbuild creates static chunks that do not have names, i.e. chunk-123, chunk-456, etc.
This is discussed here: evanw/esbuild#1716
Ever since #71 or its fix in #72 the order of paths gets scrambled and that messes up tailwind for me.
I don't do any config.assets
modification at all so this should all be default. I have the latest version of all the other gems.
Propshaft::LoadPath#initialize
propshaft 0.6.1 logic:
[4] pry(#<Propshaft::LoadPath>)> Array(paths).collect { |path| Pathname.new(path) }
=> [#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/assets/builds>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/assets/images>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/assets/stylesheets>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/turbo-rails-1.0.1/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/tailwindcss-rails-2.0.6-arm64-darwin/app/assets/fonts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/tailwindcss-rails-2.0.6-arm64-darwin/app/assets/stylesheets>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/stimulus-rails-1.0.3/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/importmap-rails-1.0.3/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actiontext-7.0.2.2/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actiontext-7.0.2.2/app/assets/stylesheets>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actioncable-7.0.2.2/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/activestorage-7.0.2.2/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actionview-7.0.2.2/lib/assets/compiled>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/javascript>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/vendor/javascript>]
propshaft 0.6.3 logic:
[5] pry(#<Propshaft::LoadPath>)> dedup(paths)
=> [#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actioncable-7.0.2.2/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actiontext-7.0.2.2/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actiontext-7.0.2.2/app/assets/stylesheets>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/actionview-7.0.2.2/lib/assets/compiled>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/activestorage-7.0.2.2/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/importmap-rails-1.0.3/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/stimulus-rails-1.0.3/app/assets/javascripts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/tailwindcss-rails-2.0.6-arm64-darwin/app/assets/fonts>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/tailwindcss-rails-2.0.6-arm64-darwin/app/assets/stylesheets>,
#<Pathname:/Users/miharekar/.gem/ruby/3.1.1/gems/turbo-rails-1.0.1/app/assets/javascripts>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/assets/builds>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/assets/images>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/assets/stylesheets>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/app/javascript>,
#<Pathname:/Users/miharekar/Development/Personal/decent-visualizer/vendor/javascript>]
Before | After |
---|---|
So in the new version the tailwind compilation doesn't seem to work but I don't know enough about it to dive deeper.
Doing @paths = dedup(paths).sort.reverse
fixes it, so this is definitely the issue, but that's not a proper fix ๐
I think the dedup method should respect the order of paths passed in.
Context:
Using Propshaft, cssbundling-rails, jsbundling-rails, esbuild
I'm using a npm plugin that has a css like this:
// node_modules/the_module/build/css/styles.css
.some-div {
background: url('../img/icon.png')
}
the background refers to
node_modules/the_module/build/img/icon.png
In my application.scss I have
@import 'the_module/build/css/styles';
The css file gets included in my precompiled application.css but it tries to find an image in localhost:3000/img/icon.png which of course does not exist.
How can I make that image available under assets?
recently stumbled into this project while attempting a rails 7 update. I am using the predigested ".digested" method because my js files need to reference themselves, and am having 2 issues with the source maps.
sourceMappingURL
is being striped away:
(quick and dirty solution in dev mode is to call config.assets.compilers.pop
to remove Propshaft::Compilers::SourceMappingUrls
)extract_path_and_digest
- firien/propshaft@3903815...ed67507Hi there.
While migrating to this awesome gem to handle the asset pipeline, I found that it logs every digested asset with this line: "Writing #{asset.digested_path}" from lib/propshaft/processor.rb
in line 43.
My question is: Is there a way to avoid logging? I'm using Capistrano for deploy, if that is worth mentioning.
Thank you very much in advance.
If the asset_host config is set, the URLs generated by Propshaft within CSS files do not contain the asset host, and instead are always relative. Perhaps this is intentional, but I can't find documentation or discussion of that.
I'm playing around with Propshaft for couple of days now and I love it. I just want to be sure the way I'm using it is aligned with vision for Propshaft.
Let say I need to load several vendor CSS files and several custom CSS files. I find it that the best way for me is to add multiple stylesheet_link_tag
:
// app/views/layouts/application.css
<head>
<%= stylesheet_link_tag "simplebar.min.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "leaflet.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "tiny-slider.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "nouislider.min.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "theme.min.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "trix", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "actiontext", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "rails_bootstrap_forms", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "my_other_custom.css", "data-turbo-track": "reload" %>
</head>
Is this considered ok/best-practice? Or would you suggest something else?
note I find it to import files from css with
import url('/some-other.css')
possible but problematic (more info here).
Hypothetically if my project ends up with 50 vendor CSS files and 17 css files. Is it ok to load all 67 at once in application layout (as described in Question1) or is it better to load them in different contexts. e.g.:
// app/views/layouts/application.css
<head>
<!-- some core CSS -->
<%= yield :head %>
<%= stylesheet_link_tag "theme.min.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "rails_bootstrap_forms", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
</head>
...
//app/views/posts/_form
....
<% content_for :head do %>
<%= stylesheet_link_tag "trix", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "actiontext", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "my_other_custom.css", "data-turbo-track": "reload" %>
<% end %>
Although the second option makes theoretically more sense, especially for custom app css (no need to load marketing CSS everywhere), but when it comes to vendor CSS files is it worth the trouble ?
If I understand correctly all the CSS is cached in the browser = so it should not be a big deal. Any opinion on this ?
which one you think is better for best practice:
Option A - Lot of smaller app files example :
// app/views/layouts/application.css
<head>
...
<%= stylesheet_link_tag "frontpage.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "posts.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "publishing.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "comments.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "author.css", "data-turbo-track": "reload" %>
</head>
Option B - try to group them to one bigger CSS file:
// app/views/layouts/application.css
<head>
...
<%= stylesheet_link_tag "frontpage.css", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "blog.css", "data-turbo-track": "reload" %>
</head>
yes ideally I should use importmaps to load my JS
BUT let say I'm working with one of bootstrap-themes (e.g.: Front). Once I download the theme I got bunch of vendor javascript files that I can just move to vendor/assets/javascript/
and load with javascript_include_tag
<body>
...
<%= javascript_include_tag 'theme.min.js', defer: true %>
<%= javascript_include_tag "tom-select.complete.min.js", defer: true %>
....
<body>
I find it really convenient and not colliding with my importmaps JS (Stimulus, Turbo, all works nice)
Is this considered OK ?
Thank you for your input
P.S. sorry I'm posting this question here, I tried to ask this on discuss.rubyonrails.org but spam filter marked my post as spam ๐
Hi, we have a couple of assets that we don't want propshaft to digest and therefore we add the predigested
suffix to its file name. This worked until the new version 0.7.0. This pull request introduced changes that broke this feature. It doesn't add new assets with the digested
suffix the load_path
(only the first found asset).
The problem is that in this line asset.logical_path
is always filename.js
and not filename-xyz.digested.js
. This is because in this line it removes the predigested part from the logical path.
I was using Sprockets and decided to check Propshaft out since I don't use any of the unique features of Sprockets. I have a copy of all of the Font Awesome SVGs in app/assets/svgs
.
With Sprockets a request in development is instantaneous, whereas with Propshaft every request takes a second or more.
When I removed most of the icons from the asset directory Rails+Propshaft became fast.
I have a multi-tenant app that dynamically sets a CDN for each domain hosted. I use a proc in the config like this:
config.asset_host = -> (asset, request) { "https://cdn.#{request.domain}" }
This way domain1.com, domain2.com, domain3.com all have their own CDN at cdn.domain1.com, cdn.domain2.com, cdn.domain3.com... etc. All derived from the request. The stylesheet tags all look like:
<link rel="stylesheet" href="https://cdn.example1.com/assets/fonts-cdf664222a5fa20e6165a5732e3560a3bedbcc8d.css">
<link rel="stylesheet" href="https://cdn.example2.com/assets/fonts-cdf664222a5fa20e6165a5732e3560a3bedbcc8d.css">
<link rel="stylesheet" href="https://cdn.example3.com/assets/fonts-cdf664222a5fa20e6165a5732e3560a3bedbcc8d.css">
With propshaft 0.7.0 the asset urls inside the css don't resolve correctly probably because propshaft isn't expecting a proc in the config, just a string.
With 0.7.0 the asset url generated looks like:
@font-face {
src: url("#<Proc:0x00007f19f925a480 /app/project/releases/20230305134308/config/environments/production.rb:42 (lambda)>/assets/fonts/some-font-90c75952b33cc3eacf616e676327865cdb140281.woff2") format("woff2");
}
With previous versions of propshaft the asset url generated looks like:
@font-face {
src: url("/assets/fonts/some-font-90c75952b33cc3eacf616e676327865cdb140281.woff2") format("woff2");
}
Maybe there is a better way for a multi tenant app to set various CDNs than setting the asset_host with a proc. ๐คทโโ๏ธ
I'm trying to bundle add solidus && rails generate solidus:install
but it carries with it Sprockets which will automatically replace my app's Propshaft so that everything gets messed up. Is there a way to force blockage of Sprockets somehow?
I'm struggling to display svg images inline.
rails (7.0.4)
propshaft (0.6.4)
cssbundling-rails (1.1.1)
jsbundling-rails (1.0.3)
Using webpack, propshaft.
The method proposed in the migration guide is not resulting in the SVG rendering.
Rails.application.assets.load_path.find('logo.svg').content
For example:
<div class="shape shape-bottom shape-fluid-x svg-shim text-gray-200">
<%= Rails.application.assets.load_path.find('shapes/curves/curve-1.svg').content %>
</div>
results in:
<div class="shape shape-bottom shape-fluid-x svg-shim text-gray-200">
<svg viewBox="0 0 2880 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 48h2880V0h-720C1442.5 52 720 0 720 0H0v48z"/></svg>
</div>
Creating the image using the path outputs the SVG as expected.
<%= image_tag image_url('shapes/curves/curve-1.svg') %>
And putting the SVG directly into the template works.
<div class="shape shape-bottom shape-fluid-x svg-shim">
<svg viewBox="0 0 2880 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 48h2880V0h-720C1442.5 52 720 0 720 0H0v48z" fill="currentColor"/></svg>
</div>
In sprockets if you place assets/javascript/client/pay.html.erb
and assets/javascript/client/pay.js.erb
both will be compiled and placed in assets folder as client/pay.html
and client/pay.js
. Is there a way to replicate this behaviour in propshaft?
Upgrading from propshaft v0.4.1 to v0.4.2 introduced this error on application initialization:
undefined local variable or method `paths' for #<Propshaft::Railtie:0x00005cd9e1dc97c8> (NameError)
from this line:
propshaft/lib/propshaft/railtie.rb
Line 39 in b47f43b
$ bundle exec rails c
Traceback (most recent call last):
37: from bin/rails:4:in `<main>'
36: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
35: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
34: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/loaded_features_index.rb:100:in `register'
33: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
32: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
31: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/commands.rb:18:in `<main>'
30: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/command.rb:48:in `invoke'
29: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/command/base.rb:87:in `perform'
28: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
27: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
26: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
25: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/commands/console/console_command.rb:101:in `perform'
24: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/command/actions.rb:15:in `require_application_and_environment!'
23: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/command/actions.rb:28:in `require_environment!'
22: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/application.rb:345:in `require_environment!'
21: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/zeitwerk-2.5.1/lib/zeitwerk/kernel.rb:35:in `require'
20: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
19: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
18: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/loaded_features_index.rb:100:in `register'
17: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
16: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/bootsnap-1.9.3/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
15: from /home/richard/playground/rails-propshaft-example/config/environment.rb:5:in `<main>'
14: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/application.rb:369:in `initialize!'
13: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/initializable.rb:60:in `run_initializers'
12: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:205:in `tsort_each'
11: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:226:in `tsort_each'
10: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:347:in `each_strongly_connected_component'
9: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:347:in `call'
8: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:347:in `each'
7: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:349:in `block in each_strongly_connected_component'
6: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:431:in `each_strongly_connected_component_from'
5: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
4: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/2.7.0/tsort.rb:228:in `block in tsort_each'
3: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/initializable.rb:61:in `block in run_initializers'
2: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/initializable.rb:32:in `run'
1: from /home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/bundler/gems/rails-14f190f33710/railties/lib/rails/initializable.rb:32:in `instance_exec'
/home/richard/.asdf/installs/ruby/2.7.2/lib/ruby/gems/2.7.0/gems/propshaft-0.4.2/lib/propshaft/railtie.rb:39:in `block in <class:Railtie>': undefined local variable or method `paths' for #<Propshaft::Railtie:0x00005cd9e1dc97c8> (NameError)
Did you mean? Pathname
I added a test app for integration testing in #20, and it's producing the same error after rebasing:
https://github.com/rails/propshaft/runs/4414708235?check_suite_focus=true#step:4:4
66ce0f8 seems to be the commit that broke this. If I revert that commit, the integration test passes:
https://github.com/rmacklin/propshaft/runs/4414863639?check_suite_focus=true#step:4:10
This is more of a "polish" kind of issue, but bin/rails routes
inspects Propshaft::Server
when it prints out the /assets
entry:
If Propshaft::Server
is a singleton, perhaps the output should just be Propshaft::Server
, which would look like this:
Prefix Verb URI Pattern Controller#Action
/assets Propshaft::Server
widgets GET /widgets(.:format) widgets#index
I'd be happy to submit a PR, but I'm not sure whether implementing #inspect
on Propshaft::Server
is an ideal solution in this case, since #inspect
is useful in many other scenarios besides the Rails route inspector.
Here is the relevant code in the route inspector: #37
Side note: Engines/Railties don't appear to have this problem, since the route inspector ends up calling inspect
on the classes, rather than instances.
Hi,
I am using dartsass-rails gem, it add a task before asset:precompile run, that task output a unique file application.css (for the simpliest case) in assets/builds.
Should not propshaft had only this files and copy it in public/assets folder ?
Hello!
I created a sample Rails 7 RC1 application with Propshaft and I wanted to use Bootstrap Icons from NPM package.
As you can see in the README of my sample app, I had to play a few tricks to make them work because the fonts import didn't work out-of-the-box.
I wanted some advice from multiple developers if there was a potential issue with Propshaft not handling the default font path correctly in bootstrap-icons
and if there's not, if my workaround is good. I tried a few things and I don't know if it is the smartest solution.
This discussion may lead to write some documentation for best practices around Propshaft.
Thanks in advance for your help!
I want to exclude all assets I am not using from precompiling.
I understand that config.assets.excluded_paths
exists and that it requires a full path.
In my case Rails.application.config.assets.paths
returns
["/usr/src/app/app/assets/builds",
"/usr/src/app/app/assets/images",
"/usr/local/bundle/gems/view_component-2.53.0/app/assets/vendor",
"/usr/local/bundle/gems/unobtrusive_flash-3.3.1/lib/assets/javascripts",
"/usr/local/bundle/gems/unobtrusive_flash-3.3.1/lib/assets/stylesheets",
"/usr/local/bundle/gems/turbo-rails-1.0.1/app/assets/javascripts",
"/usr/local/bundle/gems/nested_form-0.3.2/vendor/assets/javascripts",
"/usr/local/bundle/gems/heroicon-0.4.0/app/assets/images",
"/usr/local/bundle/gems/actioncable-7.0.2.3/app/assets/javascripts",
"/usr/local/bundle/gems/actionview-7.0.2.3/lib/assets/compiled"]
I would like to exclude most of them, e.g. "/usr/local/bundle/gems/nested_form-0.3.2/vendor/assets/javascripts"
or "/usr/local/bundle/gems/actionview-7.0.2.3/lib/assets/compiled"
.
I have two reasons for this: It takes comparatively long (e.g. assets from heroicon
), I don't like to waste space (I know, it is not too much) and I like to have a clean directory with only the files I really use.
This is the only way I found to do so:
Rails.application.config.assets.excluded_paths << File.join(Heroicon.root, 'app/assets/images')
# rubocop:disable Style/StringConcatenation
Rails.application.config.assets.excluded_paths << (Pathname.new(Gem.find_files_from_load_path('nested_form').first) + '../../vendor/assets/javascripts')
Rails.application.config.assets.excluded_paths << (Pathname.new(Gem.find_files_from_load_path('turbo-rails').first) + '../../app/assets/javascripts')
Rails.application.config.assets.excluded_paths << (Pathname.new(Gem.find_files_from_load_path('unobtrusive_flash').first) + '../../lib/assets/stylesheets')
Rails.application.config.assets.excluded_paths << (Pathname.new(Gem.find_files_from_load_path('unobtrusive_flash').first) + '../../lib/assets/javascripts')
Rails.application.config.assets.excluded_paths << (Pathname.new(Gem.find_files_from_load_path('view_component').first) + '../../app/assets/vendor')
# rubocop:enable Style/StringConcatenation
Note: I am unable to use this methodology to exclude actionview
or actioncable
.
Pathname.new(Gem.find_files_from_load_path('whaever').first)
does not look like a good solution
What is the recommended way?
How can this be simplified?
I've been trying out the new asset pipeline today:
It's so fast compared to webpack :)
However I can't figure out how to refer to a font asset in a stylesheet.
Here's the directory structure:
app/assets/
โโโ builds/
โย ย โโโ application.css
โโโ config/
โโโ fonts/
โย ย โโโ susa-regular.woff2
โโโ images/
โโโ stylesheets/
โโโ application.bulma.sass
โโโ fonts.sass
And here are the test stylesheets:
// app/assets/stylesheets/application.bulma.sass
@import 'fonts'
// app/assets/stylesheets/fonts.sass
@font-face
font-family: 'SusaRegular'
src: url('../fonts/susa-regular.woff2') format('woff2')
.logotype
font-family: 'SusaRegular', serif
<!-- html snippet ->
<p class="logotype">hello</p>
The application.css
which is built by propshaft and/or cssbundling repeats the font-face's src declaration verbatim. I had hoped it would replace it with a path to a digested copy of the font file.
So, unsurprisingly, when I load a page in the browser, there's a 404 for GET http://0.0.0.0:3000/fonts/susa-regular.woff2
.
I checked Rails.application.config.assets.paths
in the Rails console; it includes my app/assets/fonts/
directory.
I tried using asset-path(...)
instead of url(...)
, but it didn't work (though I didn't expect to as I think it's obsolete?).
Any tips would be much appreciated. Thank you!
Is there a way to configure propshaft with Stimulus controllers in the ViewComponents (https://viewcomponent.org/) components folder instead of the javascript folder? I try the assets pipline aproach (ViewComponent/view_component#1064) but didn't work.
app/views/layouts/application.html.erb:
Google Chrome console / networks tab
Scenarios:
Gemfile: Propshaft uncommented, sprockets-rails commented
ESBUILD_MODULES=1 ./bin/dev
Output: ๐ด
Gemfile: Propshaft commented, sprockets-rails uncommented
ESBUILD_MODULES=1 ./bin/dev
Output: ๐ข
Gemfile: Propshaft commented, sprockets-rails uncommented
./bin/dev
Output: ๐ข
Gemfile: Propshaft uncommented, sprockets-rails commented
./bin/dev
Output: ๐ข
Minimalist application to reproduce the issue: https://github.com/navidemad/PropshaftApp
With sprockets you were able to change the prefix in application.rb
to something like config.assets.prefix = "/assetz" so you're able to use asset
as a model/routes etc is there a need for this using propshaft? if so how would you go about changing this?
As per the Rails docs, if one is using sprockets-rails >= 3.2.0 it's possible to set config.assets.unknown_asset_fallback = false
and raise an error when an asset is not found. Looking at the current implementation of asset_url
we get a warning if propshaft is unable to resolve an asset URL. Would it be possible to have a similar configuration that would allow raising an error instead (especially on assets:precompile
)?
Houston we have a problem). Hi guys, I have trouble with using many CSS files in the folder app/assets/stylesheets
, like when I add a file like buttons.css
and load it to the application.css
by @import url('buttons.css');
that is done, but.. when I make changes inside file buttons.css
- no changes on-site, I mean that changes, not tracks or maybe I do something wrong. Can you help me please with it?
I switched from sprockets
to propshaft
assets compiler in my project. To make that switch, I followed the instructions from this document by Propshaft.
When using sprockets
, I had to run rails assets:precompile
every time I made any changes to a css
, js
, file or add a new image in the assets
folder. To overcome this in Propshaft I followed the instructions in the documentation which says:
Propshaft uses a dynamic assets resolver in development mode. However, when you run assets:precompile locally Propshaft will then switch to a static assets resolver. Therefore, changes to assets will not be observed anymore and you will have to precompile the assets each time changes are made. This is different to Sprockets.
If you wish to have dynamic assets resolver enabled again, you need to clean your target folder (usually public/assets) and propshaft will start serving dynamic content from the source.
So I deleted all the files in the public/assets
folder and re-initialized the rails server, but unfortunately, this didn't work & I do have to pre-compile assets in order to see the changes.
My application is running on rails 7.0.4
& ruby 3.1.2
and this is the command I gave to initialize the app:
rails new --skip-test -d=postgresql -j esbuild --css bootstrap fmb
So been using esbuild & bootstrap for JS & CSS respectively with sprockets
as a assets compiler & to transition to propshaft
, I:
sprockets
with propshaft
gem.bundle install
.config.assets.paths << Rails.root.join('app','assets');
in the config/application.rb
file so no changes there.manifest.js
file.image_url
or font-url
in my project so no changes there.Could you let me know if I missed any steps here as everything does work perfectly except for the precompilation part? It's really annoying to compile the assets every time I make any changes to the assets files and re-initialize the server to see those changes.
recent versions of bootstrap icons add a hash parameter in the resource reference, e.g. ./fonts/bootstrap-icons.woff2?8d200481aa7f02a2d63a331fc782cfaf
because of the extra query param (which should not really matter) propshaft seems unable to match it with the actual file even though assets:reveal shows it finds the linked file.
propshaft should probably remove query parameters from local urls before matching it with the exposed assets it's serving for doing it's digest rewriting
(EDITED) this issue seems difficult to reproduce. at first propshaft was not digesting correctly. and when we removed the query parameter, propshaft started doing the digesting correctly. however, once we added the query param (hash) again to the font url, propshaft kept doing the digesting correctly. we're currently kind of seriously puzzled on this and what caused propshaft to not do the digesting correctly initially.
Hello,
I've migrated from sprockets to propshaft with cssbundling and jsbundling. While everything works fine in development mode it doesn't in production.
When running rake assets:reveal I see all required assets properly listed in the output and assets:precompile generates all required assets including digests in the public/assets folder. e.g: application-15fae71d9b66770b18316ce2e449486d37028831.css
etc. However; when opening up the production app the app is unable to locate the generated assets properly. I'm getting 404 responses in the browser.
Request URL: http://localhost:3000/assets/application-15fae71d9b66770b18316ce2e449486d37028831.css
Request Method: GET
Status Code: 404 Not Found
Remote Address: 127.0.0.1:3000
Referrer Policy: strict-origin-when-cross-origin
File digests seem to be correspond to the ones in manifest.json and the actual file names so that shouldn't be it.
Is there anything I'm missing?
If I understood correctly the idea of Portshaft (pls correct me if I'm wrong ) then the way how to include css files would be:
in app/assets/application.css
/* Application styles */
@import url('/bootstrap.css');
@import url('/my-custom.css');
in app/assets/bootstrap.css
I have the content of bootstrap.css
from Bootstrap 5 download page
in app/assets/my-custom.css
:
p {
color: red;
}
my app/views/layout/application.css
<!DOCTYPE html>
<html>
<head>
<title>Myapp</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>
<body>
<h1>Propshaft test</h1>
<div class="text-primary">
If this text is blue, Bootstrap5 css works via Portshaft
</div>
<p>If this text is in color then @include css custom file works</p>
</body>
</html>
So far so good, I run rails server and load the localhost:3000
you can see the <p>
is in red
Now I change the app/assets/my-custom.css
:
p {
color: yellow;
}
I save the file and reload my localhost:3000
As you can see the change that I want the collor of <p>
to be yellot was not picked up.
Restarting of rails server don't help, only thing that helps is if I rename the file e.g. from app/assets/my-custom.css
to app/assets/my-custom-xx.cssand alter the
app/assets/application.css`
/* Application styles */
@import url('/bootstrap.css');
@import url('/my-custom-xx.css');
now it the
is yellow
rails new myapp -a propshaft
rails assets:precompile
rails assets:reveal
bootstrap.css
application.css
my-custom-xx.css
my-custom.css
stimulus.min.js
stimulus.js
stimulus.min.js.map
stimulus-importmap-autoloader.js
stimulus-autoloader.js
stimulus-loading.js
turbo.min.js.map
turbo.js
turbo.min.js
es-module-shims.js.map
es-module-shims.js
es-module-shims.min.js
actiontext.js
trix.js
trix.css
action_cable.js
actioncable.esm.js
actioncable.js
activestorage.esm.js
activestorage.js
rails-ujs.js
application.js
controllers/hello_controller.js
controllers/index.js
controllers/application.js
I'll admin this is a bit pedantic, but since this project is so early, I'd like to make a case that assets are actually "compiled" before they're deployed.
"precompile" makes sense if a rails application was compiled, but since its interpreted, there's actually no compilation that happens.
Quite simply, assets are compiled before they are deployed along side a Rails application.
Similar to https://github.com/rails/sprockets-rails#sri-support
Currently adding integrity: true
passes the option as is
This seems like a great solution to cssbundling-rails#22 and a replacement for Sprockets. However it would be ideal to have the ability to just replace all url()
calls with the digested url even if it's behind a configuration flag.
The use cases for this are things like icon fonts, UI libraries, purchased themes all containing CSS that reference assets that come along with them such as images, font files etc.. A conscience effort has to be made (even with Sprockets) to go through and edit the supplied files to use the asset-path helpers. Having the ability to replace all url() calls would allow drop in updates to these types of assets just by dropping the files into folders within config.assets.paths
.
Happy to work on a PR if anyone else agrees this is desired.
When I reference an SVG sprite member in a stylesheet, it preserves the anchor pointing that member. To illustrate:
.icon.icon-rails { background-image: url('icons.svg#rails'); }
Should output
.icon.icon-rails { background-image: url('/assets/icons-abcdef123456.svg#rails'); }
The CssAssetCompiler
strips the anchor from the URL and results in no image being embedded:
.icon.icon-rails { background-image: url('icons.svg#rails'); }
Outputs:
.icon.icon-rails { background-image: url('/assets/icons-abcdef123456.svg'); }
I created a simple example of the issue here: https://github.com/flipsasser/propshaft-svg-sprite-example
Environment
7.0.2.3
ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [arm64-darwin21]
2.3.9
0.6.4
Problem
As far as I understand Propshaft has two ways to resolve assets: dynamically and statically. Dynamic is the preferred way for development and static the way for production as assets get precompiled to public/assets
.
Now, I recently deployed my project to Heroku and noticed that it crashes immediately as I visit the URL. Upon checking logs I noticed the following error message:
Propshaft::MissingAssetError in Home#index
The asset 'tailwind.css' was not found in the load path.
...
I double checked on Heroku and confirmed that the public/assets
folder was correctly created. I also took a look at the .manifest.json
and found no problems. I tried to reproduce the problem locally by running rails assets:precompile
and voilร : same error message and same behavior (i.e. public/assets
and .manifest.json
look fine).
I noticed that this problem isn't specific to tailwind.css
as stated in the error message - it seems to be any asset really. Oddly enough, upon rails assets:clobber
everything works fine again locally as Propshaft switches back to the dynamic resolver.
Please note, this is fairly fresh rails project (about a week old) and I have not changed the default config in development.rb
, production.rb
and application.rb
- yet I am unable to get the project to work properly after a rails assets:precompile
.
What am I missing?
(I've attached a full stack trace just in case)
stack_trace.log
Hi,
I've recently started a brand new Rails 7 application with Tailwind and no webpacker.
I can see that sprocket-rails
is in my Gemfile
. In the Gemfile.lock
there is no bundling gem and nothing regarding Webpack or Webpacker.
What should we do in a case like this?
Is using Propshaft instead of Sprockets even recommended?
Thanks for all the great work ๐
In migrating from Sprockets to a Propshaft + JavaScript Bundling and CSS Bundling for Rails set up, we have lost the generation of .gz
compressed versions of our JavaScript and CSS assets (see Sprockets' ZlibExporter
).
As these files would automatically be served by the ActionDispatch::Static
middleware (useful when serving Rails applications from Heroku), would adding similar functionality to Propshaft be welcome or is it out of scope for the project?
I'd imagine it would be an optional part of outputting the assets in the Processor, creating versions of each compressable asset with the same filename but with .gz
and .br
appended.
Hey there! I would like to share some bits of code that we implemented at our company and it could be merged into the official propshaft
gem. Right now there is no way to reference digested assets from webpack, rollup.js or any other build system. On the other side, propshaft
already does recognize digested assets with .digested.
pattern on the filename. The motivation for this feature is to be able to use preload_link_tag
or reference any kind of asset generated from external builders. No more talk, here is the code.
# lib/propshaft/digested.rb
module Propshaft
CACHE = {}
module Digested
refine Propshaft::LoadPath do
def resolve_digested(asset_name)
Propshaft.resolve_digested_from(asset_name, source: assets_by_path)
end
end
refine Propshaft::Resolver::Static do
def resolve_digested(asset_name)
Propshaft.resolve_digested_from(asset_name, source: parsed_manifest)
end
end
refine Propshaft::Resolver::Dynamic do
def resolve_digested(asset_name)
load_path.resolve_digested(asset_name)
end
end
end
def self.resolve_digested_from(asset_name, source:)
CACHE[asset_name] ||= source.find do |logical_path, _|
filename, extname = asset_name.split(".")
pattern = /\A#{filename}-([0-9a-zA-Z]{7,128})\.digested\.#{extname}\z/
pattern.match?(logical_path)
end&.first
end
end
# app/helpers/propshaft_helper.rb
module PropshaftHelper
using Propshaft::Digested
def digested_path(path)
Rails.application.assets.resolver.resolve_digested(path) || raise(Propshaft::MissingAssetError.new(path))
end
end
Let me know if this sounds good so I can start working on a pull request. :D
The docs say:
Precompilation in development
Propshaft uses a dynamic assets resolver in development mode. However, when you run assets:precompile locally Propshaft will then switch to a static assets resolver. Therefore, changes to assets will not be observed anymore and you will have to precompile the assets each time changes are made. This is different to Sprockets.
My question is:
How do I switch it back? It seems crazy that if you run rails assets:precompile
one time you're screwed... ๐
Following c669e39 I set the following in my app:
config.assets.excluded_paths << 'app/assets/stylesheets'
But this didn't actually exclude my stylesheets directory. Looking at the source I realised I needed instead:
config.assets.excluded_paths << "#{Rails.root}/app/assets/stylesheets"
As an alternative I patched the source to automatically add the prefix:
diff --git i/lib/propshaft/railtie.rb w/lib/propshaft/railtie.rb
index a8236c6..b164e50 100644
--- i/lib/propshaft/railtie.rb
+++ w/lib/propshaft/railtie.rb
@@ -24,7 +24,9 @@ class Railtie < ::Rails::Railtie
app.config.assets.paths.unshift(*paths["lib/assets"].existent_directories)
app.config.assets.paths.unshift(*paths["app/assets"].existent_directories)
- app.config.assets.paths = app.config.assets.paths.without(Array(app.config.assets.excluded_paths).collect(&:to_s))
+ app.config.assets.paths = app.config.assets.paths.without(
+ Array(app.config.assets.excluded_paths).collect { |p| paths.path.join(p) }.collect(&:to_s)
+ )
end
config.after_initialize do |app|
But then I realised this would exclude (in my case) app/assets/stylesheets
from any asset path, not just my top-level assets.
Just to make it a bit clearer, would you be interested in a small PR like the following?
diff --git i/README.md w/README.md
index e5844e2..f0dca2b 100644
--- i/README.md
+++ w/README.md
@@ -18,7 +18,7 @@ With Rails 7+, you can start a new application with propshaft using `rails new m
Propshaft makes all the assets from all the paths it's been configured with through `config.assets.paths` available for serving and will copy all of them into `public/assets` when precompiling. This is unlike Sprockets, which did not copy over assets that hadn't been explicitly included in one of the bundled assets.
-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.
+You can however exempt directories that have been added through the `config.assets.excluded_paths`. This is useful if you're for example using `#{Rails.root}/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.
These assets can be referenced through their logical path using the normal helpers like `asset_path`, `image_tag`, `javascript_include_tag`, and all the other asset helper tags. These logical references are automatically converted into digest-aware paths in production when `assets:precompile` has been run (through a JSON mapping file found in `public/assets/.manifest.json`).
with Sprockets if if a developer would use scss file of bootstrap (E.g gem twbs/bootstrap) he could change configuration with scss variables like:
// in app/assets/stylesheets/application.scss
$primary: #c11;
@import "bootstrap";
Question 1: Is it save to assume this will not be possible with Propshaft ? Even with Bootstrap css variables ?
I'm asking this just to be 100% sure I'm not missing something. I fully understand Propshaft is not precompiler of scss like Sprockets/Webpacker
Question 2: if so, how would developer approach this customisation ?
Is it save to assume the choices are:
esbuild
or webpacker
, ... (but he we would be back to square 1 => the need of node)dartsass-rails
(which is good, but then where would be the line what css files place to Propshaft and which to dartsass assets)anything else I've missed?
(personally I prefer option 3)
This is the underlying cause of #90 but the description and comments there conflate a number of issues.
Create two CSS files:
/* application.css */
import('other.css');
/* other.css */
body {
background-color: pink;
}
Load application.css
:
<%= stylesheet_link_tag 'application' %>
Load the page (with browser caching enabled) and observe a pink background.
Change the body background in other.css
:
- background-color: pink;
+ background-color: red;
Reload the page.
The background is now red.
The background is still pink.
The digest for application.css
is computed from the unprocessed file content. This causes Propshaft::Asset
to produce the same digest for the asset even though the actual contents at that URL will be different (due to the changing digest of other.css
).
Because the asset is served with a very long expiry, browsers will hang on to the outdated version of the asset for a very long time.
In a production scenario, browsers would never get the new version of other.css
. This makes using @import
a pretty big foot gun.
Hi! I was just following the sprockets upgrade guide and spotted a typo:
On Section 3, step 1, it says Replace 'sass-rails' with 'propshaft';
- guess this should be Replace 'sprockets-rails' with 'propshaft';
?
Also, in case its useful for future docs:
while this guide is clearly about Sprockets -> propshaft, I was moving from a webpacker
with no sprockets-rails
setup, in which case if you first remove webpacker
(Steps 1/2 on Section 1) it is not possible to run the jsbundling-rails
install script on Step 3 as Rails will fail to boot with NoMethodError: undefined method 'assets' for #<Rails::Application::Configuration
if the environment contains any assets
config. So need to do the install before removing webpacker
or add the sprockets railtie temporarily.
Just finished migrating a large app to js/cssbundling-rails
& propshaft
๐ Thanks!
Hi all,
I've recently moved to propshaft - it works well for my CSS, but I've got an issue where it seems the importmap doesn't play nicely with js file digests from propshaft?
Here's my layout with css/js include tags
// app/views/layouts/application.html.erb
...
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
...
The importmap_tags render to the following
//application.html
<script type="importmap" data-turbo-track="reload">{
"imports": {
"application": "/assets/application-21d758878bc6e580bde82acbd80fe95b7de35812.js",
"@hotwired/turbo-rails": "/assets/turbo-e40a6f56b17550917ebb699ac84022e5715c8b05.js",
"nouislider": "https://cdn.skypack.dev/nouislider"
}
}</script>
<link rel="modulepreload" href="/assets/application-21d758878bc6e580bde82acbd80fe95b7de35812.js">
<link rel="modulepreload" href="/assets/turbo-e40a6f56b17550917ebb699ac84022e5715c8b05.js">
<script src="/assets/es-module-shims.min-e2b12bbbb10c875738c2e170931855bd187b4b90.js" async="async" data-turbo-track="reload"></script>
<script type="module">import "application"</script>
here's my application.js that imports all the required files
// application.js
import { Turbo } from "@hotwired/turbo-rails"
import { DataSourceValidator } from './src/data_source_validator.js';
import { FormFiller } from './src/form_filler.js';
All the local file imports in application.js
404 at the path /assets/src/
Is this because the src files are all digested by propshaft but the module importer is trying to import the plain filenames?
Has anyone got any recommendations for fixing this please?
I have just switched to use propshaft from sprockets and it has all gone well except for one last issue.
When running in a local development environment, with the rails config.relative_url_root set, the compilers do not prepend this value onto the generated urls.
url([asset]) becomes url([config.assets.prefix]/[digested-asset]) not url([config.relative_url_root]/[config.assets.prefix]/[digested-file])
This means the assets cannot be found as they are under the url root.
I believe in production I can overcome this by setting the config.assets.prefix to be <config.relative_url_root>/assets as this will generate the correct path, and then the assets are served up separately.
However, the above solution does not work in development (or test) as while the correct url is generated in the css, the asset cannot be served by the development server (they are under /url_root/url_root/assets)
Is there a way of setting up the configuration so that I can use relative_url_root in development or should the compilers be including the relative_url_root in the generated path
We swap out the Rails::Rack::Logger
middleware with a custom logger with app.middleware.swap(Rails::Rack::Logger, OurCustomLogger, logger_opts)
. When that happens, app.middleware.insert_before ::Rails::Rack::Logger, Propshaft::QuietAssets
will throw a No such middleware to insert before: Rails::Rack::Logger
RuntimeError.
propshaft/lib/propshaft/railtie.rb
Line 61 in 1c53221
As stuck with issue reported here, started to migrate Sprockets 4 to Propshaft
Used:
rails tmp:clear
rake assets:clobber
rake assets:precompile
ruby-3.1.2
gem 'rails', '7.0.3.1'
gem 'webrick'
gem 'propshaft', github: 'rails/propshaft', branch: 'main'
gem 'dartsass-rails', '~> 0.4.0'
...
Starting server with:
./bin/dev
Opening web page gives:
The asset 'print.css' was not found in the load path.
= stylesheet_link_tag 'print', media: 'print'
app/views/layouts/login.html.haml content:
...
= stylesheet_link_tag 'application', media: 'all'
= stylesheet_link_tag 'print', media: 'print'
= javascript_include_tag 'application'
...
app/stylesheets/print.scss
after precompile:
with sprockets4:
public/assets/print.css
With propshaft it is:
public/assets/print.scss
Content of app/assets/stylesheets/print.scss
:
@use "print/articles" as print_articles;
@use "print/base" as print_base;
Renaming print.scss
to print.css
, problem is gone. Why propshaft not doing that?
Theoretically, anything that changes the behavior of a compiler should impact the hash. Barring that, would it make sense to bring back config.assets.version
and include that in the hash?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.