JavaScriptを有効にしてください

HTML, CSS, JavaScriptを圧縮 (minify) するPythonスクリプト

 ·   4 min read

はじめに

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")

圧縮後

コメントや改行、余分なスペースは削除されます。

1
.main{padding:10px;}

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スクリプトを作成しました。

シェアする

Helve
WRITTEN BY
Helve
関西在住、電機メーカ勤務のエンジニア。Twitterで新着記事を配信中です

サイト内検索