21
JavaScript and Python back-end Max Klymyshyn oDesk PS Twitter: @maxmaxmaxmax Github: joymax Sources: goo.gl/zbtXH 1 Saturday, March 24, 12

Kharkivpy#3: Javascript and Python backend

Embed Size (px)

DESCRIPTION

Kharkivpy#3: Javascript and Python backend

Citation preview

Page 1: Kharkivpy#3: Javascript and Python backend

JavaScript and Python back-endMax Klymyshyn

oDesk PS

Twitter: @maxmaxmaxmaxGithub: joymax

Sources:goo.gl/zbtXH

1Saturday, March 24, 12

Page 2: Kharkivpy#3: Javascript and Python backend

The problem

JavaScript code grew up on the Project

Optimization of the Application become the pain in the ass

Hard to manage dependencies and test updates

2Saturday, March 24, 12

Page 3: Kharkivpy#3: Javascript and Python backend

The solution

Add Assets Management tools to the project

Define and follow conventions

3Saturday, March 24, 12

Page 4: Kharkivpy#3: Javascript and Python backend

TOCProject Structure

Assets management

JavaScript Templates

Constants within JS files

Browser-specific assets

SCSS/LESS

4Saturday, March 24, 12

Page 5: Kharkivpy#3: Javascript and Python backend

Note

This presentation based on Flask but it's possible to use Django or any other framework which supported by Webassets

5Saturday, March 24, 12

Page 6: Kharkivpy#3: Javascript and Python backend

Project structure• app.py• assets.py

• templates• base.html

• bundles• browsers.py• jstemplates.py• scss_bundle.py• vars.py

• static• src

• js• css

• js• css

6Saturday, March 24, 12

Page 7: Kharkivpy#3: Javascript and Python backend

Assets management

core = Bundle( "src/js/lib/core/*.js", "src/js/lib/*.js", output="core.js")

assets.register("js_core", core)

7Saturday, March 24, 12

Page 8: Kharkivpy#3: Javascript and Python backend

JavaScript Templates var %(namespace)s = %(namespace)s || {}; %(namespace)s._assign = function (obj, keyPath, value) { var lastKeyIndex = keyPath.length - 1; for (var i = 0; i < lastKeyIndex; i++) { key = keyPath[i]; if (typeof obj[key] === "undefined") { obj[key] = {}; } obj = obj[key]; } obj[keyPath[lastKeyIndex]] = value; }; (function(){

// ... here should be templates definitions})();

8Saturday, March 24, 12

Page 9: Kharkivpy#3: Javascript and Python backend

JavaScript templates

templates = ( 'system/*.tpl', 'views/main/*.tpl', 'views/group/*.tpl', 'views/rate/*.tpl', 'views/search/*.tpl', 'views/sort/*.tpl', 'views/progress/*.tpl', 'views/sidebar/listings/*.tpl', 'views/sidebar/search/*.tpl', )

9Saturday, March 24, 12

Page 10: Kharkivpy#3: Javascript and Python backend

Constants within JavaScript def constants(app): cfg = {} with app.test_request_context(): cfg.update(dict( API_URL=url_for("api", _external=True), TITLE="Sample Widget" )) return cfg

conf_app = JSVarsBundle("src/js/conf/main.js", output="js/compiled/conf/conf.js", vars=constants(app), filters=[“yui_js”], ignore_filters=assets.debug)

10Saturday, March 24, 12

Page 11: Kharkivpy#3: Javascript and Python backend

Constants within JavaScript Configuration file looks like:

...

_.defaults(config, { 'api_url': '$$API_URL', 'title': '$$TITLE' });

window.KHARKIVPY.config = config;

11Saturday, March 24, 12

Page 12: Kharkivpy#3: Javascript and Python backend

Browser-specific assets

We need to load custom assets for different browsers

We don’t have ability to use conditional commends for IEs (business requirement)

12Saturday, March 24, 12

Page 13: Kharkivpy#3: Javascript and Python backend

Browser-specific assets chrome17 = BrowserBundle( 'src/css/browsers/chrome17.css', browser='Chrome', browser_version='17', output='css/chrome17.css' )... browserspec_assets_loader = LoaderBrowserBundle( 'src/css/browsers/safari5.css', # dirty hack, we’ll change it bundles=[chrome17, safari5], filters='loader_browser', output='js/compiled/assets-loader.js' )

assets.register("browserspec_assets_loader",browserspec_assets_loader)

13Saturday, March 24, 12

Page 14: Kharkivpy#3: Javascript and Python backend

Browser-specific assetsBelow is generated snippet by webassets bundle:

(function (assets) { BrowserAssets('/static/', assets);})({'Chrome': {

'17': ['src/css/browsers/chrome17.css']}, 'Safari': {

'5.1': ['src/css/browsers/safari5.css']}});

14Saturday, March 24, 12

Page 15: Kharkivpy#3: Javascript and Python backend

SCSS/LESS

It was painful to maintain raw CSS for complex public widget

We declined to use LESS because we aren’t found good and maintainable LESS compiler for Python

We decided to not use client-side LESS parser to avoid possible conflicts with client’s code

15Saturday, March 24, 12

Page 16: Kharkivpy#3: Javascript and Python backend

SCSS/LESSstyle_files = ( 'reset.scss', 'base.scss',)

register_scss_bundle( style_files, assets=assets, name='css_core', output='css/style.css', prefix='src/css', compile_to='css/compiled')

16Saturday, March 24, 12

Page 17: Kharkivpy#3: Javascript and Python backend

CDN (Amazon CloudFront)

Sometimes back-end server goes down

Clients and partners may experience really weird behavior and look of the Widget when back-end not available

No one want to loose face in front of the client

17Saturday, March 24, 12

Page 18: Kharkivpy#3: Javascript and Python backend

CDN (Amazon CloudFront)

All of static related to the Widget hosted on Amazon CloudFront

In case back-end goes down for maintenance or because of failure JavaScript display nice error

Widget still looks like it should

18Saturday, March 24, 12

Page 19: Kharkivpy#3: Javascript and Python backend

CDN Pitfalls

Amazon CloudFront may update your files REALLY SLOW

It may take up to 24 hrs to spread updates to all CDN nodes around the world

You may experience hard time with your product owner

CDN is for really patient clients

19Saturday, March 24, 12

Page 20: Kharkivpy#3: Javascript and Python backend

Questions?

20Saturday, March 24, 12

Page 21: Kharkivpy#3: Javascript and Python backend

21Saturday, March 24, 12