darkroom 0.0.3 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +127 -41
- data/VERSION +1 -1
- data/lib/darkroom/asset.rb +253 -100
- data/lib/darkroom/darkroom.rb +60 -13
- data/lib/darkroom/delegates/css.rb +39 -0
- data/lib/darkroom/delegates/html.rb +53 -0
- data/lib/darkroom/delegates/htx.rb +21 -0
- data/lib/darkroom/delegates/javascript.rb +14 -0
- data/lib/darkroom/errors/asset_error.rb +33 -0
- data/lib/darkroom/errors/asset_not_found_error.rb +10 -21
- data/lib/darkroom/errors/circular_reference_error.rb +21 -0
- data/lib/darkroom/errors/duplicate_asset_error.rb +4 -4
- data/lib/darkroom/errors/invalid_path_error.rb +28 -0
- data/lib/darkroom/errors/missing_library_error.rb +3 -3
- data/lib/darkroom/errors/unrecognized_extension_error.rb +21 -0
- data/lib/darkroom/version.rb +1 -1
- data/lib/darkroom.rb +16 -32
- metadata +11 -4
- data/lib/darkroom/errors/spec_not_defined_error.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfceb46e778a627cdd5fb64a51224ce2fdbfabb27dc4020e625d470fd80050a5
|
4
|
+
data.tar.gz: 38478af8de2fb0c42f46857e204b05ba76fa5f18415e0ae7d66baaefb04a5d8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 513abc20887e655aa9ecbcdfb706ae9c75d0e97907de7cd72e42aec6544839c4e96596f576b551b3e06dbc8d0fcd1edacbb212a662a017c6edbf0ed6c3111b58
|
7
|
+
data.tar.gz: e93f811868982d3ede4e64c848f9479a8564959845d0a1dea3a1bce980961d9fb8278513f969bfef45ac258fc39bce486c1915129ed69c914ffdce75ad0060ed
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright 2021 Nate Pickens
|
1
|
+
Copyright 2021-2022 Nate Pickens
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
4
4
|
documentation files (the "Software"), to deal in the Software without restriction, including without
|
data/README.md
CHANGED
@@ -9,19 +9,20 @@ each language's native import statement syntax.
|
|
9
9
|
The following file types are supported out of the box, though support for others can be added (see the
|
10
10
|
[Extending](#extending) section):
|
11
11
|
|
12
|
-
| Name | Content Type
|
13
|
-
|
14
|
-
| CSS | text/css
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
| JPEG | image/jpeg
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
| Name | Content Type | Extension(s) |
|
13
|
+
|------------|------------------|--------------|
|
14
|
+
| CSS | text/css | .css |
|
15
|
+
| HTML | text/html | .htm, .html |
|
16
|
+
| HTX | text/javascript | .htx |
|
17
|
+
| ICO | image/x-icon | .ico |
|
18
|
+
| JavaScript | text/javascript | .js |
|
19
|
+
| JPEG | image/jpeg | .jpg, .jpeg |
|
20
|
+
| JSON | application/json | .json |
|
21
|
+
| PNG | image/png | .png |
|
22
|
+
| SVG | image/svg+xml | .svg |
|
23
|
+
| Text | text/plain | .txt |
|
24
|
+
| WOFF | font/woff | .woff |
|
25
|
+
| WOFF2 | font/woff2 | .woff2 |
|
25
26
|
|
26
27
|
## Installation
|
27
28
|
|
@@ -37,6 +38,17 @@ Or install manually on the command line:
|
|
37
38
|
gem install darkroom
|
38
39
|
```
|
39
40
|
|
41
|
+
Darkroom depends on a few other gems for compilation and minification of certain asset types, but does not
|
42
|
+
explicitly include them as dependencies since need for them varies from project to project. As such, if your
|
43
|
+
project includes HTX templates or you wish to minify CSS and/or JavaScript assets, the following will need
|
44
|
+
to be added to your Gemfile:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
gem('htx') # HTX compilation
|
48
|
+
gem('sassc') # CSS minification
|
49
|
+
gem('terser') # JavaScript and HTX minification
|
50
|
+
```
|
51
|
+
|
40
52
|
## Usage
|
41
53
|
|
42
54
|
To create and start using a Darkroom instance, specify one or more load paths (all other arguments are
|
@@ -44,50 +56,70 @@ optional):
|
|
44
56
|
|
45
57
|
```ruby
|
46
58
|
darkroom = Darkroom.new('app/assets', 'vendor/assets', '...',
|
47
|
-
hosts: [
|
59
|
+
hosts: [ # Hosts to prepend to asset paths (useful in production
|
60
|
+
'https://cname1.cdn.com', # when assets are served from a CDN with multiple
|
61
|
+
'https://cname2.cdn.com', # cnames); hosts are chosen round-robin per thread
|
62
|
+
'...',
|
63
|
+
],
|
48
64
|
prefix: '/static', # Prefix to add to all asset paths
|
49
|
-
pristine: ['/google-verify.html'], # Paths with no prefix or versioning (
|
65
|
+
pristine: ['/google-verify.html'], # Paths with no prefix or versioning (/favicon.ico,
|
66
|
+
# /mask-icon.svg, /humans.txt, and /robots.txt are
|
67
|
+
# included automatically)
|
50
68
|
minify: true, # Minify assets that can be minified
|
51
|
-
minified_pattern: /(\.|-)min\.\w+$/, # Files
|
52
|
-
internal_pattern: /^\/components\//, # Files
|
69
|
+
minified_pattern: /(\.|-)min\.\w+$/, # Files to skip minification on when minify: true
|
70
|
+
internal_pattern: /^\/components\//, # Files to disallow direct external access to (they can
|
71
|
+
# still be imported into other assets)
|
53
72
|
min_process_interval: 1, # Minimum time that must elapse between process calls
|
54
73
|
)
|
74
|
+
```
|
55
75
|
|
56
|
-
|
57
|
-
|
76
|
+
Note that assets paths across all load path directories must be globally unique (e.g. the existence of both
|
77
|
+
`app/assets/app.js` and `vendor/assets/app.js` will result in an error).
|
78
|
+
|
79
|
+
Darkroom will never update assets without explicitly being told to do so. The following call should be made
|
80
|
+
once when the app is started and additionally at the beginning of each web request in development to refresh
|
81
|
+
any modified assets:
|
82
|
+
|
83
|
+
```ruby
|
58
84
|
darkroom.process
|
85
|
+
```
|
86
|
+
|
87
|
+
Alternatively, assets can be dumped to disk when deploying to a production environment where assets will be
|
88
|
+
uploaded to and served from a CDN or proxy server:
|
59
89
|
|
60
|
-
|
61
|
-
# uploaded to and served from a CDN or proxy server.
|
90
|
+
```ruby
|
62
91
|
darkroom.dump('output/dir',
|
63
92
|
clear: true, # Delete contents of output/dir before dumping
|
64
93
|
include_pristine: true, # Include pristine assets (if preparing for CDN upload, files like
|
65
94
|
) # /favicon.ico or /robots.txt should be left out)
|
66
95
|
```
|
67
96
|
|
68
|
-
Note that assets paths across all load path directories must be globally unique (e.g. the existence of both
|
69
|
-
`app/assets/app.js` and `vendor/assets/app.js` will result in an error).
|
70
|
-
|
71
97
|
To work with assets:
|
72
98
|
|
73
99
|
```ruby
|
74
|
-
#
|
75
|
-
path = darkroom.asset_path('/js/app.js')
|
100
|
+
# A Darkroom instance has a few convenience helper methods.
|
101
|
+
path = darkroom.asset_path('/js/app.js') # => '/static/js/app-[fingerprint].js'
|
102
|
+
integrity = darkroom.asset_integrity('/js/app.js') # => 'sha384-[hash]'
|
76
103
|
|
77
104
|
# Retrieve the Asset object associated with a path.
|
78
105
|
asset = darkroom.asset(path)
|
79
106
|
|
80
|
-
#
|
81
|
-
assest.path
|
82
|
-
assest.
|
107
|
+
# Prefix (if set on the Darkroom instance) is included in the unversioned and versioned paths.
|
108
|
+
assest.path # => '/js/app.js'
|
109
|
+
assest.path_unversioned # => '/static/js/app.js'
|
110
|
+
assest.path_versioned # => '/static/js/app-[fingerprint].js'
|
83
111
|
|
84
|
-
asset.content_type
|
85
|
-
asset.content
|
112
|
+
asset.content_type # => 'text/javascript'
|
113
|
+
asset.content # Content of processed /js/app.js file
|
86
114
|
|
87
|
-
asset.headers # => {'Content-Type' => '
|
115
|
+
asset.headers # => {'Content-Type' => 'text/javascript',
|
88
116
|
# 'Cache-Control' => 'public, max-age=31536000'}
|
89
|
-
asset.headers(versioned: false) # => {'Content-Type' => '
|
90
|
-
# 'ETag' => '
|
117
|
+
asset.headers(versioned: false) # => {'Content-Type' => 'text/javascript',
|
118
|
+
# 'ETag' => '[fingerprint]'}
|
119
|
+
|
120
|
+
asset.integrity # => 'sha384-[hash]'
|
121
|
+
asset.integrity(:sha256) # => 'sha256-[hash]'
|
122
|
+
asset.integrity(:sha512) # => 'sha512-[hash]'
|
91
123
|
```
|
92
124
|
|
93
125
|
## Asset Bundling
|
@@ -146,19 +178,73 @@ Imports can even be cyclical. If `asset-a.css` imports `asset-b.css` and vice-ve
|
|
146
178
|
contain the content of both of those assets (though order will be different as an asset's own content always
|
147
179
|
comes after any imported assets' contents).
|
148
180
|
|
181
|
+
## Asset References
|
182
|
+
|
183
|
+
Asset paths and content can be inserted into an asset by referencing an asset's path and including a query
|
184
|
+
parameter.
|
185
|
+
|
186
|
+
| String | Result |
|
187
|
+
|----------------------------------|-----------------------------------|
|
188
|
+
| /logo.svg?asset-path | /prefix/logo-[fingerprint].svg |
|
189
|
+
| /logo.svg?asset-path=versioned | /prefix/logo-[fingerprint].svg |
|
190
|
+
| /logo.svg?asset-path=unversioned | /prefix/logo.svg |
|
191
|
+
| /logo.svg?asset-content | data:image/svg+xml;base64,[data] |
|
192
|
+
| /logo.svg?asset-content=base64 | data:image/svg+xml;base64,[data] |
|
193
|
+
| /logo.svg?asset-content=utf8 | data:image/svg+xml;utf8,\<svg>... |
|
194
|
+
|
195
|
+
Where these get recognized is specific to each asset type.
|
196
|
+
|
197
|
+
* **CSS** - Within `url(...)`, which may be unquoted or quoted with single or double quotes.
|
198
|
+
* **HTML** - Values of `href` and `src` attributes on `a`, `area`, `audio`, `base`, `embed`, `iframe`,
|
199
|
+
`img`, `input`, `link`, `script`, `source`, `track`, and `video` tags.
|
200
|
+
* **HTX** - Same behavior as HTML.
|
201
|
+
|
202
|
+
HTML assets additionally support the `?asset-content=displace` query parameter for use with `<link>`,
|
203
|
+
`<script>`, and `<img>` tags with CSS, JavaScript, and SVG asset references, respectively. The entire tag is
|
204
|
+
replaced appropriately.
|
205
|
+
|
206
|
+
```html
|
207
|
+
<!-- Source -->
|
208
|
+
<head>
|
209
|
+
<title>My App</title>
|
210
|
+
<link href='/app.css?asset-content=displace' type='text/css'>
|
211
|
+
<script src='/app.js?asset-content=displace'></script>
|
212
|
+
</head>
|
213
|
+
|
214
|
+
<body>
|
215
|
+
<img src='/logo.svg?asset-content-displace'>
|
216
|
+
</body>
|
217
|
+
|
218
|
+
<!-- Result -->
|
219
|
+
<head>
|
220
|
+
<title>My App</title>
|
221
|
+
<style>/* Content of /app.css */</style>
|
222
|
+
<script>/* Content of /app.js */</script>
|
223
|
+
</head>
|
224
|
+
|
225
|
+
<body>
|
226
|
+
<svg><!-- ... --></svg>
|
227
|
+
</body>
|
228
|
+
```
|
229
|
+
|
149
230
|
## Extending
|
150
231
|
|
151
232
|
Darkroom is extensible. Support for arbitrary file types can be added as follows (all named parameters are
|
152
233
|
optional):
|
153
234
|
|
154
235
|
```ruby
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
236
|
+
# Simple type with no special behavior.
|
237
|
+
Darkroom.register('.extension1', 'extension2', '...', 'content/type')
|
238
|
+
|
239
|
+
# Complex type with special behavior.
|
240
|
+
Darkroom.register('.extension1', 'extension2', '...',
|
241
|
+
content_type: 'content/type', # HTTP MIME type string
|
242
|
+
import_regex: /import (?<path>.*)/, # Regex for identifying imports for bundling
|
243
|
+
reference_regex: /ref=(?<path>.*)/, # Regex for identifying references to other assets
|
244
|
+
compile_lib: 'some-compile-lib', # Name of library required for compilation
|
245
|
+
compile: ->(path, content) { '...' }, # Lambda that returns compiled content
|
246
|
+
minify_lib: 'some-minify-lib', # Name of library required for minification
|
247
|
+
minify: ->(content) { '...' }, # Lambda that returns minified content
|
162
248
|
)
|
163
249
|
|
164
250
|
```
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.6
|