※記事内に商品プロモーションを含むことがあります。
はじめに
HTML, CSS, JavaScriptを圧縮 (minify) して、ファイル容量を削減するPythonスクリプトを作成しました。
小規模なウェブサイトなどを対象として、ローカルで複数のファイルをまとめてminifyする場面を想定しています。
ローカルでminifyできるツールは多数公開されていますが、圧縮アルゴリズムをブラックボックス化したくなかったためPythonで自作しました。
実行環境はPython 3.9.7です。
圧縮するPythonスクリプト
圧縮するPythonスクリプトは以下の通りです。
minify
という名前の関数にしています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import re
def minify(src_path, dest_path):
"""HTML/CSS/JavaScriptを圧縮する
Args:
src_path (str): 圧縮したいファイルのパス
dest_path (str): 圧縮後に保存するパス
"""
extention = src_path.split(".")[-1] # 拡張子
with open(src_path, encoding="utf_8") as f:
s0 = f.readlines()
if extention=="html":
s1 = "".join([s.strip() for s in s0]) # 各行の前後の空白を削除
s9 = re.sub('<!--.*?-->', '', s1) # コメントの削除
elif extention=="css":
s1 = "".join([s.strip() for s in s0]) # 各行の前後の空白を削除
s2 = re.sub('/\*.*?\*/', '', s1) # コメントの削除
s3 = re.sub(': +?', ':', s2) # セミコロン後の空白を削除
s9 = re.sub(' +?{', '{', s3) # '{'前の空白を削除
elif extention=="js":
s1 = [s.split("//")[0] for s in s0] # 1行コメント(//以降)を削除
s2 = "".join([s.strip() for s in s1]) # 各行の前後の空白を削除
s9 = re.sub('/\*.*?\*/', '', s2) # コメント(/* */)の削除
with open(dest_path, mode='w', encoding="utf_8") as f:
f.write(s9)
|
主な注意点は以下の通りです。
- JavaScriptは各行の末尾に
;
を付けている必要がある
- CSSではショートハンドへの変換は行わない
使用例
Pythonスクリプトの実行結果の例を示します。
HTML
以下の断片的なHTMLファイルsrc/index.html
を圧縮し、dest/index.html
というパスに保存します。
圧縮前
1
2
3
4
5
|
<!--コメント-->
<body>
<h1>見出し</h1>
<img src="img/sample.jpg">
</body>
|
minify
関数を以下のように実行します。
1
|
minify("src/index.html", "dest/index.html")
|
圧縮後
インデントやコメント、改行は削除されます。
1
|
<body><h1>見出し</h1><img src="img/sample.jpg"></body>
|
CSS
以下のCSSファイルsrc/style.css
を圧縮し、dest/style.css
というパスに保存します。
圧縮前
1
2
3
4
|
.main {
/* 余白の追加 */
padding: 10px;
}
|
minify
関数を以下のように実行します。
1
|
minify("src/style.css", "dest/style.css")
|
圧縮後
コメントや改行、余分なスペースは削除されます。
JavaScript
以下のJavaScriptファイルsrc/script.js
を圧縮し、dest/script.js
というパスに保存します。
圧縮前
1
2
3
4
5
|
console.log("Hello World."); // コメント
/*
コメント
*/
let val = 1;
|
minify
関数を以下のように実行します。
1
|
minify("src/script.js", "dest/script.js")
|
圧縮後
コメントや改行は削除されます。
1
|
console.log("Hello World.");let val = 1;
|
フォルダ単位でまとめてminifyする
フォルダ内にあるHTML, CSS, JavaScriptをまとめてminifyすることを考えます。
src
フォルダに圧縮前のファイルがあり、ディレクトリの構造を保ったまま圧縮してdest
フォルダに保存するものとします(一般的にはsrc
フォルダが開発用、dest
フォルダが公開用になると思います)。
このときのPythonスクリプトを以下に示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import os
import shutil
src = "src"
dest = "dest"
for current_dir, sub_dirs, files_list in os.walk(src):
for subdir in sub_dirs:
os.makedirs(dest+"/"+subdir, exist_ok=True)
for file in files_list:
extention = file.split(".")[-1] # 拡張子
file_path = current_dir+"/"+file
if extention in ["html", "css", "js"]:
minify(file_path, file_path.replace(src, dest, 1))
else:
shutil.copy2(file_path, file_path.replace(src, dest, 1))
|
os.walk()
はフォルダ内のファイル名を再帰的に取得する関数です。
また、ファイルの拡張子を取得して、HTML, CSS, JavaScriptのみminifyします。
それ以外のファイル(画像など)はminifyせずに、shutil.copy2()
関数でコピーします。
まとめ
HTML, CSS, JavaScriptを圧縮 (minify) して、ファイル容量を削減するPythonスクリプトを作成しました。