Skip to content

Instantly share code, notes, and snippets.

@dimitar-kunchev
Last active November 22, 2018 10:47
Show Gist options
  • Save dimitar-kunchev/e792d31236428c4285d9be3199ebcd61 to your computer and use it in GitHub Desktop.
Save dimitar-kunchev/e792d31236428c4285d9be3199ebcd61 to your computer and use it in GitHub Desktop.
JS minification script with support to watch multiple files on linux; via javascript-minifier.com
#!/usr/bin/python3
"""
This script uses javascript-minifier.com to compress JS files. The way you can us it is:
To generate a .min.js version in the same folder:
jsminify.py some-file.js
To watch for changes as you edit file(s) in a directory:
jsminify.py -w ./
To watch for changes in cirrent dir and specify target dir for compressed files:
jsminify.py -d ../minified/ ./
To compress one file and specify output
jsminify.py -o minified/some-file.js source/some-file.js
The arguments constructions can be improved, but it gets the job done.
Example use with git pre-commit hook where you have one js dir with source files and js.min dir with output files
#!/bin/bash
srcdir="some-path/js"
mindir="some-path/js.min"
BRANCH=`git rev-parse --abbrev-ref HEAD`
echo $BRANCH
changes=`git diff --cached --name-only $srcdir`
for f in $changes; do
echo $f
outf=`echo ${f/$srcdir/$mindir}`
echo $outf
jsminify.py -o $outf $f
git add $outf
done
"""
import sys
import getopt
import os.path
import requests
import glob
import inotify.adapters
import datetime
def minify(file_name, out_target=None):
with open(file_name, 'r') as f:
js = f.read()
payload = {'input': js}
url = 'https://javascript-minifier.com/raw'
in_file_name = os.path.basename(file_name)
if out_target is None:
out_dir = os.path.dirname(file_name)
name, ext = os.path.splitext(in_file_name)
out_file_name = name + '.min' + ext
print('Minify ' + in_file_name + ' -> ' + out_file_name)
out_file_name = os.path.join(out_dir, file_name)
elif os.path.isdir(out_target):
out_file_name = os.path.join(out_target, file_name)
print('Minify ' + in_file_name + ' -> ' + out_file_name)
else:
out_file_name = out_target
print('Minify ' + in_file_name + ' -> ' + out_file_name)
response = requests.post(url, payload)
if response.ok:
with open(out_file_name, 'w') as f:
f.write(response.text)
else:
print('ERROR')
if __name__ == "__main__":
try:
cmdline_opts, args = getopt.getopt(sys.argv[1:], "wd:o:", ["watch", "dir=", "out="])
except getopt.GetoptError as err:
print('getopt error')
sys.exit(1)
watch_mode = False
output_dir = None
output_file_name = None
input_file_list = args # type: list
for opt, arg in cmdline_opts:
if opt in ['-w', '--watch']:
watch_mode = True
if opt in ['-d', '--dir']:
print("Output will be in " + arg)
output_dir = arg
if opt in ['-o', '--out']:
# print('Output will be ' + arg)
output_file_name = arg
if output_file_name is not None:
if len(input_file_list) is not 1:
print('Output option can be used only with single file')
sys.exit(2)
print(input_file_list)
parsed_file_list = []
for f in input_file_list:
if os.path.exists(f) and os.path.isfile(f):
print('Add file ' + f)
parsed_file_list.append(f)
else:
possible_matches = glob.glob(f, recursive=True)
if len(possible_matches) > 0:
for fn in possible_matches:
if not fn.endswith('.min.js'):
if os.path.isfile(fn):
parsed_file_list.append(fn)
else:
print('Do not minify ' + fn + ' - not a file')
else:
print('Do not minify ' + fn + ' - already minified?')
for f in parsed_file_list:
if output_file_name:
minify(f, output_file_name)
sys.exit(0)
else:
minify(f, output_dir)
if watch_mode:
ina = inotify.adapters.Inotify()
for fl in input_file_list:
if os.path.isdir(fl):
print('Add watch on ' + fl)
ina.add_watch(fl)
monitor_events = {'IN_CREATE', 'IN_MOVED_TO', 'IN_CLOSE_WRITE'}
while True:
for event in ina.event_gen(timeout_s=1, yield_nones=False):
(_, type_names, path, file_name) = event
# print(event)
if any(x in set(type_names) for x in monitor_events):
# or IN_MODIFY
if file_name.endswith('.js') and not file_name.endswith('.min.js'):
print(datetime.datetime.now(), end=": ")
minify(os.path.join(path, file_name), output_dir)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment