Webassets
Webassets is a general, dependency-independent library for managing the assets of your web application, compatible with Python 3.10 and later. It efficiently merges and compresses CSS and JavaScript files, supports various filters, and integrates with compilers like CoffeeScript or Sass. The library currently stands at version 3.0.0 and has an active development cadence, with recent major updates.
Common errors
-
FilterError: sass: subprocess had error: stderr=(sass):1: File to import not found or unreadable: <file_name>
cause External filters like Sass often use standard input when applied to merged bundles, which can prevent them from resolving relative `@import` paths correctly.fixEnsure all imported files are directly accessible via `load_path` settings in your `Environment` or adjust your build process to pre-compile Sass files that use relative imports before `webassets` processes them. -
command not found: <filter_executable>
cause An external tool required by a filter (e.g., `uglifyjs`, `cleancss`, `tsc`) is not installed on the system or is not in the system's PATH.fixInstall the missing external tool (e.g., `npm install -g uglify-js` for UglifyJS) and verify its executable is available in your system's PATH. Alternatively, specify the full path to the executable in your `webassets` configuration (e.g., `env.config['UGLIFYJS_BIN'] = '/usr/local/bin/uglifyjs'`). -
404 Not Found for web assets like JS or CSS files
cause Incorrect `directory` or `url` configuration in the `Environment` instance, or issues with symlink resolution on the web server.fixVerify that `Environment.directory` points to the correct base directory where your static files reside, and `Environment.url` matches the URL prefix under which these assets are served by your web server. Check server configurations for symlink handling if applicable.
Warnings
- breaking Version 3.0.0 drops support for all Python versions earlier than 3.10.
- breaking The 'yui' compressor has been removed in version 3.0.0 due to being obsolete.
- gotcha Many `webassets` filters (e.g., for Sass, TypeScript, Closure Compiler, UglifyJS, Clean-css) require external command-line tools to be installed and accessible in your system's PATH, or explicitly configured via `Environment` settings.
- gotcha For robust cache busting and consistent asset URLs across deployments, use the `%(version)s` placeholder in the `output` filename of your `Bundle` rather than relying solely on the `url_expire` querystring.
Install
-
pip install webassets
Imports
- Environment
from webassets import Environment
- Bundle
from webassets import Bundle
Quickstart
import os
import shutil
from webassets import Environment, Bundle
# Define base directories and create dummy files for demonstration
base_dir = "webassets_quickstart_temp"
static_dir = os.path.join(base_dir, "static")
css_dir = os.path.join(static_dir, "css")
js_dir = os.path.join(static_dir, "js")
output_dir = os.path.join(static_dir, "gen")
os.makedirs(css_dir, exist_ok=True)
os.makedirs(js_dir, exist_ok=True)
os.makedirs(output_dir, exist_ok=True)
with open(os.path.join(css_dir, "style.css"), "w") as f:
f.write("body { font-family: sans-serif; }\n")
with open(os.path.join(js_dir, "main.js"), "w") as f:
f.write("console.log('Hello from main.js');\n")
with open(os.path.join(js_dir, "utils.js"), "w") as f:
f.write("function greet() { return 'Greetings!'; }\n")
# Initialize the Environment
# `directory` is the base path for source files and output
# `url` is the base URL from which assets are served in the browser
env = Environment(directory=static_dir, url='/static')
# Define a CSS bundle (no filters for simplicity in this quickstart)
css_bundle = Bundle(
'css/style.css',
output='gen/packed.css'
)
# Define a JavaScript bundle with an included filter (rjsmin)
js_bundle = Bundle(
'js/main.js',
'js/utils.js',
filters='rjsmin', # rjsmin is included with webassets
output='gen/packed.js'
)
# Register bundles with the environment
env.register('all_css', css_bundle)
env.register('all_js', js_bundle)
# Access the URLs in production mode (default behaviour: merges and applies filters)
print("CSS URLs (production mode):", env['all_css'].urls())
print("JS URLs (production mode):", env['all_js'].urls())
# Switch to debug mode to see individual source files (for development)
env.debug = True
print("\nCSS URLs (debug mode):", env['all_css'].urls())
print("JS URLs (debug mode):", env['all_js'].urls())
# Clean up dummy files and directories
shutil.rmtree(base_dir)