jekyll-minify-js 0.1.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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/lib/jekyll_minify_js.rb +109 -0
  4. metadata +111 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e1f72d786bd2ce0c1dbd137ff1ba6cebd86e821ddaf316ab29d7c069bbed93d7
4
+ data.tar.gz: d64d7e54e46539d68d9de1bc960fa37b6addf655f861354291e622006996af14
5
+ SHA512:
6
+ metadata.gz: ebf5214539d6cf1b969ee420d27c247f2cae2d3931ef8cf57ded6fa7673e322eee8f62bf49934515ccc8e72b0546b5c31b587816eac166b3545b1594245b36e6
7
+ data.tar.gz: 615d71275d2ce2084feed54aa665b82faedc94e0e14d9853bcc4d6cef4e3f27e9466194dfcde019ebd1a00f1e745c40d797bfa5eb2b5e1047e01142f823b9d07
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ ISC License
2
+
3
+ Copyright 2025 Pho Thin Maung<phothinmg@disroot.org>
4
+
5
+ Permission to use, copy, modify, and/or distribute
6
+ this software for any purpose with or without fee is
7
+ hereby granted, provided that the above copyright
8
+ notice and this permission notice appear in all copies.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
11
+ DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
14
+ FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
16
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
17
+ CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
18
+ OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
19
+ THIS SOFTWARE.
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jekyll'
4
+ require 'fileutils'
5
+ require 'shellwords'
6
+ begin
7
+ require 'terser'
8
+ rescue LoadError
9
+ # terser gem not available; plugin will fallback to external CLI or copy
10
+ end
11
+ require 'pathname'
12
+
13
+ # module Jekyll
14
+ module Jekyll
15
+ # MinifyJs is a Jekyll `Generator` that minifies JavaScript files found under
16
+ # common asset directories. It prefers the `terser` Ruby gem when available
17
+ # and falls back to an external `terser` CLI when necessary.
18
+ class MinifyJs < Generator
19
+ safe true
20
+ priority :low
21
+
22
+ def generate(_site)
23
+ # Work is done in the :post_write hook to avoid Jekyll overwriting outputs.
24
+ end
25
+
26
+ def self.run(site) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
27
+ # Support both repository-root layout and app/ layout.
28
+ candidates = [
29
+ File.join(site.source, 'assets', 'js'),
30
+ File.join(site.source, 'app', 'assets', 'js')
31
+ ]
32
+ src_dir = candidates.find { |p| Dir.exist?(p) }
33
+ return unless src_dir
34
+
35
+ # Read configuration from _config.yml under `minify_js:` key
36
+ cfg = site.config.fetch('minify_js', {})
37
+ return if cfg.key?('enabled') && cfg['enabled'] == false
38
+
39
+ dest_dir = File.join(site.dest, cfg.fetch('output_dir', 'assets/js'))
40
+ FileUtils.mkdir_p(dest_dir)
41
+
42
+ terser_available = defined?(Terser)
43
+
44
+ # Build options from config
45
+ compress_opt = cfg.fetch('compress', true)
46
+ mangle_opt = cfg.fetch('mangle', true)
47
+ source_map_enabled = cfg.fetch('source_map', true)
48
+ exclude_patterns = cfg.fetch('exclude', ['**/*.min.js'])
49
+
50
+ Dir.glob(File.join(src_dir, '**', '*.js')).each do |src| # rubocop:disable Metrics/BlockLength
51
+ rel = Pathname.new(src).relative_path_from(Pathname.new(src_dir)).to_s
52
+ out = File.join(dest_dir, rel)
53
+ out_dir = File.dirname(out)
54
+ FileUtils.mkdir_p(out_dir)
55
+ map_name = "#{File.basename(out)}.map"
56
+
57
+ # Skip excluded files
58
+ next if exclude_patterns.any? { |pat| File.fnmatch(pat, rel) }
59
+
60
+ if terser_available
61
+ Jekyll.logger.info 'Terser:', "minifying #{rel} via terser Ruby gem"
62
+ begin
63
+ src_content = File.open(src, 'r:BOM|UTF-8', &:read)
64
+ options = {}
65
+ options[:compress] = compress_opt
66
+ options[:mangle] = mangle_opt
67
+ if source_map_enabled
68
+ options[:source_map] =
69
+ { filename: File.basename(src), output_filename: File.basename(out), sources_content: true,
70
+ url: map_name }
71
+ compiled, map = Terser.compile_with_map(src_content, options)
72
+ else
73
+ compiled = Terser.compile(src_content, options)
74
+ map = nil
75
+ end
76
+ compiled += "\n//# sourceMappingURL=#{map_name}\n" unless compiled.include?('sourceMappingURL')
77
+ File.write(out, compiled)
78
+ File.write("#{out}.map", map) if map
79
+ rescue StandardError => e
80
+ Jekyll.logger.warn 'Terser:', "ruby terser failed for #{rel}: #{e.message}; copying original"
81
+ FileUtils.cp(src, out)
82
+ end
83
+ else
84
+ terser_cmd = new.detect_terser_cmd
85
+ if terser_cmd
86
+ cmd = %(#{terser_cmd} #{Shellwords.escape(src)} --compress --mangle -o #{Shellwords.escape(out)} --source-map "url='#{map_name}',includeSources") # rubocop:disable Layout/LineLength
87
+ Jekyll.logger.info 'Terser:', "minifying #{rel} via external terser"
88
+ success = system(cmd)
89
+ unless success && File.exist?(out)
90
+ Jekyll.logger.warn 'Terser:', "minify failed for #{rel}; copying original"
91
+ FileUtils.cp(src, out)
92
+ end
93
+ else
94
+ Jekyll.logger.warn 'Terser:', 'no terser available — copying original JS'
95
+ FileUtils.cp(src, out)
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ def detect_terser_cmd
102
+ # Prefer the bundler-installed terser (from the `terser` gem) via `bundle exec terser`.
103
+ return 'bundle exec terser' if system('bundle exec terser --version > /dev/null 2>&1')
104
+ return 'terser' if system('terser --version > /dev/null 2>&1')
105
+
106
+ nil
107
+ end
108
+ end
109
+ end
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-minify-js
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Pho Thin Maung
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: fileutils
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.8'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.8'
26
+ - !ruby/object:Gem::Dependency
27
+ name: jekyll
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '4.4'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '4.4'
40
+ - !ruby/object:Gem::Dependency
41
+ name: pathname
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.4.0
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.4.0
54
+ - !ruby/object:Gem::Dependency
55
+ name: shellwords
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.2.2
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.2.2
68
+ - !ruby/object:Gem::Dependency
69
+ name: terser
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.2'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.2'
82
+ email: phothinmg@disroot.org
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - LICENSE
88
+ - lib/jekyll_minify_js.rb
89
+ homepage: https://rubygems.org/gems/hola
90
+ licenses:
91
+ - ISC
92
+ metadata:
93
+ rubygems_mfa_required: 'true'
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: 3.4.8
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.6.9
109
+ specification_version: 4
110
+ summary: Jekyll plugin for Minify Js.
111
+ test_files: []