SystemJS needs some quite careful configuration, especially with Angular, and Wordpress plays around with paths quite a bit, so getting the three to play nicely is possible but fiddly. Here’s how I made it all work.
(These instructions are for “jspm”: “^0.16.10” (“systemjs”: “0.19.3”,), angular 1.x and wordpress 4.x)
In my Wordpress theme directory I ended up with the following file structure. My app has its source in
assets/app and the production code is compiled to
/ |- /lib |--- config.php |- /assets |--- /app |----- app.js |----- /services |--- /jspm_packages |--- config.js |--- loader.js |- /dist |- /node_modules |- gulpfile.js |- *.php,...
I want SystemJS to load all the necessary files automatically, and with no compilation during development.
The first trick is with
config.js where we need to use the full directory (relative to the wordpress root) as my
wp_enqueue_script to inject the relevant script(s) after doing a simple test of whether this is the development server or not.
loader.js is a very simple script:
This was the most confusing part of the whole exercise as I started getting bugs when I added / removed totally unrelated (e.g. jQuery) packages to my overall page. Turned out SystemJS affects the timing of page loading and can disrupt the conventional
ng-app directive used to load angular.
As a result, it is recommended to bootstrap Angular manually:
I started off trying to point to absolute Urls of templates, but subsequently switched to a template caching approach, with the templates compiled into a ‘standalone’ module that I could then ‘import’ from my main app.
The trick is that the
baseUrl needs to change for the bundle. This took me the longest to work out and here is the way I now use. The key line is where I call
Builder and override the
ng-annotate does not work out of the box with the bundle created by systemjs-builder, as it cannot find the functio calls that it needs to work on. But it is sufficient to add “ngInject” as the first line of the function / class body to help it.