Search code examples
flaskbabeljsflask-assetswebassets

How to minify ES2016 or convert to ES2015 in flask?


I'm using flask-assets and none of the available filters (rjsmin, jsmin, closure_js, uglifyjs, etc.) is able to minify a ES2016 JavaScript file. The minified files yield errors on the browser console (due to bad conversions) or even crash on execution before serving the resources. Also, I have tried Babel filter from webassets and I it doesn't make any change on the files, they are just served without changes.

I also can't manage to enforce the closure or babel extra_args to customise their operation.

Any tip or recommendation?

Example code:

from flask_assets import Bundle
page_js = Bundle(
    'js/code_with_es2016.js',
    filters='rjsmin',
    output='public/js/code.min.js'
)

Solution

  • You will need to use the babel filter with babel-presets-env. The webassets documentation is a bit behind on the recent developments which is no surprise considering how fast things are moving in the javascript world.

    So first you will need to install babel-cli globally:

    npm install -g babel-cli
    

    Now you will need to install babel-preset-env locally, so within your project directory do:

    npm install --save babel-preset-env
    

    Finally this is how to set up your bundle with flask-assets:

    from flask_assets import Bundle, Environment
    from webassets.filter import get_filter
    
    assets = Environment()
    assets.init_app(app)
    babel = get_filter('babel', presets='babel-preset-env')
    assets.register('js_all', Bundle(
        'js/code_with_es2016.js',
        output='public/js/code.min.js',
        filters=[babel, 'rjsmin']
    ))
    
    

    You can also tell babel where your babel-preset-env is installed by specifying the absolute or relative path to it:

    preset_location = './path/to/node_modules/babel-preset-env'
    babel = get_filter('babel', presets=preset_location)
    assets.register('js_all', Bundle(
        'js/code_with_es2016.js',
        output='public/js/code.min.js',
        filters=[babel, 'rjsmin']
    ))
    

    And one last thing, and this is only (like) my opinion, I would highly recommend switching over to javascript/node based build process for your frontend assets (you are using babel already!). Depending on what you are developing gulp or webpack can be good candidates to use for your frontend build. Flask-assets/webassets just seem unnecessary because they're lagging behind with docs and package versions of whatever the latest and greatest in the frontend world is.