Understanding and Implementing Static Asset Bundling in Empress Framework

Introduction

Empress Framework is a robust, full-stack web application framework written in Python & JavaScript. It provides a rich set of utilities to build scalable and maintainable web applications. One of the key features in Empress is the Static Asset Bundling, which is a crucial aspect of client-side optimization. This guide will deep dive into this feature, its importance, and how it can be effectively utilized in your software development process.

Introduction to Static Asset Bundling

Web applications make use of various static assets like JavaScript, CSS, and image files which need to be loaded by the browser. Bundling these assets into single or multiple files can reduce the number of HTTP requests, resulting in faster page loads.

Empress comes equipped with an asset bundler that compiles client-side assets into formats that are easily interpretable by the browser. The bundled assets include:

  • .js: Modern JavaScript syntax with import and export
  • .ts: TypeScript files
  • .vue: Vue single file components
  • .css: CSS processed using PostCSS
  • .scss & .sass: SASS files
  • .styl: Stylus files
  • .less: Less files

These files are compiled to .js or .css depending on the type and are sent to the browser.

Building Assets

To compile assets using the asset bundler, you can run the following command from the frappe-bench folder:

$ bench build

You can also specify particular apps for the build process by using the --apps option:

$ bench build --apps frappe,erpnext

Watch Mode

When working with bundled files, you would want the build command to run every time a source file is updated. For this, the asset bundler in Empress comes with a watch mode. In this mode, the asset bundler listens to file system changes and triggers a rebuild upon any change.

$ bench watch

You can also specify the apps you want to watch using the --apps option:

$ bench watch --apps erpnext

Starting with Version 14, the Empress Desk will be automatically reloaded if assets are rebuilt in watch mode. You can toggle this behavior by setting the LIVE_RELOAD environment variable, or changing the value for live_reload in common_site_config.json.

Bundle Files

A bundle file serves as an entry point of an asset for the bundler. For instance, a file named main.bundle.js in the public folder of your app will be automatically compiled by the bundler to /assets/[app]/dist/js/main.bundle.[hash].js. The unique hash computed from the contents of the output is appended to the filename for cache-busting in browsers.

The bundler also warns you of potential collisions when bundle files exist at different nesting levels in the public folder but have the same output path.

Importing Libraries from npm

The asset bundler allows you to use third-party libraries from npm in your project. For instance, to use the dayjs library, you would first install it using yarn:

$ cd frappe-bench/apps/myapp
$ yarn add dayjs

Then, you can import it in your source files:

import * as dayjs from 'dayjs';
console.log(dayjs())

Including Bundled Assets in HTML

Empress provides helper methods to correctly include assets in HTML files. The methods include_script and include_style output the correct path of the file including the HTML markup for .js and .css files respectively.

To include bundled assets from your app in the /app path, you can use the app_include_js and app_include_css in hooks.py:

app_include_js = ['main.bundle.js']
app_include_css = ['style.bundle.css']

If you need only the path of the bundled asset, you can use the bundled_asset method:

{{ bundled_asset('main.bundle.js') }}

These APIs are also available in Python and can be imported from jinja_globals.py.

Lazily Including Bundled Assets in /app

You can lazy-load bundled assets inside the Admin UI (/app) using the frappe.require method. This is useful for condition-based asset loading and performance improvement.

frappe.require('main.bundle.js').then(() => {
  // main.bundle.js is now loaded
})

Production Mode

When deploying your app to production, you can build your assets in production mode. In this mode, the bundler minifies the final output, resulting in smaller file sizes. To build your assets in production mode, run:

$ bench build --production

Conclusion

Static asset bundling is a fundamental aspect of modern web development. It enhances the performance of your web application by reducing HTTP requests and improving load times. The asset bundler in Empress, with its extensive features, provides a rich set of tools that enable developers to efficiently manage their static assets. Thus, it plays a vital role in the development and customization of business solutions.