jekyll-simple-assets 0.1.0 → 0.6.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/Gemfile.lock +81 -0
- data/README.md +115 -3
- data/jekyll-simple-assets.gemspec +2 -0
- data/lib/jekyll-simple-assets.rb +106 -158
- data/lib/jekyll-simple-assets/content-hash.rb +181 -0
- data/lib/jekyll-simple-assets/critical.rb +141 -0
- data/lib/jekyll-simple-assets/esbuild.rb +92 -0
- data/lib/jekyll-simple-assets/terser.rb +100 -0
- data/lib/jekyll-simple-assets/version.rb +1 -1
- metadata +36 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9a88ce587480260a2b882650c270bdc2109b2e85fb0171259b19134d8860c7e
|
4
|
+
data.tar.gz: 89d8af9b0ccc245da99c45e43369cfb636e978d862ad80a7bf01a595f2df75f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4104483ef4f80d627cab01fbc07799aae26849d4015ec03671b4cd74ed09728d39f7f2ffdcef339c2fc5a7ace21933b8218c200a34750216ac40234f3e7bb69
|
7
|
+
data.tar.gz: 144171dcfee48d6800d2796ed8eb14772ea82873914e5b53f616a206bfe1af28b73c6c2ba5b265edaae9de24931877f5f0a69cfd2ee5d6fce50939186a72f4fb
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
jekyll-simple-assets (0.6.0)
|
5
|
+
css_parser
|
6
|
+
jekyll
|
7
|
+
terser
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.7.0)
|
13
|
+
public_suffix (>= 2.0.2, < 5.0)
|
14
|
+
colorator (1.1.0)
|
15
|
+
concurrent-ruby (1.1.8)
|
16
|
+
css_parser (1.9.0)
|
17
|
+
addressable
|
18
|
+
em-websocket (0.5.2)
|
19
|
+
eventmachine (>= 0.12.9)
|
20
|
+
http_parser.rb (~> 0.6.0)
|
21
|
+
eventmachine (1.2.7)
|
22
|
+
execjs (2.7.0)
|
23
|
+
ffi (1.15.0)
|
24
|
+
forwardable-extended (2.6.0)
|
25
|
+
http_parser.rb (0.6.0)
|
26
|
+
i18n (1.8.9)
|
27
|
+
concurrent-ruby (~> 1.0)
|
28
|
+
jekyll (4.2.0)
|
29
|
+
addressable (~> 2.4)
|
30
|
+
colorator (~> 1.0)
|
31
|
+
em-websocket (~> 0.5)
|
32
|
+
i18n (~> 1.0)
|
33
|
+
jekyll-sass-converter (~> 2.0)
|
34
|
+
jekyll-watch (~> 2.0)
|
35
|
+
kramdown (~> 2.3)
|
36
|
+
kramdown-parser-gfm (~> 1.0)
|
37
|
+
liquid (~> 4.0)
|
38
|
+
mercenary (~> 0.4.0)
|
39
|
+
pathutil (~> 0.9)
|
40
|
+
rouge (~> 3.0)
|
41
|
+
safe_yaml (~> 1.0)
|
42
|
+
terminal-table (~> 2.0)
|
43
|
+
jekyll-sass-converter (2.1.0)
|
44
|
+
sassc (> 2.0.1, < 3.0)
|
45
|
+
jekyll-watch (2.2.1)
|
46
|
+
listen (~> 3.0)
|
47
|
+
kramdown (2.3.1)
|
48
|
+
rexml
|
49
|
+
kramdown-parser-gfm (1.1.0)
|
50
|
+
kramdown (~> 2.0)
|
51
|
+
liquid (4.0.3)
|
52
|
+
listen (3.5.0)
|
53
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
54
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
55
|
+
mercenary (0.4.0)
|
56
|
+
pathutil (0.16.2)
|
57
|
+
forwardable-extended (~> 2.6)
|
58
|
+
public_suffix (4.0.6)
|
59
|
+
rb-fsevent (0.10.4)
|
60
|
+
rb-inotify (0.10.1)
|
61
|
+
ffi (~> 1.0)
|
62
|
+
rexml (3.2.4)
|
63
|
+
rouge (3.26.0)
|
64
|
+
safe_yaml (1.0.5)
|
65
|
+
sassc (2.4.0)
|
66
|
+
ffi (~> 1.9)
|
67
|
+
terminal-table (2.0.0)
|
68
|
+
unicode-display_width (~> 1.1, >= 1.1.1)
|
69
|
+
terser (1.1.3)
|
70
|
+
execjs (>= 0.3.0, < 3)
|
71
|
+
unicode-display_width (1.7.0)
|
72
|
+
|
73
|
+
PLATFORMS
|
74
|
+
ruby
|
75
|
+
|
76
|
+
DEPENDENCIES
|
77
|
+
bundler
|
78
|
+
jekyll-simple-assets!
|
79
|
+
|
80
|
+
BUNDLED WITH
|
81
|
+
2.1.4
|
data/README.md
CHANGED
@@ -12,21 +12,22 @@ webpack.
|
|
12
12
|
|
13
13
|
#### contenthash
|
14
14
|
|
15
|
-
Returns
|
15
|
+
Returns a base64 encoded md5 hash based on the contents of the path given.
|
16
16
|
|
17
17
|
```liquid
|
18
18
|
{% contenthash assets/js/app.js %}
|
19
|
-
//
|
19
|
+
// Mpz5BzLfDInvj7C36UFv4w==
|
20
20
|
```
|
21
21
|
|
22
22
|
#### asset
|
23
23
|
|
24
24
|
Returns a relative url to the path given, with a hash based on the content of
|
25
25
|
the file as a query string.
|
26
|
+
Will link to a minified version of the file if possible.
|
26
27
|
|
27
28
|
```liquid
|
28
29
|
{% asset assets/js/app.js %}
|
29
|
-
// /assets/js/app.js?v=
|
30
|
+
// /assets/js/app.js?v=Mpz5BzLfDInvj7C36UFv4w==
|
30
31
|
```
|
31
32
|
|
32
33
|
#### bundle
|
@@ -58,9 +59,120 @@ Returns an md5 hash of the input string.
|
|
58
59
|
{{ 'some text' | md5 }}
|
59
60
|
```
|
60
61
|
|
62
|
+
#### uglify
|
63
|
+
|
64
|
+
Minifies javascript given as an input string (uses terser, and terser settings
|
65
|
+
even though the filter is called `uglify`
|
66
|
+
|
67
|
+
```liquid
|
68
|
+
{{ 'const foo = "bar"' | uglify }}
|
69
|
+
```
|
70
|
+
|
61
71
|
## Content hashes
|
62
72
|
|
63
73
|
How the content hashes work is by generating a placeholder string that is
|
64
74
|
passed to the template. Once all of the sites files and pages have been
|
65
75
|
processed and copied over, the content hashes are worked out, and the
|
66
76
|
placeholder string in the pages output is replaced with the hash.
|
77
|
+
|
78
|
+
Because of this you need to be careful with using capture tags around or trying
|
79
|
+
to manipulate the output of the contenthash or asset tags.
|
80
|
+
|
81
|
+
By default the generation of content hashes is only enabled for production
|
82
|
+
builds (if JEKYLL_ENV is set to 'production').
|
83
|
+
|
84
|
+
## Critical CSS
|
85
|
+
|
86
|
+
This plugin can also be used to generate critical css stylesheets. See
|
87
|
+
configuration for more information on doing this. To generate critical css,
|
88
|
+
[critical](https://github.com/addyosmani/critical) must be installed.
|
89
|
+
|
90
|
+
## Javascript/Typescript bundling
|
91
|
+
|
92
|
+
This plugin can also be used to bundle javascript and typescript files and
|
93
|
+
modules using esbuild. Node modules can be included just by requiring them.
|
94
|
+
Local modules can be required under the `@simple-assets` namespace, which
|
95
|
+
will look for js files in the `_js` and `_ts` directories.
|
96
|
+
|
97
|
+
For example:
|
98
|
+
```javascript
|
99
|
+
// assets/js/main.js
|
100
|
+
|
101
|
+
// require node_module
|
102
|
+
var leftpad = require('left-pad');
|
103
|
+
|
104
|
+
// will look for left-pad.js or left-pad.ts at _js/ or _ts/ in the
|
105
|
+
// project root
|
106
|
+
var rightpad = require('@simple-assets/right-pad');
|
107
|
+
```
|
108
|
+
|
109
|
+
You can also put variables in the liquid frontmatter of a js/ts file (that is
|
110
|
+
not under `_js` or `_ts`) to configure esbuild.
|
111
|
+
|
112
|
+
```liquid
|
113
|
+
---
|
114
|
+
bundle: false # don't bundle or run esbuild on this file
|
115
|
+
esbuild_flags: --target=es5 # pass any flags to esbuild for this file
|
116
|
+
---
|
117
|
+
```
|
118
|
+
|
119
|
+
To bundle javascript [esbuild](https://github.com/evanw/esbuild) must be
|
120
|
+
installed.
|
121
|
+
|
122
|
+
## Javascript minification
|
123
|
+
|
124
|
+
The terser package is also included and will minify files if `terser_enabled`
|
125
|
+
is set to true in config.yml, or if JEKYLL_ENV is set to production. Any
|
126
|
+
options can be passed to terser under the `terser` key in config.yml
|
127
|
+
(see configuration for example, or
|
128
|
+
[here](https://github.com/ahorek/terser-ruby) for detailed options).
|
129
|
+
Additionally you can set terser settings in the liquid frontmatter of a js file
|
130
|
+
in the same manner as in config.yml, also under the `terser` key.
|
131
|
+
|
132
|
+
## Configuration
|
133
|
+
|
134
|
+
```
|
135
|
+
simple_assets:
|
136
|
+
# If set to true generation of content hashes will be enabled, even in a non
|
137
|
+
# production build.
|
138
|
+
# default: false
|
139
|
+
hashing_enabled: true
|
140
|
+
|
141
|
+
# If set to true, source maps will be generated for javascript
|
142
|
+
# default: false
|
143
|
+
source_maps_enabled: true
|
144
|
+
|
145
|
+
# The length of the content hashes generated.
|
146
|
+
# default: 16
|
147
|
+
hash_length: 8
|
148
|
+
|
149
|
+
# Options for generating a critical css file using the `critical` npm module
|
150
|
+
critical_css:
|
151
|
+
|
152
|
+
# Array of source css files used to take the critical css from
|
153
|
+
css_files:
|
154
|
+
- assets/css/style.css
|
155
|
+
|
156
|
+
# Array of critical css files to generate
|
157
|
+
files:
|
158
|
+
# The path of the critical css file output
|
159
|
+
- output_file: assets/css/critical.css
|
160
|
+
# The path of the input page used to generate the critical css
|
161
|
+
# either this option or layout can be used
|
162
|
+
input_page_path: _drafts/webmentions-static-site.md
|
163
|
+
# The layout to use to generate critical css
|
164
|
+
# (will use the first page found with this layout)
|
165
|
+
layout: post
|
166
|
+
# If the rules should be removed from the original source css files
|
167
|
+
extract: true
|
168
|
+
|
169
|
+
# Options for bundling javascript/typescript with the `esbuild` npm module
|
170
|
+
# Set to true to enable
|
171
|
+
bundle: true
|
172
|
+
|
173
|
+
# Options for javascript minification with terser
|
174
|
+
terser:
|
175
|
+
# any options for terser can be put here and will be passed to it
|
176
|
+
output:
|
177
|
+
ascii_only: true
|
178
|
+
```
|
data/lib/jekyll-simple-assets.rb
CHANGED
@@ -2,9 +2,50 @@
|
|
2
2
|
|
3
3
|
require 'digest'
|
4
4
|
require 'pathname'
|
5
|
+
require 'open3'
|
6
|
+
require 'shellwords'
|
7
|
+
|
8
|
+
require 'jekyll-simple-assets/content-hash'
|
9
|
+
require 'jekyll-simple-assets/critical'
|
10
|
+
require 'jekyll-simple-assets/esbuild'
|
11
|
+
require 'jekyll-simple-assets/terser'
|
5
12
|
|
6
13
|
module Jekyll
|
7
14
|
module SimpleAssets
|
15
|
+
def self.site (site = nil)
|
16
|
+
@@site = site if site
|
17
|
+
|
18
|
+
@@site
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.config
|
22
|
+
@@config ||= @@site.config['simple_assets']
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.hashing_enabled?
|
26
|
+
config['hashing_enabled'] || ENV['JEKYLL_ENV'] == 'production'
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.critical_css_enabled?
|
30
|
+
config.key?('critical_css')
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.esbuild_enabled?
|
34
|
+
config.key?('bundle') && config['bundle'] != false
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.esbuild_config_file (file = nil)
|
38
|
+
@@esbuild_config_file ||= file
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.terser_enabled?
|
42
|
+
config['terser_enabled'] || ENV['JEKYLL_ENV'] == 'production'
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.source_maps_enabled?
|
46
|
+
config['source_maps_enabled']
|
47
|
+
end
|
48
|
+
|
8
49
|
module SimpleAssetsFilters
|
9
50
|
def md5 (input)
|
10
51
|
Digest::MD5.hexdigest(input)
|
@@ -13,13 +54,13 @@ module Jekyll
|
|
13
54
|
|
14
55
|
class BundleTag < Jekyll::Tags::IncludeTag
|
15
56
|
def tag_includes_dirs(context)
|
16
|
-
[ "_js", "_assets" ].freeze
|
57
|
+
[ "_js", "_javascript", "_assets" ].freeze
|
17
58
|
end
|
18
59
|
end
|
19
60
|
|
20
61
|
class BundleRawTag < Jekyll::Tags::IncludeTag
|
21
62
|
def tag_includes_dirs(context)
|
22
|
-
[ "_js", "_assets" ].freeze
|
63
|
+
[ "_js", "_javascript", "_assets" ].freeze
|
23
64
|
end
|
24
65
|
|
25
66
|
def render(context)
|
@@ -35,198 +76,105 @@ module Jekyll
|
|
35
76
|
|
36
77
|
return unless File.file? path
|
37
78
|
|
38
|
-
|
39
|
-
content = File.read path
|
40
|
-
end
|
79
|
+
content = File.read path
|
41
80
|
|
42
81
|
content
|
43
82
|
end
|
44
83
|
end
|
84
|
+
end
|
85
|
+
end
|
45
86
|
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.asset_placeholder_map
|
51
|
-
@@asset_placeholder_map ||= {}
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.asset_contenthash_map
|
55
|
-
@@asset_contenthash_map ||= {}
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.get_placeholder (asset_path)
|
59
|
-
asset_placeholder_map[asset_path] ||= Digest::MD5.hexdigest(asset_path)
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.relative_url (site, path)
|
63
|
-
"#{ site.config['baseurl'] }/#{ path }".gsub(%r{/{2,}}, '/')
|
64
|
-
end
|
65
|
-
|
66
|
-
class AssetTag < Liquid::Tag
|
67
|
-
def initialize (tag_name, text, tokens)
|
68
|
-
super
|
69
|
-
@text = text
|
70
|
-
end
|
71
|
-
|
72
|
-
def get_value (context, expression)
|
73
|
-
result = nil
|
74
|
-
|
75
|
-
unless expression.empty?
|
76
|
-
lookup_path = expression.split('.')
|
77
|
-
result = context
|
78
|
-
lookup_path.each do |variable|
|
79
|
-
result = result[variable] if result
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
case result
|
84
|
-
when 'true'
|
85
|
-
result = true
|
86
|
-
when 'false'
|
87
|
-
result = false
|
88
|
-
end
|
89
|
-
|
90
|
-
result || expression
|
91
|
-
end
|
92
|
-
|
93
|
-
def render (context)
|
94
|
-
site = context.registers[:site]
|
95
|
-
page = context.environments.first['page']
|
96
|
-
|
97
|
-
args = Shellwords.split(@text)
|
87
|
+
Liquid::Template.register_tag('bundle', Jekyll::SimpleAssets::BundleTag)
|
88
|
+
Liquid::Template.register_tag('bundle_raw', Jekyll::SimpleAssets::BundleRawTag)
|
98
89
|
|
99
|
-
|
90
|
+
Liquid::Template.register_filter(Jekyll::SimpleAssets::SimpleAssetsFilters)
|
100
91
|
|
101
|
-
|
92
|
+
Jekyll::Hooks.register :site, :post_render, priority: :low do |site, payload|
|
93
|
+
Jekyll::SimpleAssets::site(site)
|
102
94
|
|
103
|
-
|
104
|
-
SimpleAssets::page_assets_map[page_path] ||= {}
|
105
|
-
SimpleAssets::page_assets_map[page_path][asset_path] ||= {}
|
106
|
-
SimpleAssets::page_assets_map[page_path][asset_path][@type] ||= []
|
95
|
+
potential_assets = []
|
107
96
|
|
108
|
-
|
97
|
+
potential_assets += site.pages
|
98
|
+
potential_assets += site.static_files
|
109
99
|
|
110
|
-
|
100
|
+
potential_pages = potential_assets
|
111
101
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
102
|
+
site.collections.each do |collection_name, collection|
|
103
|
+
potential_pages = potential_pages + collection.docs
|
104
|
+
end
|
118
105
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
@type = 'path'
|
123
|
-
end
|
106
|
+
if Jekyll::SimpleAssets::critical_css_enabled?
|
107
|
+
potential_assets.each do |asset|
|
108
|
+
Jekyll::SimpleAssets::make_temp_css_files_for_critical(asset)
|
124
109
|
end
|
125
110
|
|
126
|
-
|
127
|
-
|
128
|
-
super
|
129
|
-
@type = 'contenthash'
|
130
|
-
end
|
111
|
+
potential_pages.each do |doc|
|
112
|
+
Jekyll::SimpleAssets::get_html_input_for_critical(doc, site)
|
131
113
|
end
|
132
114
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
if File.extname(asset_path) == '.scss'
|
137
|
-
asset_path = Pathname.new(asset_path).sub_ext('.css').to_path()
|
138
|
-
elsif File.extname(asset_path) == '.ts'
|
139
|
-
asset_path = Pathname.new(asset_path).sub_ext('.js').to_path()
|
140
|
-
end
|
141
|
-
|
142
|
-
return unless SimpleAssets::asset_placeholder_map[asset_path]
|
143
|
-
return if SimpleAssets::asset_contenthash_map[asset_path]
|
144
|
-
|
145
|
-
content = ""
|
146
|
-
|
147
|
-
# Prefer reading from output if available, because in theory should
|
148
|
-
# be faster than from disk, but fall back to reading from disk for
|
149
|
-
# static assets.
|
150
|
-
if asset.respond_to? :output
|
151
|
-
content = asset.output
|
152
|
-
elsif File.file? asset_path
|
153
|
-
content = File.read asset_path
|
154
|
-
elsif File.file? asset.path
|
155
|
-
content = File.read asset.path
|
156
|
-
else
|
157
|
-
Jekyll.logger.warn "SimpleAssets", "File: #{ asset_path } not found"
|
158
|
-
end
|
115
|
+
Jekyll::SimpleAssets::generate_critical_css(site)
|
116
|
+
end
|
159
117
|
|
160
|
-
|
161
|
-
|
162
|
-
|
118
|
+
if Jekyll::SimpleAssets::hashing_enabled?
|
119
|
+
potential_assets.each do |asset|
|
120
|
+
Jekyll::SimpleAssets::resolve_asset_content_hashes(asset, site)
|
121
|
+
end
|
163
122
|
|
164
|
-
|
123
|
+
if Jekyll::SimpleAssets::critical_css_enabled?
|
124
|
+
Jekyll::SimpleAssets::resolve_critical_css_content_hashes(site)
|
165
125
|
end
|
166
126
|
|
167
|
-
|
127
|
+
potential_pages.each do |doc|
|
168
128
|
page_path = doc.path.sub("#{ site.config['source'] }/", '')
|
169
129
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
types.each do |type, placeholders|
|
174
|
-
placeholders.each do |placeholder_hash|
|
175
|
-
unless SimpleAssets::asset_contenthash_map[asset_path]
|
176
|
-
Jekyll.logger.warn "SimpleAssets", "No contenthash for: #{ asset_path } not found"
|
177
|
-
end
|
178
|
-
|
179
|
-
replacement = SimpleAssets::asset_contenthash_map[asset_path]
|
180
|
-
|
181
|
-
if type == 'path'
|
182
|
-
replacement = "#{ asset_path }?v=#{ replacement }"
|
183
|
-
|
184
|
-
replacement = SimpleAssets::relative_url(site, replacement)
|
185
|
-
end
|
130
|
+
if Jekyll::SimpleAssets::page_assets_map[page_path]
|
131
|
+
doc.output = Jekyll::SimpleAssets::replace_placeholders_for_path(page_path, doc.output)
|
132
|
+
end
|
186
133
|
|
187
|
-
|
134
|
+
if doc.extname =~ /^\.(j|t)s$/i and Jekyll::SimpleAssets::should_minify_file?(doc)
|
135
|
+
min_path, minified = Jekyll::SimpleAssets::minify_file(doc)
|
188
136
|
|
189
|
-
|
190
|
-
|
191
|
-
else
|
192
|
-
doc.output = doc.output.sub(placeholder, replacement)
|
193
|
-
end
|
194
|
-
end
|
137
|
+
if min_path and Jekyll::SimpleAssets::page_assets_map[page_path]
|
138
|
+
minified = Jekyll::SimpleAssets::replace_placeholders_for_path(page_path, minified)
|
195
139
|
end
|
140
|
+
|
141
|
+
File.write(File.join(Jekyll::SimpleAssets::site.config['destination'], min_path), minified)
|
196
142
|
end
|
197
143
|
end
|
198
144
|
end
|
199
145
|
end
|
200
146
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
Liquid::Template.register_filter(Jekyll::SimpleAssets::SimpleAssetsFilters)
|
207
|
-
|
208
|
-
if ENV['JEKYLL_ENV'] == 'production'
|
209
|
-
Jekyll::Hooks.register :site, :post_render do |site, payload|
|
210
|
-
potential_assets = []
|
211
|
-
|
212
|
-
potential_assets += site.pages
|
213
|
-
potential_assets += site.static_files
|
147
|
+
Jekyll::Hooks.register :pages, :post_render do |page, payload|
|
148
|
+
unless Jekyll::SimpleAssets::esbuild_config_file
|
149
|
+
Jekyll::SimpleAssets::generate_esbuild_config_file()
|
150
|
+
end
|
214
151
|
|
215
|
-
|
216
|
-
|
152
|
+
if page.extname =~ /^\.(j|t)s$/i
|
153
|
+
if Jekyll::SimpleAssets::esbuild_enabled?
|
154
|
+
Jekyll::SimpleAssets::esbuild_bundle_file(page, payload, Jekyll::SimpleAssets::esbuild_config_file.path)
|
217
155
|
end
|
218
156
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
Jekyll::SimpleAssets::replace_placeholders_for_asset(doc, site)
|
157
|
+
if Jekyll::SimpleAssets::should_minify_file?(page)
|
158
|
+
min_path = page.path.sub(/\.(j|t)s$/i, '.min.js')
|
159
|
+
File.write(File.join(Jekyll::SimpleAssets::site.config['destination'], min_path), '')
|
223
160
|
end
|
161
|
+
end
|
162
|
+
end
|
224
163
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
164
|
+
Jekyll::Hooks.register :site, :post_read do |site|
|
165
|
+
css_pages = [];
|
166
|
+
|
167
|
+
site.pages.each do |doc|
|
168
|
+
if doc.extname == '.scss'
|
169
|
+
css_pages << doc
|
170
|
+
site.pages = site.pages - [ doc ]
|
229
171
|
end
|
230
172
|
end
|
173
|
+
|
174
|
+
site.pages = css_pages + site.pages
|
231
175
|
end
|
232
176
|
|
177
|
+
# Jekyll::Hooks.register :pages, :post_render do |document|
|
178
|
+
# puts 'rendered:' + document.path
|
179
|
+
# end
|
180
|
+
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module SimpleAssets
|
5
|
+
|
6
|
+
|
7
|
+
def self.hash_length
|
8
|
+
config['hash_length'] || 16
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.page_assets_map
|
12
|
+
@@page_assets_map ||= {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.asset_placeholder_map
|
16
|
+
@@asset_placeholder_map ||= {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.asset_contenthash_map
|
20
|
+
@@asset_contenthash_map ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.get_placeholder (asset_path)
|
24
|
+
asset_placeholder_map[asset_path] ||= Digest::MD5.base64digest(asset_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.relative_url (path)
|
28
|
+
"#{ @@site.config['baseurl'] || '' }/#{ path }".gsub(%r{/{2,}}, '/')
|
29
|
+
end
|
30
|
+
|
31
|
+
class AssetTag < Liquid::Tag
|
32
|
+
def initialize (tag_name, text, tokens)
|
33
|
+
super
|
34
|
+
@text = text
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_value (context, expression)
|
38
|
+
result = nil
|
39
|
+
|
40
|
+
unless expression.empty?
|
41
|
+
lookup_path = expression.split('.')
|
42
|
+
result = context
|
43
|
+
lookup_path.each do |variable|
|
44
|
+
result = result[variable] if result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
case result
|
49
|
+
when 'true'
|
50
|
+
result = true
|
51
|
+
when 'false'
|
52
|
+
result = false
|
53
|
+
end
|
54
|
+
|
55
|
+
result || expression
|
56
|
+
end
|
57
|
+
|
58
|
+
def render (context)
|
59
|
+
site = SimpleAssets::site(context.registers[:site])
|
60
|
+
|
61
|
+
page = context.environments.first['page']
|
62
|
+
|
63
|
+
args = Shellwords.split(@text)
|
64
|
+
|
65
|
+
page_path = context['page']['path'].sub(/^\//, '')
|
66
|
+
|
67
|
+
asset_path = get_value(context, args[0]).sub(/^\//, '')
|
68
|
+
|
69
|
+
if SimpleAssets::hashing_enabled?
|
70
|
+
SimpleAssets::page_assets_map[page_path] ||= {}
|
71
|
+
SimpleAssets::page_assets_map[page_path][asset_path] ||= {}
|
72
|
+
SimpleAssets::page_assets_map[page_path][asset_path][@type] ||= []
|
73
|
+
|
74
|
+
placeholder = SimpleAssets::get_placeholder(asset_path)
|
75
|
+
|
76
|
+
unless SimpleAssets::page_assets_map[page_path][asset_path][@type].include? placeholder
|
77
|
+
SimpleAssets::page_assets_map[page_path][asset_path][@type] << placeholder
|
78
|
+
end
|
79
|
+
|
80
|
+
"#{ @type }::#{ placeholder }"
|
81
|
+
else
|
82
|
+
if @type == 'path'
|
83
|
+
SimpleAssets::relative_url(asset_path)
|
84
|
+
else
|
85
|
+
placeholder[0, SimpleAssets::hash_length]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class PathTag < AssetTag
|
92
|
+
def initialize (tag_name, text, tokens)
|
93
|
+
super
|
94
|
+
@type = 'path'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class ContentHashTag < AssetTag
|
99
|
+
def initialize (tag_name, text, tokens)
|
100
|
+
super
|
101
|
+
@type = 'contenthash'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.resolve_asset_content_hashes (asset, site)
|
106
|
+
asset_path = asset.path.sub("#{ site.config['source'] }/", '')
|
107
|
+
|
108
|
+
if File.extname(asset_path) == '.scss'
|
109
|
+
asset_path = Pathname.new(asset_path).sub_ext('.css').to_path()
|
110
|
+
elsif File.extname(asset_path) == '.ts'
|
111
|
+
asset_path = Pathname.new(asset_path).sub_ext('.js').to_path()
|
112
|
+
end
|
113
|
+
|
114
|
+
return unless SimpleAssets::asset_placeholder_map[asset_path]
|
115
|
+
return if SimpleAssets::asset_contenthash_map[asset_path]
|
116
|
+
|
117
|
+
content = ""
|
118
|
+
|
119
|
+
# Prefer reading from output if available, because in theory should
|
120
|
+
# be faster than from disk, but fall back to reading from disk for
|
121
|
+
# static assets.
|
122
|
+
if asset.respond_to? :output
|
123
|
+
content = asset.output
|
124
|
+
elsif File.file? asset_path
|
125
|
+
content = File.read asset_path
|
126
|
+
elsif File.file? asset.path
|
127
|
+
content = File.read asset.path
|
128
|
+
else
|
129
|
+
Jekyll.logger.warn "SimpleAssets:", "File: #{ asset_path } not found"
|
130
|
+
end
|
131
|
+
|
132
|
+
if content.nil?
|
133
|
+
Jekyll.logger.warn "SimpleAssets:", "#{ asset_path } has no content"
|
134
|
+
end
|
135
|
+
|
136
|
+
base64hash = Digest::MD5.base64digest(content)
|
137
|
+
|
138
|
+
hash = base64hash[0, SimpleAssets::hash_length].gsub(/[+\/]/, '_')
|
139
|
+
|
140
|
+
SimpleAssets::asset_contenthash_map[asset_path] = hash
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.replace_placeholders_for_path (page_path, input)
|
144
|
+
output = input
|
145
|
+
|
146
|
+
SimpleAssets::page_assets_map[page_path].each do |asset_path, types|
|
147
|
+
types.each do |type, placeholders|
|
148
|
+
placeholders.each do |placeholder_hash|
|
149
|
+
unless SimpleAssets::asset_contenthash_map[asset_path]
|
150
|
+
Jekyll.logger.warn "SimpleAssets:", "No contenthash for: #{ asset_path } not found"
|
151
|
+
|
152
|
+
next
|
153
|
+
end
|
154
|
+
|
155
|
+
replacement = SimpleAssets::asset_contenthash_map[asset_path]
|
156
|
+
|
157
|
+
if type == 'path'
|
158
|
+
min_path = asset_path.sub(/\.([^\.]*?)$/, '.min.\1')
|
159
|
+
url = (File.file? File.join(SimpleAssets::site.config['destination'], min_path)) ? min_path : asset_path
|
160
|
+
|
161
|
+
replacement = "#{ url }?v=#{ replacement }"
|
162
|
+
|
163
|
+
replacement = SimpleAssets::relative_url(replacement)
|
164
|
+
end
|
165
|
+
|
166
|
+
placeholder = "#{ type }::#{ SimpleAssets::asset_placeholder_map[asset_path] }"
|
167
|
+
|
168
|
+
output = output.gsub(placeholder, replacement)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
output
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
Liquid::Template.register_tag('asset', Jekyll::SimpleAssets::PathTag)
|
181
|
+
Liquid::Template.register_tag('contenthash', Jekyll::SimpleAssets::ContentHashTag)
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'css_parser'
|
4
|
+
require 'tempfile'
|
5
|
+
|
6
|
+
module Jekyll
|
7
|
+
module SimpleAssets
|
8
|
+
|
9
|
+
|
10
|
+
def self.critical_css_source_files ()
|
11
|
+
@@critical_css_source_files ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.make_temp_css_files_for_critical (asset)
|
15
|
+
SimpleAssets::config['critical_css']['css_files'].each do |path|
|
16
|
+
next unless asset.path == path || asset.path == path.sub(/\.css$/, '.scss')
|
17
|
+
|
18
|
+
f = Tempfile.new([ 'css-source', '.css' ])
|
19
|
+
f.write asset.output
|
20
|
+
f.close
|
21
|
+
|
22
|
+
Jekyll.logger.debug("SimpleAssets:", "Created new temp file for css: #{ asset.path } at: #{ f.path }")
|
23
|
+
|
24
|
+
SimpleAssets::critical_css_source_files[path] = { 'file' => f, 'page' => asset }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.get_html_input_for_critical (doc, site)
|
29
|
+
return unless doc.respond_to? '[]'
|
30
|
+
|
31
|
+
SimpleAssets::config['critical_css']['files'].each do |file|
|
32
|
+
next if file['html']
|
33
|
+
|
34
|
+
page_path = doc.path.sub("#{ site.config['source'] }/", '')
|
35
|
+
|
36
|
+
next unless page_path == file['input_page_path'] || file['layout'] == doc['layout']
|
37
|
+
|
38
|
+
file['html'] = doc.output
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.generate_critical_css (site)
|
43
|
+
css_files_str = ''
|
44
|
+
|
45
|
+
SimpleAssets::critical_css_source_files.each do |_, f|
|
46
|
+
css_files_str += "--css #{ f['file'].path } "
|
47
|
+
|
48
|
+
f['css'] = CssParser::Parser.new
|
49
|
+
f['css'].load_string! f['page'].output
|
50
|
+
end
|
51
|
+
|
52
|
+
SimpleAssets::config['critical_css']['files'].each do |file|
|
53
|
+
css_path = File.join(site.config['destination'], file['output_file'])
|
54
|
+
|
55
|
+
html = file['html']
|
56
|
+
|
57
|
+
critical_cmd = "npx critical #{ css_files_str }"
|
58
|
+
|
59
|
+
Jekyll.logger.debug("SimpleAssets:", "Running command: #{ critical_cmd }")
|
60
|
+
|
61
|
+
Open3.popen3(critical_cmd) do |stdin, stdout, stderr, wait_thr|
|
62
|
+
stdin.write(html)
|
63
|
+
stdin.close
|
64
|
+
|
65
|
+
if !wait_thr.value.success? || stderr.read != ''
|
66
|
+
Jekyll.logger.error("SimpleAssets:", 'Critical (css) error:')
|
67
|
+
stderr.each do |line|
|
68
|
+
Jekyll.logger.error("", line)
|
69
|
+
end
|
70
|
+
elsif stderr.read != ''
|
71
|
+
Jekyll.logger.error("SimpleAssets:", 'Critical (css) error:')
|
72
|
+
stderr.each do |line|
|
73
|
+
Jekyll.logger.error("", line)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
critical_css_str = stdout.read
|
78
|
+
|
79
|
+
asset_path = file['output_file'].sub(/^\//, '')
|
80
|
+
|
81
|
+
base64hash = Digest::MD5.base64digest(critical_css_str)
|
82
|
+
|
83
|
+
hash = base64hash[0, SimpleAssets::hash_length].gsub(/[+\/]/, '_')
|
84
|
+
|
85
|
+
SimpleAssets::asset_contenthash_map[asset_path] = hash
|
86
|
+
|
87
|
+
IO.write(css_path, critical_css_str)
|
88
|
+
|
89
|
+
site.keep_files << asset_path
|
90
|
+
|
91
|
+
if file['extract']
|
92
|
+
critical_css = CssParser::Parser.new
|
93
|
+
|
94
|
+
critical_css.load_string! critical_css_str
|
95
|
+
|
96
|
+
SimpleAssets::critical_css_source_files.each do |_, f|
|
97
|
+
f['css'].each_rule_set do |source_rule_set, source_media_type|
|
98
|
+
critical_css.each_rule_set do |critical_rule_set, critical_media_type|
|
99
|
+
if critical_rule_set.selectors.join(',') == source_rule_set.selectors.join(',')
|
100
|
+
f['css'].remove_rule_set! source_rule_set, source_media_type
|
101
|
+
f['extract'] = true
|
102
|
+
|
103
|
+
break
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
SimpleAssets::critical_css_source_files.each do |_, f|
|
113
|
+
leftover_css = f['css'].to_s if f['extract']
|
114
|
+
|
115
|
+
# css_parser leaves blank keyframes so fix them
|
116
|
+
keyframes = f['page'].output.scan(/@keyframes\s+(?:.*?)\s*{(?:\s*\S*?\s*{.*?}\s*)+}/m)
|
117
|
+
keyframes.each { |keyframe| leftover_css += keyframe }
|
118
|
+
|
119
|
+
f['page'].output
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.resolve_critical_css_content_hashes (site)
|
124
|
+
SimpleAssets::critical_css_source_files.each do |_, source_file|
|
125
|
+
page = source_file['page']
|
126
|
+
page_path = page.path.sub("#{ site.config['source'] }/", '')
|
127
|
+
|
128
|
+
SimpleAssets::config['critical_css']['files'].each do |file|
|
129
|
+
css_path = File.join(site.config['destination'], file['output_file'])
|
130
|
+
content = IO.read(css_path)
|
131
|
+
|
132
|
+
critical = SimpleAssets::replace_placeholders_for_path(page_path, content)
|
133
|
+
|
134
|
+
IO.write(css_path, critical)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Jekyll
|
2
|
+
module SimpleAssets
|
3
|
+
|
4
|
+
def self.generate_esbuild_config_file ()
|
5
|
+
source_path = Jekyll::SimpleAssets::site.config['source']
|
6
|
+
|
7
|
+
tsconfig_path = File.join(source_path, 'jsconfig.json')
|
8
|
+
jsconfig_path = File.join(source_path, 'tsconfig.json')
|
9
|
+
|
10
|
+
config = {}
|
11
|
+
|
12
|
+
if File.file?(tsconfig_path)
|
13
|
+
config = JSON.parse(File.read(tsconfig_path))
|
14
|
+
elsif File.file?(jsconfig_path)
|
15
|
+
config = JSON.parse(File.read(jsconfig_path))
|
16
|
+
end
|
17
|
+
|
18
|
+
f = Tempfile.new([ 'jsconfig.esbuild.', '.json' ])
|
19
|
+
|
20
|
+
config['compilerOptions'] = {} unless config['compilerOptions']
|
21
|
+
|
22
|
+
base_url = source_path
|
23
|
+
if config['compilerOptions']['baseUrl']
|
24
|
+
base_url = File.join(source_path, config['compilerOptions']['baseUrl'])
|
25
|
+
end
|
26
|
+
config['compilerOptions']['baseUrl'] = Pathname.new(base_url).relative_path_from(Pathname.new(f.path))
|
27
|
+
|
28
|
+
config['compilerOptions']['paths'] = {} unless config['compilerOptions']['paths']
|
29
|
+
|
30
|
+
relative_path = Pathname.new(source_path).relative_path_from(Pathname.new(base_url))
|
31
|
+
|
32
|
+
config['compilerOptions']['paths']['@simple-assets/*'] = [
|
33
|
+
File.join(relative_path, '_js/*'),
|
34
|
+
File.join(relative_path, '_ts/*'),
|
35
|
+
]
|
36
|
+
|
37
|
+
f.write config.to_json
|
38
|
+
f.close
|
39
|
+
|
40
|
+
Jekyll::SimpleAssets::esbuild_config_file(f)
|
41
|
+
|
42
|
+
Jekyll.logger.debug("SimpleAssets:", "esbuild: using tsconfig #{ f.path }")
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.esbuild_bundle_file (page, payload, config_path)
|
46
|
+
if page.data['bundle'] == false
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
bundle_cmd = "npx esbuild --bundle --tsconfig=#{ config_path }"
|
51
|
+
|
52
|
+
if page.data['esbuild_flags']
|
53
|
+
bundle_cmd += ' ' + page.data['esbuild_flags']
|
54
|
+
end
|
55
|
+
|
56
|
+
node_env = '--define:process.env.NODE_ENV="' + (ENV['JEKYLL_ENV'] != 'production' ? "'development'" : "'production'") + '"'
|
57
|
+
|
58
|
+
bundle_cmd += ' ' + node_env + " --sourcefile=#{ page.path[/[^\/]*$/] }"
|
59
|
+
|
60
|
+
if SimpleAssets::source_maps_enabled?
|
61
|
+
bundle_cmd += ' ' + '--sourcemap=inline'
|
62
|
+
end
|
63
|
+
|
64
|
+
dir = File.dirname(page.path)
|
65
|
+
|
66
|
+
Jekyll.logger.info("SimpleAssets:", 'bundling: ' + page.path)
|
67
|
+
Jekyll.logger.debug("SimpleAssets:", 'running command: ' + bundle_cmd)
|
68
|
+
|
69
|
+
Open3.popen3(bundle_cmd, :chdir => dir) do |stdin, stdout, stderr, wait_thr|
|
70
|
+
stdin.write(page.output)
|
71
|
+
stdin.close
|
72
|
+
|
73
|
+
bundled = stdout.read
|
74
|
+
|
75
|
+
if !wait_thr.value.success? || stderr.read != ''
|
76
|
+
Jekyll.logger.error("SimpleAssets:", 'esbuild error:')
|
77
|
+
stderr.each do |line|
|
78
|
+
Jekyll.logger.error("", line)
|
79
|
+
end
|
80
|
+
elsif stderr.read != ''
|
81
|
+
Jekyll.logger.error("SimpleAssets:", 'esbuild error:')
|
82
|
+
stderr.each do |line|
|
83
|
+
Jekyll.logger.error("", line)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
page.output = bundled
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'terser'
|
3
|
+
|
4
|
+
module Jekyll
|
5
|
+
|
6
|
+
module SimpleAssets
|
7
|
+
def self.symbolize_keys (hash)
|
8
|
+
return {} if hash.nil?
|
9
|
+
|
10
|
+
hash.inject({}) do |result, (key, value)|
|
11
|
+
|
12
|
+
new_key = case key
|
13
|
+
when String then key.to_sym
|
14
|
+
else key
|
15
|
+
end
|
16
|
+
new_value = case value
|
17
|
+
when Hash then symbolize_keys(value)
|
18
|
+
else value
|
19
|
+
end
|
20
|
+
|
21
|
+
if new_value.is_a?(String) and new_value.match(/^\/.*\/$/)
|
22
|
+
new_value = /#{ Regexp.quote(new_value[1..-2]) }/
|
23
|
+
end
|
24
|
+
|
25
|
+
result[new_key] = new_value
|
26
|
+
|
27
|
+
result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.merge_recursively(a, b)
|
32
|
+
a.merge(b) {|key, a_item, b_item| SimpleAssets::merge_recursively(a_item, b_item) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.should_minify_file? (page)
|
36
|
+
return false unless page.respond_to? :output
|
37
|
+
return false unless SimpleAssets::terser_enabled?
|
38
|
+
return false if page.data['do_not_compress'] == true
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.minify_file (page)
|
43
|
+
return unless SimpleAssets::should_minify_file?(page)
|
44
|
+
|
45
|
+
site_config = symbolize_keys(SimpleAssets::site.config['simple_assets']['terser'])
|
46
|
+
page_config = symbolize_keys(page.data['terser'])
|
47
|
+
|
48
|
+
config = SimpleAssets::merge_recursively(site_config || {}, page_config || {})
|
49
|
+
|
50
|
+
map_path = page.path + '.map'
|
51
|
+
if SimpleAssets::source_maps_enabled?
|
52
|
+
config = SimpleAssets::merge_recursively(config, {
|
53
|
+
:source_map => { :filename => page.path[/[^\/]*$/], :url => true },
|
54
|
+
})
|
55
|
+
|
56
|
+
minified, source_map = Terser.new(config).compile_with_map(page.output)
|
57
|
+
else
|
58
|
+
minified = Terser.new(config).compile(page.output)
|
59
|
+
end
|
60
|
+
|
61
|
+
min_path = page.path.sub(/\.(j|t)s$/i, '.min.js')
|
62
|
+
Jekyll.logger.info("SimpleAssets:", 'minified: ' + min_path)
|
63
|
+
|
64
|
+
if source_map
|
65
|
+
File.write(File.join(SimpleAssets::site.config['destination'], map_path), source_map)
|
66
|
+
minified = minified.gsub(/^\/\/#\s*?source(Mapping)?URL=.*$/, '')
|
67
|
+
minified += "\n//# sourceMappingURL=#{ SimpleAssets::relative_url(map_path) }"
|
68
|
+
|
69
|
+
Jekyll.logger.debug("SimpleAssets:", 'created source map: ' + map_path)
|
70
|
+
|
71
|
+
SimpleAssets::site.config['keep_files'] << map_path
|
72
|
+
end
|
73
|
+
|
74
|
+
if SimpleAssets::page_assets_map[page.path]
|
75
|
+
SimpleAssets::page_assets_map[min_path] = SimpleAssets::page_assets_map[page.path]
|
76
|
+
end
|
77
|
+
|
78
|
+
SimpleAssets::site.config['keep_files'] << min_path
|
79
|
+
|
80
|
+
return min_path, minified
|
81
|
+
end
|
82
|
+
|
83
|
+
module UglifyFilter
|
84
|
+
def uglify (input)
|
85
|
+
return if input.nil?
|
86
|
+
|
87
|
+
return input.split('\n').join('\\\n') unless SimpleAssets::terser_enabled?
|
88
|
+
|
89
|
+
config = @context.registers[:site].config['simple_assets']
|
90
|
+
|
91
|
+
terser_config = SimpleAssets::symbolize_keys(config['terser'])
|
92
|
+
|
93
|
+
Terser.new(terser_config).compile(input)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
Liquid::Template.register_filter(Jekyll::SimpleAssets::UglifyFilter)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-simple-assets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sophie Askew
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: css_parser
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: terser
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: bundler
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -47,10 +75,15 @@ extra_rdoc_files: []
|
|
47
75
|
files:
|
48
76
|
- ".gitignore"
|
49
77
|
- Gemfile
|
78
|
+
- Gemfile.lock
|
50
79
|
- LICENSE
|
51
80
|
- README.md
|
52
81
|
- jekyll-simple-assets.gemspec
|
53
82
|
- lib/jekyll-simple-assets.rb
|
83
|
+
- lib/jekyll-simple-assets/content-hash.rb
|
84
|
+
- lib/jekyll-simple-assets/critical.rb
|
85
|
+
- lib/jekyll-simple-assets/esbuild.rb
|
86
|
+
- lib/jekyll-simple-assets/terser.rb
|
54
87
|
- lib/jekyll-simple-assets/version.rb
|
55
88
|
homepage: https://github.com/syldexiahime/jekyll-simple-assets
|
56
89
|
licenses:
|
@@ -71,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
104
|
- !ruby/object:Gem::Version
|
72
105
|
version: '0'
|
73
106
|
requirements: []
|
74
|
-
|
75
|
-
rubygems_version: 2.7.6
|
107
|
+
rubygems_version: 3.1.3
|
76
108
|
signing_key:
|
77
109
|
specification_version: 4
|
78
110
|
summary: Some simple asset utils for jekyll
|