darkroom 0.0.3 → 0.0.6
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/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
|