Angular.JS optimizations for Optimus.
Add to :dependencies
in your project.clj
:
[optimus "2023-02-08"]
[optimus-angular "2023-02-08"]
This project offers two distinct features. It helps you:
- Prepopulate the Angular.JS template cache.
- Prepare JavaScript for minification with ng-annotate.
Both features work with Optimus,
or any other asset serving framework that uses the same data structure
for asset representation: [{:path :contents}]
optimus-angular/create-template-cache
is a custom Optimus asset
loader. It creates a virtual JavaScript asset that populates the
Angular.JS template cache with your given templates.
Here's an example usage:
(ns my-app.example
(require [optimus.assets :as assets]
[optimus-angular.core :as optimus-angular]))
(defn get-assets [] ;; 1
(concat
(assets/load-bundles "public" my-bundles) ;; 1
[(optimus-angular.templates/create-template-cache ;; 2
:path "/templates/angular.js" ;; 3
:module "MYAPP" ;; 4
:templates (assets/load-assets "public" ;; 5
["/angular/templates/home.html"
"/angular/templates/form.html"
"/angular/templates/list.html"]))]))
-
You create the template cache in your
get-assets
function along with your other assets. -
Notice that
create-template-cache
creates a single asset, so it's in a vector to concat with the other assets . -
You use the
:path
to reference the virtual asset when linking. -
The name of your Angular module.
-
It takes a list of assets to include in the cache. These could be virtual too, like if you're creating your HTML with hiccup.
So, it creates a file /templates/angular.js
that inlines the templates
and adds them to the $templateCache
.
You link to this script with:
(optimus/file-path request "/templates/angular.js")
Or let's say you have a bundle named app.js
. You can add a :bundle "app.js"
pair to the create-template-cache
call, and the file will
be bundled together with the rest of the javascript files in
/bundles/app.js
. Nifty.
Dear me, no. That would be a chore. Optimus' load-assets
supports
regex to pick up files on the class path:
(assets/load-assets "public" [#"/angular/templates/.+\.html$"])
When minifying JavaScript, local variable names are changed to be just one letter. This reduces file size, but disrupts some libraries that use clever reflection tricks - like Angular.JS.
By transforming your assets with
optimus-angular/prepare-for-minification
, these reflection tricks
are replaced by an alternate syntax that still functions after
mangling of local names.
Make sure to insert this asset transformation earlier in the stack than the js-minifier. This would be a good way of doing it:
(defn my-optimize [assets options]
(-> assets
(optimus-angular/prepare-for-minification)
(optimus.optimizations/all options)))
This will change code like this:
angular.module('my-app').controller('MyCtrl', function ($scope, $http) {});
into code like this:
angular.module('my-app').controller('MyCtrl', [
'$scope', '$http', function ($scope, $http) {}
]);
which can be safely minified. There are limitations tho. Optimus-angular uses ng-annotate to do this job. Please read more about how it works in the ng-annotate README.
- Switch from ngmin to ng-annotate
- Add Last-Modified headers to template asset
Yes, please do!
You need npm installed to fetch the JavaScript dependencies. The actual fetching is automated however.
lein midje
will run all tests.
lein midje namespace.*
will run only tests beginning with "namespace.".
lein midje :autotest
will run all the tests indefinitely. It sets up a
watcher on the code files. If they change, only the relevant tests will be
run again.
Copyright © 2013 Magnar Sveen
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.