Packaging JavaScript Libraries
Summary
- MUST: A package must not include JavaScript libraries that have a separate upstream. Those JavaScript libraries need to be packaged in a JavaScript library.
- MUST: A JavaScript library intended to be served via a web server must provide an apache config file that lets the library be served by apache. This file is placed in %{_sysconfdir}/js/ with a filename extension of *.conf. The config file must make the JavaScript library available at the URL http://localhost/js/LIBRARY
- MUST: Files from the JavaScript library must be placed in a subdirectory of %{_datadir}
Rationale
Duplication
We have a standard to avoid duplication of system libraries. This applies as much to JavaScript libraries as it does to C, python, Java, and any other programming language. The main concern is security. JavaScript code is not vulnerable to buffer overflows like C but it can be subject to attacks from malicious data that attempts to send the user to alternate web sites, steal their information, or execute code via jsonp requests to an alternate server. Duplicating third party libraries in an application leads to these problems sticking with an application even after the upstream library has fixed the issues and thus is prohibited.
There are also some JavaScript libraries which are intended to be used on the local system, not served via a web server to a browser. These libraries clearly have all the standard reasons to avoid duplication.
Licensing
It is common to see third-party applications consuming multiple JavaScript libraries. When all of these libraries are stuck in a directory, there is little information to tell what the relationship is between the files. This leads to problems when incompatible licenses are found. For instance, if Foo.js is licensed with Apache Software License-2.0, Bar.js and Baz.js licensed with LGPLv2+, and Qux.js with MIT we have to audit the code in Foo.js to determine what symbols are potentially being used in other files and then audit Bar.js and Baz.js to see if those symbols are being used there.
Having separate packages for each library makes diagnosing these problems much easier.
Potential Problems
Some JavaScript libraries change at a very fast rate and with no eye towards backwards compatibility. We may need to do more work forward porting applications to new versions.
At least one JavaScript library (mootools ) has a web form to customize and compress the library before downloading it. This can cause us headaches as it is encouraging frameworks to have their own local fork. One way to work around this might be to build it from the source repo so that each of the modules can be obtained as a separate file.
Default Location
URL
JavaScript libraries intended to be served up by a web server. JavaScript libraries must provide an apache conf file that will serve the library from the filesystem to clients.Config files for other web servers are optional. URLs for JavaScript libraries should be rooted in /js/.
- Note* not all javascript libraries are intended to be served by a web server. When the library is for local consumption only, they do not need to have an apache conf file.
Filesystem Locations
Config files for apache should be added to %{_sysconfdir}/js.d with a *.conf extension. Until this package is owned by a base package like filesystem, it should be owned by the package that places files there or one of that package's requirements. We'll either modify apache to source files in this directory by default or provide a shim package that adds that directory in future versions.
Note: An alternative to providing a .conf files for each js library would be to provide a single configuration in apache to load the standard javascript directory. This setup would require that javascript not intended to be served by apache be placed in a separate location.
The JavaScript library itself must reside in a subdirectory of %{_datadir}
"Compilation"
Note: This step is more properly called "Language rewriting"
JavaScript is an interpreted language so source is also runnable. However, since the server sends the JavaScript over the network to the client, several methods of making the code smaller (Pack, shrinksafe, yuicompressor, etc) have evolved. Some of these involve compression implemented in JavaScript while others involve removing extraneous whitespace and comments. ATM, no form of compilation is supported by Fedora but equally, no form of compilation is banned. If one form of compilation becomes prevalent or is in demand in the future we can reevaluate this.
Note: At the moment, we require having the uncompiled versions of the library alongside the compiled version. This is due to concerns about GPL requirements for distributing code in the preferred form for modification. If this is considered onerous we can revisit this at a later time.
Spec template
MochiKit is a current example of a well packaged JavaScript library. Beginnings of a spec template taken from there
Source1: %{name}.conf [...] %install mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name} install -p -m 0644 lib/MochiKit/* $RPM_BUILD_ROOT%{_datadir}/%{name} mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/httpd/js.d install -p -m 0644 %{SOURCE1} $RPM_BUILD_ROOT%{_sysconfdir}/js.d/ [...] %files %defattr(-,root,root,-) %doc Changes doc examples LICENSE.txt %{_datadir}/%{name} %config(noreplace) %{_sysconfdir}/js.d/%{name}.conf