4.4 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	Static asset pipeline
This page documents additional information that may be useful when developing new features for Zulip that require front-end changes, especially those that involve adding new files. For a more general overview, see the new feature tutorial.
Primary build process
Most of the existing JS in Zulip is written in IIFE-wrapped modules,
one per file in the static/js directory.  When running Zulip in
development mode, each file is loaded separately, to make reloading
nice and efficient.  In production mode (and when creating a release
tarball using tools/build-release-tarball), JavaScript files are
concatenated and minified.  We use the
django pipeline extension
to manage our static assets.
Adding static files
To add a static file to the app (JavaScript, CSS, images, etc), first
add it to the appropriate place under static/.
- Third-party files that we haven't patched should be installed via
npm, so that it's easy to upgrade them and third-party code doesn't bloat the Zulip repository. You can then access them inJS_SPECSvia their paths undernode_modules(technically,static/node_modules, but the static is automatically appended). You'll want to add these to thepackage.jsonin the root of the repository, and then provision (to havenpmdownload them) before continuing. Your commit should also updatePROVISION_VERSIONinversion.py. - Third-party files that we have patched should all go in
static/third/. Tag the commit with "[third]" when adding or modifying a third-party package. Our goal is to the extent possible to eliminate patched third-party code from the project. - Our own JavaScript lives under 
static/js; CSS lives understatic/styles. Portico JavaScript ("portico" means for logged-out pages) lives understatic/js/portico. 
After you add a new JavaScript file, it needs to be specified in the
JS_SPECS dictionary defined in zproject/settings.py to be included
in the concatenated file; this will magically ensure it is available
both in development and production.  Similarly, CSS should be added to
the STYLESHEETS section of PIPELINE in zproject/settings.py.  A
few notes on doing this:
- If you plan to only use the JS/CSS within the app proper, and not on
the login page or other standalone pages, put it in the 
appbundle. - If you plan to use it in both, put it in the 
commonbundle. - If it's just used on a single standalone page (e.g. 
/stats), give it its own bundle. To load a bundle in the relevant Jinja2 template for that page, useminified_jsandstylesheetfor JS and CSS, respectively. 
If you want to test minified files in development, look for the
PIPELINE_ENABLED = line in zproject/settings.py and set it to True
-- or just set DEBUG = False.
Note that static/html/{400,5xx}.html will only render properly if
minification is enabled, since they, by nature, hardcode the path
static/min/portico.css.
Experimental Webpack/CommonJS modules
This section is experimental and largely irrelevant unless you're interested in helping migrate Zulip to a more modern static asset pipeline.
New JS written for Zulip can be written as CommonJS modules (bundled
using webpack, though this will be taken care
of automatically whenever run-dev.py is running). (CommonJS is the
same module format that Node uses, so see the Node
documentation for
more information on the syntax.)
Benefits of using CommonJS modules over the IIFE module approach:
- namespacing/module boilerplate will be added automatically in the bundling process
 - dependencies between modules are more explicit and easier to trace
 - no separate list of JS files needs to be maintained for concatenation and minification
 - third-party libraries can be more easily installed/versioned using npm
 - running the same code in the browser and in Node for testing is simplified (as both environments use the same module syntax)
 
The entry point file for the bundle generated by webpack is
static/js/src/main.js. Any modules you add will need to be required
from this file (or one of its dependencies) in order to be included in
the script bundle.