propshaft 0.1.0 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2eb4dab520f6e9bc958d7ea65ed10531ab418ac34c3daefdcec0b4d61094bcdd
4
- data.tar.gz: 8d76024de20625ee78b0cc8409a2e74b66ac0ccd8203ba14e263d89b649da21d
3
+ metadata.gz: f5ac96be7b15334f58662f5033d02375a23050328d28aca71058777cd1778ba6
4
+ data.tar.gz: bb4c8a1c289ce56c380da154c0174d6bef08a988cd7a4e53fe0193b05f62b092
5
5
  SHA512:
6
- metadata.gz: 5f8fbd11cd6a8a9031be35139887e1cec8e3823a4eb68e79ad61df91a307aa1222927fd8d87316c6b55df979cdd91f57bc4d653e092190a1b7933db175e44f14
7
- data.tar.gz: 70a5ad6e8382e5dafc4bed6b26e1f9ba5008f6bd536961393b807cbb47580dbfc95c1c1cbe04b1b4954968213c2aa112ed822e156fe8f044209bade7ccc79de8
6
+ metadata.gz: e082b706b8d3e1733805697fdb3f3520ba977531533ec1da6078277cf9e7d59c8a2cf79464653ec8d058ae98b40db10cf372bc3e260ea56194aa062cf7f501b0
7
+ data.tar.gz: eb18c451c949637476e936afcf88a656dad3f0ae7217d326fbb117390bfc3de7ae83e5fe71f66848739300d7d841ba113abf6704cb6c3e95ddae47d9ca674547
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Propshaft
2
2
 
3
- Propshaft is an asset pipeline library for Rails. It's built for era where bundling assets to save on HTTP connections is no longer urgent, where JavaScript and CSS is either compiled by dedicated Node.js bundlers or served directly to the browsers, and where increases in bandwidth has made the need for minification less pressing. These factors allow for a dramatically simpler and faster asset pipeline compared to previous options, like Sprockets.
3
+ Propshaft is an asset pipeline library for Rails. It's built for an era where bundling assets to save on HTTP connections is no longer urgent, where JavaScript and CSS are either compiled by dedicated Node.js bundlers or served directly to the browsers, and where increases in bandwidth have made the need for minification less pressing. These factors allow for a dramatically simpler and faster asset pipeline compared to previous options, like Sprockets.
4
4
 
5
- So that's what Propshaft doesn't do. Here's what it actually does provide:
5
+ So that's what Propshaft doesn't do. Here's what it does provide:
6
6
 
7
- 1. Configurable load path: You can register directories from multiple places in your app and gems, and reference assets from all of these paths as though they were one.
8
- 1. Digest processing: All assets in the load path will be copied (or compiled) in a precompilation step for production that also stamps all of them with a digest hash, so you can use long-expiry cache headers for better performance. The digested assets can be referred to through their logical path because the processing leaves a manifest file that provides a way to translate.
9
- 1. Development server: There's no need to precompile the assets in development. You can refer to them via the same asset_path helpers and they'll be served by a development server.
10
- 1. Basic compiler step: Propshaft was explicitly not designed to provide full transpiler capabilities. You can get that better elsewhere. But it does offer a simple input->output compiler setup that by default is used to translate `asset-path` function calls in CSS to `url(digested-asset)` instead.
7
+ 1. **Configurable load path**: You can register directories from multiple places in your app and gems, and reference assets from all of these paths as though they were one.
8
+ 1. **Digest stamping**: All assets in the load path will be copied (or compiled) in a precompilation step for production that also stamps all of them with a digest hash, so you can use long-expiry cache headers for better performance. The digested assets can be referred to through their logical path because the processing leaves a manifest file that provides a way to translate.
9
+ 1. **Development server**: There's no need to precompile the assets in development. You can refer to them via the same asset_path helpers and they'll be served by a development server.
10
+ 1. **Basic compilers**: Propshaft was explicitly not designed to provide full transpiler capabilities. You can get that better elsewhere. But it does offer a simple input->output compiler setup that by default is used to translate `asset-path` function calls in CSS to `url(digested-asset)` instead.
11
11
 
12
12
 
13
13
  ## Installation
@@ -17,16 +17,16 @@ With Rails 7+, you can start a new application with propshaft using `rails new m
17
17
 
18
18
  ## Usage
19
19
 
20
- Propshaft makes all the assets from all the paths its 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 bundled assets.
20
+ 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.
21
21
 
22
- 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`).
22
+ 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`).
23
23
 
24
24
  Additionally, Propshaft ships with a CSS function called `asset-path("image.svg")` that'll be compiled into `url("/assets/image-f2e1ec14d6856e1958083094170ca6119c529a73.svg")` when doing `assets:precompile`. This function is applied to all `.css` files.
25
25
 
26
26
 
27
27
  ## Migrating from Sprockets
28
28
 
29
- Propshaft does a lot less than Sprockets, by design, so it might well be a fair bit of work to migrate, if it's even desirable. This is particularly true if you rely on Sprockets to provide any form of transpiling, like CoffeeScript or Sass, or if you rely on any gems that do. You'll need to either stop transpiling or use a Node-based transpiler, like those in `jsbundling-rails` and `cssbundling-rails`.
29
+ Propshaft does a lot less than Sprockets, by design, so it might well be a fair bit of work to migrate if it's even desirable. This is particularly true if you rely on Sprockets to provide any form of transpiling, like CoffeeScript or Sass, or if you rely on any gems that do. You'll need to either stop transpiling or use a Node-based transpiler, like those in `jsbundling-rails` and `cssbundling-rails`.
30
30
 
31
31
  On the other hand, if you're already bundling JavaScript and CSS through a Node-based setup, then Propshaft is going to slot in easily. Since you don't need another tool to bundle or transpile. Just to digest and serve.
32
32
 
@@ -7,7 +7,7 @@ class Propshaft::Compilers::CssAssetUrls
7
7
 
8
8
  def compile(input)
9
9
  input.gsub(/asset-path\(["']([^"')]+)["']\)/) do |match|
10
- %[url("/#{assembly.config.prefix}/#{assembly.load_path.find($1).digested_path}")]
10
+ %[url("#{assembly.config.prefix}/#{assembly.load_path.find($1).digested_path}")]
11
11
  end
12
12
  end
13
13
  end
@@ -11,8 +11,12 @@ class Propshaft::LoadPath
11
11
  assets_by_path[asset_name]
12
12
  end
13
13
 
14
- def assets
15
- assets_by_path.values
14
+ def assets(content_types: nil)
15
+ if content_types
16
+ assets_by_path.values.select { |asset| asset.content_type.in?(content_types) }
17
+ else
18
+ assets_by_path.values
19
+ end
16
20
  end
17
21
 
18
22
  def manifest
@@ -1,5 +1,6 @@
1
1
  class Propshaft::Processor
2
2
  MANIFEST_FILENAME = ".manifest.json"
3
+ COMPRESSABLE_CONTENT_TYPES = %i[ js css text json xml html svg otf ttf ].collect { |t| Mime[t] }
3
4
 
4
5
  attr_reader :load_path, :output_path, :compilers
5
6
 
@@ -41,10 +42,6 @@ class Propshaft::Processor
41
42
  compile_asset(asset) || copy_asset(asset)
42
43
  end
43
44
 
44
- def copy_asset(asset)
45
- FileUtils.copy asset.path, output_path.join(asset.digested_path)
46
- end
47
-
48
45
  def compile_asset(asset)
49
46
  File.open(output_path.join(asset.digested_path), "w+") do |file|
50
47
  begin
@@ -56,10 +53,13 @@ class Propshaft::Processor
56
53
  end if compilers.compilable?(asset)
57
54
  end
58
55
 
56
+ def copy_asset(asset)
57
+ FileUtils.copy asset.path, output_path.join(asset.digested_path)
58
+ end
59
+
59
60
 
60
61
  def compress_assets
61
- # FIXME: Only try to compress text assets with brotli
62
- load_path.assets.each do |asset|
62
+ load_path.assets(content_types: COMPRESSABLE_CONTENT_TYPES).each do |asset|
63
63
  compress_asset output_path.join(asset.digested_path)
64
64
  end if compressor_available?
65
65
  end
@@ -18,15 +18,6 @@ module Propshaft
18
18
  config.assets.prefix = "/assets"
19
19
  config.assets.compilers = [ [ "text/css", Propshaft::Compilers::CssAssetUrls ] ]
20
20
 
21
- # Compatibility shiming (need to provide log warnings when used)
22
- config.assets.precompile = []
23
- config.assets.debug = nil
24
- config.assets.quiet = nil
25
- config.assets.compile = nil
26
- config.assets.version = nil
27
- config.assets.css_compressor = nil
28
- config.assets.js_compressor = nil
29
-
30
21
  config.after_initialize do |app|
31
22
  config.assets.output_path ||=
32
23
  Pathname.new(File.join(app.config.paths["public"].first, app.config.assets.prefix))
@@ -50,5 +41,14 @@ module Propshaft
50
41
  end
51
42
  end
52
43
  end
44
+
45
+ # Compatibility shiming (need to provide log warnings when used)
46
+ config.assets.precompile = []
47
+ config.assets.debug = nil
48
+ config.assets.quiet = nil
49
+ config.assets.compile = nil
50
+ config.assets.version = nil
51
+ config.assets.css_compressor = nil
52
+ config.assets.js_compressor = nil
53
53
  end
54
54
  end
@@ -8,7 +8,7 @@ module Propshaft::Resolver
8
8
 
9
9
  def resolve(logical_path)
10
10
  if asset = load_path.find(logical_path)
11
- File.join prefix, asset.logical_path
11
+ File.join prefix, asset.digested_path
12
12
  end
13
13
  end
14
14
  end
@@ -6,7 +6,9 @@ class Propshaft::Server
6
6
  end
7
7
 
8
8
  def call(env)
9
- if asset = @assembly.load_path.find(requested_path(env))
9
+ path, digest = extract_path_and_digest(env)
10
+
11
+ if (asset = @assembly.load_path.find(path)) && asset.digest == digest
10
12
  compiled_content = @assembly.compilers.compile(asset)
11
13
 
12
14
  [
@@ -15,7 +17,7 @@ class Propshaft::Server
15
17
  "Content-Length" => compiled_content.length.to_s,
16
18
  "Content-Type" => asset.content_type,
17
19
  "ETag" => asset.digest,
18
- "Cache-Control" => "public, must-revalidate"
20
+ "Cache-Control" => "public, max-age=31536000, immutable"
19
21
  },
20
22
  [ compiled_content ]
21
23
  ]
@@ -25,7 +27,11 @@ class Propshaft::Server
25
27
  end
26
28
 
27
29
  private
28
- def requested_path(env)
29
- Rack::Utils.unescape(env["PATH_INFO"].to_s.sub(/^\//, ""))
30
+ def extract_path_and_digest(env)
31
+ full_path = Rack::Utils.unescape(env["PATH_INFO"].to_s.sub(/^\//, ""))
32
+ digest = full_path[/-([0-9a-f]{7,128})\.[^.]+\z/, 1]
33
+ path = digest ? full_path.sub("-#{digest}", "") : full_path
34
+
35
+ [ path, digest ]
30
36
  end
31
37
  end
@@ -1,3 +1,3 @@
1
1
  module Propshaft
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.4"
3
3
  end
data/lib/propshaft.rb CHANGED
@@ -1,3 +1,6 @@
1
+ module Propshaft
2
+ end
3
+
1
4
  require "propshaft/assembly"
2
5
  require "propshaft/helper"
3
6
  require "propshaft/railtie"
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.1.0
4
+ version: 0.1.4
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: 2021-09-19 00:00:00.000000000 Z
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails