Compiling SCSS to CSS

Minifying static assets and compiling SCSS to CSS with Python

Using the sass, rcssmin and rjsmin Python packages to optimize web assets, including Bootstrap

I wanted a way to minify JS and CSS files, along with compile SCSS to CSS, without messing around with NPM or YARN.

Also, I didn't want to bake it into the application, rather just a simple script that can be ran from the command line.

libsass

Python scss to css compiler:

pip install libsass

rcssmin

Python CSS minifier:

pip install rcssmin

rjsmin

Python JavaScript minifier:

pip install rjsmin

Example app structure

Most of the Bootstrap scss files have been omitted for illustration.

base
├── app
│   ├── __init__.py
│   ├── static
│   │   ├── css
│   │   │   ├── style.css
│   │   │   ├── style.css.map
│   │   │   └── style.min.css
│   │   ├── js
│   │   │   ├── app.js
│   │   │   ├── app.min.js
│   │   └── scss
│   │       ├── bootstrap
│   │       │   ├── bootstrap.scss
│   │       │   ├── mixins
│   │       │   │   ├── _alert.scss
│   │       │   ├── utilities
│   │       │   │   ├── _align.scss
│   │       │   └── vendor
│   │       │       └── _rfs.scss
│   │       ├── custom
│   │       │   └── custom.scss
│   │       └── style.scss
│   ├── templates
│   │   └── index.html
│   └── views.py
├── run.py
└── runner.py
  • All scss imports are declared in style.scss

Example usage with Flask

A simple script that compiles and minifies the files:

runner.py

import rcssmin
import rjsmin
import sass

"""
This script does 3 things:
    - Compiles scss to css
    - Minifies css
    - Minifies JavaScript
"""

# Map scss source files to css destination files
sass_map = {"app/static/scss/style.scss": "app/static/css/style.css"}

# Map un-minified css source files to minified css destination files
css_map = {"app/static/css/style.css": "app/static/css/style.min.css"}

# Map un-minified JavaScript source files to minified JavaScript destination files
js_map = {"app/static/js/app.js": "app/static/js/app.min.js"}


def compile_sass_to_css(sass_map):

    print("Compiling scss to css:")

    for source, dest in sass_map.items():
        with open(dest, "w") as outfile:
            outfile.write(sass.compile(filename=source))
        print(f"{source} compiled to {dest}")


def minify_css(css_map):

    print("Minifying css files:")

    for source, dest in css_map.items():
        with open(source, "r") as infile:
            with open(dest, "w") as outfile:
                outfile.write(rcssmin.cssmin(infile.read()))
        print(f"{source} minified to {dest}")


def minify_javascript(js_map):

    print("Minifying JavaScript files:")

    for source, dest in js_map.items():
        with open(source, "r") as infile:
            with open(dest, "w") as outfile:
                outfile.write(rjsmin.jsmin(infile.read()))
        print(f"{source} minified to {dest}")


if __name__ == "__main__":
    print()
    print("Starting runner")
    print("--------------------")
    compile_sass_to_css(sass_map)
    print("--------------------")
    minify_css(css_map)
    print("--------------------")
    minify_javascript(js_map)
    print("--------------------")
    print("Done")
    print()

Running this file from the base directory:

python runner.py

Output

Expected output:

Starting runner
--------------------
Compiling scss to css:
app/static/scss/style.scss compiled to app/static/css/style.css
--------------------
Minifying css files:
app/static/css/style.css minified to app/static/css/style.min.css
--------------------
Minifying JavaScript files:
app/static/js/app.js minified to app/static/js/app.min.js
--------------------
Done

HTML

Using the CSS & JS in an HTML/Jinja template:

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <link rel="stylesheet" href="{{ url_for('static', filename='css/style.min.css') }}">

  <title>Hello, world!</title>
</head>

<body>

  <div class="container mt-3">
    <div class="row">
      <div class="col">
        <h5>Hello world</h5>
        <div class="card">
          <div class="card-body">
            <h5>Card</h5>
          </div>
        </div>
      </div>
    </div>
  </div>

  <script src="{{ url_for('static', filename='js/jquery/jquery-3.4.0.min.js') }}"></script>
  <script src="{{ url_for('static', filename='js/popper/popper-1.15.0.min.js') }}"></script>
  <script src="{{ url_for('static', filename='js/bootstrap/bootstrap.min.js') }}"></script>
  <script src="{{ url_for('static', filename='js/app.min.js') }}"></script>
</body>

</html>

Resources:

Last modified · 18 Apr 2019 Reference : https://pythonise.com/categories/python/python-minify-js-css-compile-scss

Last updated