JavaScript and Python back-endMax Klymyshyn
oDesk PS
Twitter: @maxmaxmaxmaxGithub: joymax
Sources:goo.gl/zbtXH
1Saturday, March 24, 12
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
The solution
Add Assets Management tools to the project
Define and follow conventions
3Saturday, March 24, 12
TOCProject Structure
Assets management
JavaScript Templates
Constants within JS files
Browser-specific assets
SCSS/LESS
4Saturday, March 24, 12
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
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
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
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
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
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
Constants within JavaScript Configuration file looks like:
...
_.defaults(config, { 'api_url': '$$API_URL', 'title': '$$TITLE' });
window.KHARKIVPY.config = config;
11Saturday, March 24, 12
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
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
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
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
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
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
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
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
Questions?
20Saturday, March 24, 12
21Saturday, March 24, 12