Last active
November 22, 2018 10:47
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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