single-spa-angularjs
single-spa-angularjs is a helper library that helps implement single-spa registered application lifecycle functions (bootstrap, mount and unmount) for use with AngularJS. Check out the single-spa-angularjs github.
#
InstallationNote that you can alternatively <script src="https://cdn.jsdelivr.net/npm/single-spa-angularjs@<VERSION>/lib/single-spa-angularjs.js
and access the library
via the window.singleSpaAngularjs.default()
global function if that is easier for you.
#
With a bundlerIf you're using a bundler such as webpack, add the following to your entry file:
#
Without a bundlerIf you're not using a bundler, you'll need to make your angularjs application a SystemJS module or a global variable. The SystemJS module is preferred, and you can read about it more in the recommended single-spa setup.
#
As a SystemJS moduleAdd the following to your AngularJS application. If you're using gulp/grunt to concatenate files together, just create a new file called
single-spa-application.js
and make sure it's included in your final build file.
Once you do this, you can System.import()
the bundle file and SystemJS + single-spa will know what to do with your module. Your
loading function should be System.import('name-of-app')
. Make sure to
add name-of-app
to your import map.
#
As a global variableYour loading function should just be the global variable itself. For example:
#
OptionsAll options are passed to single-spa-angularjs via the opts
parameter when calling singleSpaAngularJS(opts)
. The following options are available:
angular
: (required) The main angular object, which is generally either exposed onto the window or is available viarequire('angular')
orimport angular from 'angular'
.domElementGetter
: (optional) A function that takes in theprops
parameter and returns a DOMElement. This dom element is where the angular application will be bootstrapped, mounted, and unmounted. If not provided, the default is to create a div and append it todocument.body
.mainAngularModule
: (required) A string that is the name of the angular module that will be bootstrapped by angular. See angular docs forangular.bootstrap()
.uiRouter
: (optional) If you are using angular-ui-router, set this option to eithertrue
or to a string value. The string value will be the value of the ui-view HTML attribute. For example,uiRouter: 'core'
will be<div ui-view="core" />
whereasuiRouter: true
turns into<div ui-view />
.ngRoute
: (optional) If you are using ngRoute, set this option totrue
to have an<ng-view>
element automatically injected into the DOM during mount.preserveGlobal
: (optional) A boolean that defaults to false. Set if you want to keep angular on the global even after an app unmounts.elementId
: (optional) A string which will be used to identify the element appended to the DOM and bootstrapped by Angular.strictDi
: (optional - part of the bootstrap config object) A boolean that defaults to false. Set if you want to enable StrictDi modetemplate
: (optional) An HTML string that will be inserted into the DOM when the app is mounted. The template goes inside of the element returned by domElementGetter. If not provided, no template will be inserted. When using angular-ui-router, you often do not need to use this since ui-router will be putting a template onto the dom for you.
#
Custom Propssingle-spa custom props are made available as $rootScope.singleSpaProps
. In templates, you can access custom props via $root.singleSpaProps
. For example:
#
Parcels#
Creating AngularJS parcelsThe singleSpaAngularJs()
function returns an object that can serve as either a single-spa application or single-spa parcel.
#
Rendering parcels in AngularJSTo render a single-spa parcel inside of your AngularJS application, you can use the <single-spa-parcel>
directive. To do so, first add the "single-spa-angularjs"
module as a dependency of your application:
Then you can use the <single-spa-parcel>
directive in your templates:
In your controller, set the corresponding values on the $scope:
If you run into issues related to singleSpaProps
not being available for injection, this is likely caused by using <single-spa-parcel>
outside of a single-spa application or parcel. It is okay to do so, but you'll need to manually provide the singleSpaProps
value:
#
MigratingMigrating an existing AngularJS application to single-spa can be a tricky. Here are some recommendations.
#
High level approach- Convert the angularjs application to be a single-spa application via global variables.
- Switch the angularjs application from being a global variable to being SystemJS in-browser module.
- Add a new single-spa application (doesn't need to be angularjs)
#
Step 1: Convert to global variable- Load single-spa and single-spa-angularjs as global variables in your main HTML file:
- Change your angularjs application to not mount to the DOM. This is generally done removing the
ng-app
attribute in your main html file. - In one of the first / main scripts loaded for your angularjs application, create your single-spa application as a global variable. See this code.
- In your main HTML file, add the following:
- Confirm that your application now is mounting again and works properly. Also, check that it's in
MOUNTED
status as a single-spa microfrontend:
#
Step 2: Convert to SystemJS module:This step is not required unless you want to do cross microfrontend imports between your angularjs microfrontend and other microfrontends.
- Add systemjs to your index.html file:
- Remove the global single-spa script:
Modify your main / first angularjs script file to create a systemjs module instead of global variable. See this code.
Remove the
<script>
for loading that main / first angularjs script file. Replace it with a System.import.
- Modify the
<script>
in your main HTML file to load the angularjs app as a systemjs module instead of global variable:
- Verify that the app continues working.
#
Step 3: Add new microfrontendIn single-spa, it's encouraged to split microfrontends by route. During the migration/transition period, you may need to have the legacy angularjs application always active to show navigation menus, even for routes that are controlled by new microfrontends.
It's recommended to create new microfrontends via the single-spa CLI.
- Add a new call to
registerApplication()
to your index.html file.
- Add the new microfrontend to your import map in the index.html file.
- Start a new microfrontend on the port in the import map. Go to the route for the new microfrontend and verify it is loaded.
#
Examples- polyglot microfrontends account settings: Gulp + angularjs@1.7 project integrated with Vue microfrontends.
- single-spa-es5-angularjs: No build process - just global variables.