{"id":1510,"date":"2015-01-19T16:48:27","date_gmt":"2015-01-19T15:48:27","guid":{"rendered":"http:\/\/blog.gocept.com\/?p=1510"},"modified":"2015-02-26T07:14:23","modified_gmt":"2015-02-26T06:14:23","slug":"manage-javascript-dependencies-with-fanstatic","status":"publish","type":"post","link":"https:\/\/blog.gocept.com\/2015\/01\/19\/manage-javascript-dependencies-with-fanstatic\/","title":{"rendered":"Manage JavaScript dependencies with Fanstatic"},"content":{"rendered":"
Until the beginning of this year, we were using Fanstatic<\/a> to manage dependencies to external JavaScript libraries. In case you are not familiar with Fanstatic, here is a short overview. I will discuss benefits and drawbacks later on.<\/p>\n Imagine you want to use jQuery<\/a> in one of your projects. Therefore you build an integration package, say To finish up, you state the version of the downloaded After wrapping your app with Fanstatic, you can declare JavaScript dependencies by listing the integration package inside your Every time you call With Fanstatic you no longer need to copy the JavaScript files inside your project and link them statically, you just declare them as a dependency to your own JavaScript code and call The preparation described above can be tedious, but the assumption is, that someone else has built the integration package before, so you can reuse it. Installing a dependency therefore is as easy as adding a line to your Fanstatic makes it a lot easier to update external libraries, since you only need to increase the version number in your And besides many small nice features, Fanstatic can also create bundles, i.e. it will merge Despite all the benefits Fanstatic offers, we were getting more and more frustrated with it. The main reason is, that we feel a decline in the activity of the Fanstatic user group. With fewer people using Fanstatic, we often have to build the integration packages ourselves. This eliminates one of the main benefits, i.e. that we could reuse the integration packages of others.<\/p>\n For example, in a big project we did last year, we used integration packages for js.jquery<\/a>, js.classy<\/a>, js.chosen<\/a> and many more. Those are pretty popular packages and the integration worked out of the box.<\/p>\n However, even those packages have issues: The integration package for jQuery does not offer version 2.0 or higher and Chosen is only available in a single (outdated) version. We often stumbled upon similar issues with other libraries, e.g. the integration package for js.modernizr<\/a> is more than 2 years behind.<\/p>\n In addition, some newly developed libraries may not be available at all. Of course we could write the integration packages for those or update the jQuery integration package. But this would mean to find out where the code for an integration package is hosted, write a pull request and wait for a merge, as well as a new release on PyPI. In case the owner is not active anymore, you are out of luck and must add a duplicate package to PyPI. Tedious and unsatisfactory.<\/p>\n This is why we started to look for an alternative to Fanstatic. And maybe we have found it, but this is a story for another day, where I will talk about our experiences with Bower<\/a> and Bowerstatic<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"How it works<\/h2>\n
js.jquery<\/code>, which contains the
jquery.js<\/code> file. You also add a
resource.py<\/code> which would look like this:<\/p>\n
from fanstatic import Library, Resource\r\n\r\nlibrary = Library('jquery', 'resources')\r\njquery = Resource(library, 'jquery.js', minified='jquery.min.js')\r\n<\/pre>\n
jquery.js<\/code> in the
setup.py<\/code> and upload the package to PyPI<\/a>.<\/p>\n
setup.py<\/code>. To use them, you write
js.jquery.need()<\/code> inside any view. Of course you can also add a
resource.py<\/code> and declare a local resource with dependencies:<\/p>\n
import fanstatic\r\nimport js.jquery\r\n\r\nlibrary = fanstatic.Library('custom', 'resources')\r\nmy_awesome_js_code = fanstatic.Resource(\r\n library, 'js\/my_awesome_js_code.js',\r\n minified='js\/my_awesome_js_code.min.js',\r\n depends=[js.jquery.jquery])\r\n<\/pre>\n
my_awesome_js_code.need()<\/code> inside a view, it will also load jQuery.<\/p>\n
Benefits<\/h2>\n
my_awesome_js_code.need()<\/code> inside a view.<\/p>\n
setup.py<\/code> and declare it as a dependency of one of your resources.<\/p>\n
setup.py<\/code>. You can also make sure to use the same version across many projects, e.g. by sharing some buildout configuration across projects.<\/p>\n
my_awesome_js_code<\/code> and all of its dependencies into one big file and deliver it to the client, rather delivering all files separately. This usually makes the initial page load much faster.<\/p>\n
Drawbacks<\/h2>\n