Javascript Library Maintenance - WheatonCS/Lexos GitHub Wiki
Javascript libraries are external libraries which can be downloaded from repositories or content delivery networks (CDN) around the web. Typically, it is advisable to have Lexos download common libraries on the fly since the browser is likely to have cached them and may not need be loaded, making loading times faster. That's the theory, anyway. However, these libraries may not be available if the user does not have an internet connection, or they may load slowly if the internet connection is slow. For this, Lexos has LOCAL_MODE
, which can be set to True
in Lexos/config.cfg
. This will load all assets from local copies.
- Maintaining Javascript Libraries in the Lexos Repository
- Updating Libraries
- Deploying the Libraries
- Proposal: Speeding Up Performance with Webassets
All external Javascript libraries are located in the static/node_modules
folder. They are committed to the Lexos repository using npm
, which you need to download in order to install them. The easiest way to do this is to download node.js
, which comes with npm
. After you download and install node.js
, use the command npm install npm@latest -g
to ensure that you have the latest version of npm
. Finally, use the following commands to install the Javascript libraries:
cd Lexos/lexos/static
npm install
The command npm install
combines all the separate installation commands for each Javascript library. Further information is available in the Library Maintenance Guide.
It is frequently be necessary to update package versions to patch security vulnerabilities flagged by GitHub. To update a package, cd
to the parent directory of node modules
and run npm install <package_name>@latest
. This will update package.json
and package_lock.json
. Push these files to GitHub, and the update will be complete.
Once you have installed all the Javascript libraries, they can be accessed from the Flask template files with
<script type="text/javascript" src="{{ url_for('static', filename='node_modules/path_to_javascript_file.js') }}?ver={{version}}"></script>
If the library is available from a CDN, a conditional may be added to tell Flask to use that resource when it is not in local mode. This can be done as follows:
{% if config['LOCAL_MODE'] == True %}
<script type="text/javascript" src="{{ url_for('static', filename='node_modules/path_to_javascript_file.js') }}?ver={{version}}"></script>
{% else %}
<script type="text/javascript" src="url_of_cdn"></script>
{% endif %}
Webassets is a Python library for bundling Javascript and CSS assets together so that they can be loaded all at once from a minimised file. In theory, this should speed up loading times when Lexos is in local mode. I suspect that it is also faster than loading from CDN, even if some libraries like jQuery are cached. There is a Flask integration called Flask-Assets, and using it will also provides cleaner code in the template files since the entire bundle can be loaded in a single call:
{% assets "js_all" %}
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}
CSS files can also be bundled, simplifying the template files considerably. The downside is that this introduces another dependency (Flask-Assets
) to Lexos. Webassets does provide a few bells and whistles such as minimising the code and providing a debug mode which can switch to loading each resource individually.
DataTables is the one library that presents some more complex deployment decisions. The DataTables website allows you to construct a single url that will automatically load all the modules Lexos requires. This is extremely convenient. By contrast, if DataTables is loaded locally, separate calls must be made to each module. DataTables also makes use of a few extensions that cannot be installed with npm
. As a result, we have placed them in the static/js
folder, and they can be called from there. Bundling with webassets provides a solution to these issues.
If we choose to deploy resources with webassets, we should seriously consider whether it is worth loading resources from CDN even when local mode is turned off.