propshaft 0.6.4 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +10 -0
- data/lib/propshaft/asset.rb +8 -12
- data/lib/propshaft/compilers/css_asset_urls.rb +7 -6
- data/lib/propshaft/load_path.rb +3 -2
- data/lib/propshaft/output_path.rb +1 -1
- data/lib/propshaft/quiet_assets.rb +14 -0
- data/lib/propshaft/railtie.rb +10 -2
- data/lib/propshaft/railties/assets.rake +4 -0
- data/lib/propshaft/resolver/static.rb +1 -1
- data/lib/propshaft/server.rb +9 -9
- data/lib/propshaft/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a149fdc0fb45487422a71e21df47105ee0071e23f752f596f54cd98400bc99e2
|
4
|
+
data.tar.gz: 9dcd99aa258a91aa99ac46f1da9379712d836f06c42cd8ce9e6df8b020cc94c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79779f26c1d121049451c5a8d7545e9fbfbcdd2b01a966f89fa0a23aa2b140ea2932828bd4c1b9edbab8be106366f8f92f9daa91bfa1c7af2207619a6fcce9fe
|
7
|
+
data.tar.gz: 7f609b53f85ef6bdeb53972c11d9a54301cd974c7d5573d5d93fbeb043daed863e08407bb95b45d7c8a55a122770dcb5f9f8b2d55f6830c2adbb5465281613ad
|
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
|
|
data/lib/propshaft/asset.rb
CHANGED
@@ -2,10 +2,15 @@ require "digest/sha1"
|
|
2
2
|
require "action_dispatch/http/mime_type"
|
3
3
|
|
4
4
|
class Propshaft::Asset
|
5
|
+
PREDIGESTED_REGEX = /-([0-9a-zA-Z]{7,128}\.digested)/
|
6
|
+
|
5
7
|
attr_reader :path, :logical_path, :version
|
6
8
|
|
7
9
|
def initialize(path, logical_path:, version: nil)
|
8
|
-
@path
|
10
|
+
@path = path
|
11
|
+
@digest = logical_path.to_s[PREDIGESTED_REGEX, 1]
|
12
|
+
@logical_path = Pathname.new(@digest ? logical_path.sub("-#{@digest}", "") : logical_path)
|
13
|
+
@version = version
|
9
14
|
end
|
10
15
|
|
11
16
|
def content
|
@@ -25,23 +30,14 @@ class Propshaft::Asset
|
|
25
30
|
end
|
26
31
|
|
27
32
|
def digested_path
|
28
|
-
|
29
|
-
logical_path
|
30
|
-
else
|
31
|
-
logical_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" }
|
32
|
-
end
|
33
|
+
logical_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" }
|
33
34
|
end
|
34
35
|
|
35
36
|
def fresh?(digest)
|
36
|
-
self.digest == digest
|
37
|
+
self.digest == digest
|
37
38
|
end
|
38
39
|
|
39
40
|
def ==(other_asset)
|
40
41
|
logical_path.hash == other_asset.logical_path.hash
|
41
42
|
end
|
42
|
-
|
43
|
-
private
|
44
|
-
def already_digested?
|
45
|
-
logical_path.to_s =~ /-([0-9a-zA-Z]{7,128})\.digested/
|
46
|
-
end
|
47
43
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Propshaft::Compilers::CssAssetUrls
|
4
|
-
attr_reader :assembly
|
4
|
+
attr_reader :assembly, :url_prefix
|
5
5
|
|
6
|
-
ASSET_URL_PATTERN = /url\(\s*["']?(?!(
|
6
|
+
ASSET_URL_PATTERN = /url\(\s*["']?(?!(?:\#|%23|data|http|\/\/))([^"'\s?#)]+)([#?][^"')]+)?\s*["']?\)/
|
7
7
|
|
8
8
|
def initialize(assembly)
|
9
|
-
@assembly
|
9
|
+
@assembly = assembly
|
10
|
+
@url_prefix = File.join(assembly.config.host.to_s, assembly.config.prefix.to_s).chomp("/")
|
10
11
|
end
|
11
12
|
|
12
13
|
def compile(logical_path, input)
|
13
|
-
input.gsub(ASSET_URL_PATTERN) { asset_url resolve_path(logical_path.dirname, $1), logical_path, $1 }
|
14
|
+
input.gsub(ASSET_URL_PATTERN) { asset_url resolve_path(logical_path.dirname, $1), logical_path, $2, $1 }
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|
@@ -24,9 +25,9 @@ class Propshaft::Compilers::CssAssetUrls
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
def asset_url(resolved_path, logical_path, pattern)
|
28
|
+
def asset_url(resolved_path, logical_path, fingerprint, pattern)
|
28
29
|
if asset = assembly.load_path.find(resolved_path)
|
29
|
-
%[url("#{
|
30
|
+
%[url("#{url_prefix}/#{asset.digested_path}#{fingerprint}")]
|
30
31
|
else
|
31
32
|
Propshaft.logger.warn "Unable to resolve '#{pattern}' for missing asset '#{resolved_path}' in #{logical_path}"
|
32
33
|
%[url("#{pattern}")]
|
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
|
@@ -48,7 +48,8 @@ class Propshaft::LoadPath
|
|
48
48
|
paths.each do |path|
|
49
49
|
without_dotfiles(all_files_from_tree(path)).each do |file|
|
50
50
|
logical_path = file.relative_path_from(path)
|
51
|
-
|
51
|
+
asset = Propshaft::Asset.new(file, logical_path: logical_path, version: version)
|
52
|
+
mapped[asset.logical_path.to_s] ||= asset
|
52
53
|
end if path.exist?
|
53
54
|
end
|
54
55
|
end
|
@@ -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,6 +9,7 @@ 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
14
|
[ "text/css", Propshaft::Compilers::CssAssetUrls ],
|
13
15
|
[ "text/css", Propshaft::Compilers::SourceMappingUrls ],
|
@@ -15,6 +17,7 @@ module Propshaft
|
|
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.host = 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.host = app.config.asset_host
|
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/assets/.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
|
-
"
|
20
|
-
"
|
21
|
-
"
|
17
|
+
"content-length" => compiled_content.length.to_s,
|
18
|
+
"content-type" => asset.content_type.to_s,
|
19
|
+
"accept-encoding" => "vary",
|
20
|
+
"etag" => asset.digest,
|
21
|
+
"cache-control" => "public, max-age=31536000, immutable"
|
22
22
|
},
|
23
23
|
[ compiled_content ]
|
24
24
|
]
|
25
25
|
else
|
26
|
-
[ 404, { "
|
26
|
+
[ 404, { "content-type" => "text/plain", "content-length" => "9" }, [ "Not found" ] ]
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -34,7 +34,7 @@ class Propshaft::Server
|
|
34
34
|
private
|
35
35
|
def extract_path_and_digest(env)
|
36
36
|
full_path = Rack::Utils.unescape(env["PATH_INFO"].to_s.sub(/^\//, ""))
|
37
|
-
digest = full_path[/-([0-9a-zA-Z]{7,128}
|
37
|
+
digest = full_path[/-([0-9a-zA-Z]{7,128}(?:\.digested)?)\.[^.]+\z/, 1]
|
38
38
|
path = digest ? full_path.sub("-#{digest}", "") : full_path
|
39
39
|
|
40
40
|
[ path, digest ]
|
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.7.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-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/propshaft/load_path.rb
|
87
87
|
- lib/propshaft/output_path.rb
|
88
88
|
- lib/propshaft/processor.rb
|
89
|
+
- lib/propshaft/quiet_assets.rb
|
89
90
|
- lib/propshaft/railtie.rb
|
90
91
|
- lib/propshaft/railties/assets.rake
|
91
92
|
- lib/propshaft/resolver/dynamic.rb
|
@@ -112,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
113
|
- !ruby/object:Gem::Version
|
113
114
|
version: '0'
|
114
115
|
requirements: []
|
115
|
-
rubygems_version: 3.
|
116
|
+
rubygems_version: 3.4.6
|
116
117
|
signing_key:
|
117
118
|
specification_version: 4
|
118
119
|
summary: Deliver assets for Rails.
|