propshaft 0.6.4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -1
- data/lib/propshaft/assembly.rb +2 -2
- data/lib/propshaft/{compilers → compiler}/css_asset_urls.rb +6 -10
- data/lib/propshaft/{compilers → compiler}/source_mapping_urls.rb +7 -11
- data/lib/propshaft/compiler.rb +20 -0
- data/lib/propshaft/helper.rb +18 -0
- data/lib/propshaft/load_path.rb +1 -1
- data/lib/propshaft/quiet_assets.rb +14 -0
- data/lib/propshaft/railtie.rb +13 -5
- data/lib/propshaft/railties/assets.rake +4 -0
- data/lib/propshaft/resolver/static.rb +1 -1
- data/lib/propshaft/server.rb +14 -8
- data/lib/propshaft/version.rb +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56736cd8d13ffa9511e5cd47d39e3d3849f66484f0ba489686b75aa5a5c57936
|
4
|
+
data.tar.gz: 7adfc7103ca6694027ad577b7cd14bf6972227f02bdf0bd0659d508371afdfad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67c4c686072bc75784519f8043225b9bb462a19a74a2617ec1628a25cb701bad1aabe05a873126038718b6bd18ba9d51f47cdd0daa89418186996832a0f5707c
|
7
|
+
data.tar.gz: f476c9aff5b7975df5815095bdf1917eeb748ee1c9ebab0f058aa670863597a6d4794c77b3bd379eafb355c83b9fa8008b366796ad52188d7804410f93c8ec33
|
data/README.md
CHANGED
@@ -27,6 +27,16 @@ These assets can be referenced through their logical path using the normal helpe
|
|
27
27
|
|
28
28
|
If you need to put multiple files that refer to each other through Propshaft, like a JavaScript file and its source map, you have to digest these files in advance to retain stable file names. Propshaft looks for the specific pattern of `-[digest].digested.js` as the postfix to any asset file as an indication that the file has already been digested.
|
29
29
|
|
30
|
+
## Improving performance in development
|
31
|
+
|
32
|
+
Before every request Propshaft checks if any asset was updated to decide if a cache sweep is needed. This verification is done using the application's configured file watcher which, by default, is `ActiveSupport::FileUpdateChecker`.
|
33
|
+
|
34
|
+
If you have a lot of assets in your project, you can improve performance by adding the `listen` gem to the development group in your Gemfile, and this line to the `development.rb` environment file:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
|
38
|
+
```
|
39
|
+
|
30
40
|
|
31
41
|
## Migrating from Sprockets
|
32
42
|
|
@@ -39,7 +49,7 @@ But for greenfield apps using the default import-map approach, Propshaft can als
|
|
39
49
|
|
40
50
|
## Will Propshaft replace Sprockets as the Rails default?
|
41
51
|
|
42
|
-
Most likely, but Sprockets need to be supported as well for a long time to come. Plenty of apps and gems were built on Sprocket features, and they won't be migrating soon. Still working out the compatibility story. This is very much
|
52
|
+
Most likely, but Sprockets need to be supported as well for a long time to come. Plenty of apps and gems were built on Sprocket features, and they won't be migrating soon. Still working out the compatibility story. This is very much beta software at the moment.
|
43
53
|
|
44
54
|
|
45
55
|
## License
|
data/lib/propshaft/assembly.rb
CHANGED
@@ -4,8 +4,8 @@ require "propshaft/resolver/static"
|
|
4
4
|
require "propshaft/server"
|
5
5
|
require "propshaft/processor"
|
6
6
|
require "propshaft/compilers"
|
7
|
-
require "propshaft/
|
8
|
-
require "propshaft/
|
7
|
+
require "propshaft/compiler/css_asset_urls"
|
8
|
+
require "propshaft/compiler/source_mapping_urls"
|
9
9
|
|
10
10
|
class Propshaft::Assembly
|
11
11
|
attr_reader :config
|
@@ -1,16 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
attr_reader :assembly
|
3
|
+
require "propshaft/compiler"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(assembly)
|
9
|
-
@assembly = assembly
|
10
|
-
end
|
5
|
+
class Propshaft::Compiler::CssAssetUrls < Propshaft::Compiler
|
6
|
+
ASSET_URL_PATTERN = /url\(\s*["']?(?!(?:\#|%23|data|http|\/\/))([^"'\s?#)]+)([#?][^"')]+)?\s*["']?\)/
|
11
7
|
|
12
8
|
def compile(logical_path, input)
|
13
|
-
input.gsub(ASSET_URL_PATTERN) { asset_url resolve_path(logical_path.dirname, $1), logical_path, $1 }
|
9
|
+
input.gsub(ASSET_URL_PATTERN) { asset_url resolve_path(logical_path.dirname, $1), logical_path, $2, $1 }
|
14
10
|
end
|
15
11
|
|
16
12
|
private
|
@@ -24,9 +20,9 @@ class Propshaft::Compilers::CssAssetUrls
|
|
24
20
|
end
|
25
21
|
end
|
26
22
|
|
27
|
-
def asset_url(resolved_path, logical_path, pattern)
|
23
|
+
def asset_url(resolved_path, logical_path, fingerprint, pattern)
|
28
24
|
if asset = assembly.load_path.find(resolved_path)
|
29
|
-
%[url("#{
|
25
|
+
%[url("#{url_prefix}/#{asset.digested_path}#{fingerprint}")]
|
30
26
|
else
|
31
27
|
Propshaft.logger.warn "Unable to resolve '#{pattern}' for missing asset '#{resolved_path}' in #{logical_path}"
|
32
28
|
%[url("#{pattern}")]
|
@@ -1,16 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
attr_reader :assembly
|
3
|
+
require "propshaft/compiler"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(assembly)
|
9
|
-
@assembly = assembly
|
10
|
-
end
|
5
|
+
class Propshaft::Compiler::SourceMappingUrls < Propshaft::Compiler
|
6
|
+
SOURCE_MAPPING_PATTERN = %r{(//|/\*)# sourceMappingURL=(.+\.map)(\s*?\*\/)?\s*?\Z}
|
11
7
|
|
12
8
|
def compile(logical_path, input)
|
13
|
-
input.gsub(SOURCE_MAPPING_PATTERN) { source_mapping_url(asset_path($2, logical_path), $1) }
|
9
|
+
input.gsub(SOURCE_MAPPING_PATTERN) { source_mapping_url(asset_path($2, logical_path), $1, $3) }
|
14
10
|
end
|
15
11
|
|
16
12
|
private
|
@@ -22,12 +18,12 @@ class Propshaft::Compilers::SourceMappingUrls
|
|
22
18
|
end
|
23
19
|
end
|
24
20
|
|
25
|
-
def source_mapping_url(resolved_path,
|
21
|
+
def source_mapping_url(resolved_path, comment_start, comment_end)
|
26
22
|
if asset = assembly.load_path.find(resolved_path)
|
27
|
-
"#{
|
23
|
+
"#{comment_start}# sourceMappingURL=#{url_prefix}/#{asset.digested_path}#{comment_end}"
|
28
24
|
else
|
29
25
|
Propshaft.logger.warn "Removed sourceMappingURL comment for missing asset '#{resolved_path}' from #{resolved_path}"
|
30
|
-
|
26
|
+
"#{comment_start}#{comment_end}"
|
31
27
|
end
|
32
28
|
end
|
33
29
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Base compiler from which other compilers can inherit
|
4
|
+
class Propshaft::Compiler
|
5
|
+
attr_reader :assembly
|
6
|
+
|
7
|
+
def initialize(assembly)
|
8
|
+
@assembly = assembly
|
9
|
+
end
|
10
|
+
|
11
|
+
# Override this in a specific compiler
|
12
|
+
def compile(logical_path, input)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def url_prefix
|
18
|
+
@url_prefix ||= File.join(assembly.config.relative_url_root.to_s, assembly.config.prefix.to_s).chomp("/")
|
19
|
+
end
|
20
|
+
end
|
data/lib/propshaft/helper.rb
CHANGED
@@ -3,5 +3,23 @@ module Propshaft
|
|
3
3
|
def compute_asset_path(path, options = {})
|
4
4
|
Rails.application.assets.resolver.resolve(path) || raise(MissingAssetError.new(path))
|
5
5
|
end
|
6
|
+
|
7
|
+
# Add an option to call `stylesheet_link_tag` with `:all` to include every css file found on the load path.
|
8
|
+
def stylesheet_link_tag(*sources)
|
9
|
+
if sources.first == :all
|
10
|
+
super *all_stylesheets_paths
|
11
|
+
else
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns a sorted and unique array of logical paths for all stylesheets in the load path.
|
17
|
+
def all_stylesheets_paths
|
18
|
+
Rails.application.assets.load_path
|
19
|
+
.assets(content_types: [ Mime::EXTENSION_LOOKUP["css"] ])
|
20
|
+
.collect { |css| css.logical_path.to_s }
|
21
|
+
.sort
|
22
|
+
.uniq
|
23
|
+
end
|
6
24
|
end
|
7
25
|
end
|
data/lib/propshaft/load_path.rb
CHANGED
@@ -28,7 +28,7 @@ class Propshaft::LoadPath
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
# Returns a
|
31
|
+
# Returns a file watcher object configured to clear the cache of the load_path
|
32
32
|
# when the directories passed during its initialization have changes. This is used in development
|
33
33
|
# and test to ensure the map caches are reset when javascript files are changed.
|
34
34
|
def cache_sweeper
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Propshaft::QuietAssets
|
2
|
+
def initialize(app)
|
3
|
+
@app = app
|
4
|
+
@assets_regex = %r(\A/{0,2}#{::Rails.application.config.assets.prefix})
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
if env['PATH_INFO'] =~ @assets_regex
|
9
|
+
::Rails.logger.silence { @app.call(env) }
|
10
|
+
else
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/propshaft/railtie.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "rails"
|
2
2
|
require "active_support/ordered_options"
|
3
|
+
require "propshaft/quiet_assets"
|
3
4
|
|
4
5
|
module Propshaft
|
5
6
|
class Railtie < ::Rails::Railtie
|
@@ -8,13 +9,15 @@ module Propshaft
|
|
8
9
|
config.assets.excluded_paths = []
|
9
10
|
config.assets.version = "1"
|
10
11
|
config.assets.prefix = "/assets"
|
12
|
+
config.assets.quiet = false
|
11
13
|
config.assets.compilers = [
|
12
|
-
[ "text/css", Propshaft::
|
13
|
-
[ "text/css", Propshaft::
|
14
|
-
[ "text/javascript", Propshaft::
|
14
|
+
[ "text/css", Propshaft::Compiler::CssAssetUrls ],
|
15
|
+
[ "text/css", Propshaft::Compiler::SourceMappingUrls ],
|
16
|
+
[ "text/javascript", Propshaft::Compiler::SourceMappingUrls ]
|
15
17
|
]
|
16
18
|
config.assets.sweep_cache = Rails.env.development?
|
17
19
|
config.assets.server = Rails.env.development? || Rails.env.test?
|
20
|
+
config.assets.relative_url_root = nil
|
18
21
|
|
19
22
|
# Register propshaft initializer to copy the assets path in all the Rails Engines.
|
20
23
|
# This makes possible for us to keep all `assets` config in this Railtie, but still
|
@@ -28,6 +31,7 @@ module Propshaft
|
|
28
31
|
end
|
29
32
|
|
30
33
|
config.after_initialize do |app|
|
34
|
+
config.assets.relative_url_root ||= app.config.relative_url_root
|
31
35
|
config.assets.output_path ||=
|
32
36
|
Pathname.new(File.join(app.config.paths["public"].first, app.config.assets.prefix))
|
33
37
|
|
@@ -54,6 +58,12 @@ module Propshaft
|
|
54
58
|
Propshaft.logger = config.assets.logger || Rails.logger
|
55
59
|
end
|
56
60
|
|
61
|
+
initializer :quiet_assets do |app|
|
62
|
+
if app.config.assets.quiet
|
63
|
+
app.middleware.insert_before ::Rails::Rack::Logger, Propshaft::QuietAssets
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
57
67
|
rake_tasks do
|
58
68
|
load "propshaft/railties/assets.rake"
|
59
69
|
end
|
@@ -61,9 +71,7 @@ module Propshaft
|
|
61
71
|
# Compatibility shiming (need to provide log warnings when used)
|
62
72
|
config.assets.precompile = []
|
63
73
|
config.assets.debug = nil
|
64
|
-
config.assets.quiet = nil
|
65
74
|
config.assets.compile = nil
|
66
|
-
config.assets.version = nil
|
67
75
|
config.assets.css_compressor = nil
|
68
76
|
config.assets.js_compressor = nil
|
69
77
|
end
|
@@ -2,6 +2,10 @@ namespace :assets do
|
|
2
2
|
desc "Compile all the assets from config.assets.paths"
|
3
3
|
task precompile: :environment do
|
4
4
|
Rails.application.assets.processor.process
|
5
|
+
if Rails.env.development?
|
6
|
+
puts "Warning: You are precompiling assets in development. Rails will not " \
|
7
|
+
"serve any changed assets until you delete public#{Rails.application.config.assets.prefix}/.manifest.json"
|
8
|
+
end
|
5
9
|
end
|
6
10
|
|
7
11
|
desc "Remove config.assets.output_path"
|
data/lib/propshaft/server.rb
CHANGED
@@ -11,19 +11,19 @@ class Propshaft::Server
|
|
11
11
|
if (asset = @assembly.load_path.find(path)) && asset.fresh?(digest)
|
12
12
|
compiled_content = @assembly.compilers.compile(asset)
|
13
13
|
|
14
|
-
[
|
15
|
-
200,
|
14
|
+
[
|
15
|
+
200,
|
16
16
|
{
|
17
|
-
|
18
|
-
|
19
|
-
"Accept-Encoding"
|
20
|
-
|
21
|
-
|
17
|
+
Rack::CONTENT_LENGTH => compiled_content.length.to_s,
|
18
|
+
Rack::CONTENT_TYPE => asset.content_type.to_s,
|
19
|
+
VARY => "Accept-Encoding",
|
20
|
+
Rack::ETAG => asset.digest,
|
21
|
+
Rack::CACHE_CONTROL => "public, max-age=31536000, immutable"
|
22
22
|
},
|
23
23
|
[ compiled_content ]
|
24
24
|
]
|
25
25
|
else
|
26
|
-
[ 404, {
|
26
|
+
[ 404, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "9" }, [ "Not found" ] ]
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -39,4 +39,10 @@ class Propshaft::Server
|
|
39
39
|
|
40
40
|
[ path, digest ]
|
41
41
|
end
|
42
|
+
|
43
|
+
if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
|
44
|
+
VARY = "Vary"
|
45
|
+
else
|
46
|
+
VARY = "vary"
|
47
|
+
end
|
42
48
|
end
|
data/lib/propshaft/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: propshaft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -78,14 +78,16 @@ files:
|
|
78
78
|
- lib/propshaft.rb
|
79
79
|
- lib/propshaft/assembly.rb
|
80
80
|
- lib/propshaft/asset.rb
|
81
|
+
- lib/propshaft/compiler.rb
|
82
|
+
- lib/propshaft/compiler/css_asset_urls.rb
|
83
|
+
- lib/propshaft/compiler/source_mapping_urls.rb
|
81
84
|
- lib/propshaft/compilers.rb
|
82
|
-
- lib/propshaft/compilers/css_asset_urls.rb
|
83
|
-
- lib/propshaft/compilers/source_mapping_urls.rb
|
84
85
|
- lib/propshaft/errors.rb
|
85
86
|
- lib/propshaft/helper.rb
|
86
87
|
- lib/propshaft/load_path.rb
|
87
88
|
- lib/propshaft/output_path.rb
|
88
89
|
- lib/propshaft/processor.rb
|
90
|
+
- lib/propshaft/quiet_assets.rb
|
89
91
|
- lib/propshaft/railtie.rb
|
90
92
|
- lib/propshaft/railties/assets.rake
|
91
93
|
- lib/propshaft/resolver/dynamic.rb
|
@@ -112,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
114
|
- !ruby/object:Gem::Version
|
113
115
|
version: '0'
|
114
116
|
requirements: []
|
115
|
-
rubygems_version: 3.
|
117
|
+
rubygems_version: 3.4.20
|
116
118
|
signing_key:
|
117
119
|
specification_version: 4
|
118
120
|
summary: Deliver assets for Rails.
|