single-spa-angular
Advanced tools
Comparing version 2.0.0 to 2.1.0
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,8 +6,10 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = singleSpaAngular; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
exports.default = singleSpaAngular; | ||
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } | ||
var defaultOpts = { | ||
@@ -20,24 +22,30 @@ // required opts | ||
Router: null, | ||
ApplicationRef: null, | ||
domElementGetter: null // only optional if you provide a domElementGetter as a custom prop | ||
}; | ||
function singleSpaAngular(userOpts) { | ||
if ((typeof userOpts === 'undefined' ? 'undefined' : _typeof(userOpts)) !== 'object') { | ||
throw new Error('single-spa-angular requires a configuration object'); | ||
if (_typeof(userOpts) !== 'object') { | ||
throw new Error("single-spa-angular requires a configuration object"); | ||
} | ||
var opts = _extends({}, defaultOpts, userOpts); | ||
var opts = _objectSpread({}, defaultOpts, userOpts); | ||
if (!opts.angularPlatform) { | ||
throw new Error('single-spa-angular must be passed opts.angularPlatform. Usually this should be the return value of platformBrowserDynamic()'); | ||
throw new Error("single-spa-angular must be passed opts.angularPlatform. Usually this should be the return value of platformBrowserDynamic()"); | ||
} | ||
if (!opts.mainModule) { | ||
throw new Error('single-spa-angular must be passed opts.mainModule, which is the Angular module to bootstrap'); | ||
throw new Error("single-spa-angular must be passed opts.mainModule, which is the Angular module to bootstrap"); | ||
} | ||
if (typeof opts.template !== 'string') { | ||
throw new Error('single-spa-angular must be passed opts.template string'); | ||
throw new Error("single-spa-angular must be passed opts.template string"); | ||
} | ||
if (opts.Router && !opts.ApplicationRef || opts.ApplicationRef && !opts.Router) { | ||
throw Error('For @angular/router to work with single-spa, you must provide both the Router and ApplicationRef opts'); | ||
} | ||
return { | ||
@@ -51,3 +59,21 @@ bootstrap: bootstrap.bind(null, opts), | ||
function bootstrap(opts) { | ||
return Promise.resolve(); | ||
return Promise.resolve().then(function () { | ||
opts.routingEventListener = function (evt) { | ||
/* When popstate and hashchange events occur, single-spa delays them in order to | ||
* check which applications should be active and perform any necessary mounting/unmounting. | ||
* | ||
* ZoneJS freaks out about this because it hears about the events but it wasn't inside of a | ||
* Zone.current.run() block (or similar). I tried out modifying single-spa to call the event listener | ||
* inside of a Zone.run() block, but that didn't seem to help. I think if we could get that working | ||
* that it would be the best solution. | ||
* | ||
* I also tried out trying to detect with single-spa:routing-event events are the ones that actually | ||
* need to trigger an application tick, since not every one of them does. But I wasn't able to find a reliable | ||
* way of detecting it. So I fell back to just always causing an application tick, even though that's probably | ||
* not great for performance. | ||
*/ | ||
var applicationRef = opts.bootstrappedModule.injector.get(opts.ApplicationRef); | ||
applicationRef.tick(); | ||
}; | ||
}); | ||
} | ||
@@ -58,4 +84,5 @@ | ||
var domElementGetter = chooseDomElementGetter(opts, props); | ||
if (!domElementGetter) { | ||
throw new Error('cannot mount angular application \'' + (props.name || props.appName) + '\' without a domElementGetter provided either as an opt or a prop'); | ||
throw new Error("cannot mount angular application '".concat(props.name || props.appName, "' without a domElementGetter provided either as an opt or a prop")); | ||
} | ||
@@ -67,3 +94,9 @@ | ||
return opts.angularPlatform.bootstrapModule(opts.mainModule).then(function (module) { | ||
return opts.bootstrappedModule = module; | ||
opts.bootstrappedModule = module; | ||
if (opts.ApplicationRef) { | ||
window.addEventListener('single-spa:routing-event', opts.routingEventListener); | ||
} | ||
return module; | ||
}); | ||
@@ -74,10 +107,15 @@ }); | ||
function unmount(opts, props) { | ||
return new Promise(function (resolve, reject) { | ||
return Promise.resolve().then(function () { | ||
if (opts.Router) { | ||
// Workaround for https://github.com/angular/angular/issues/19079 | ||
var routerRef = opts.bootstrappedModule.injector.get(opts.Router); | ||
routerRef.dispose(); | ||
} | ||
if (opts.ApplicationRef) { | ||
window.removeEventListener('single-spa:routing-event', opts.routingEventListener); | ||
} | ||
opts.bootstrappedModule.destroy(); | ||
delete opts.bootstrappedModule; | ||
resolve(); | ||
}); | ||
@@ -88,4 +126,5 @@ } | ||
var element = domElementGetter(); | ||
if (!element) { | ||
throw new Error('domElementGetter did not return a valid dom element'); | ||
throw new Error("domElementGetter did not return a valid dom element"); | ||
} | ||
@@ -92,0 +131,0 @@ |
{ | ||
"name": "single-spa-angular", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "Helpers for building single-spa applications which use Angular 2", | ||
@@ -9,3 +9,3 @@ "main": "lib/single-spa-angular.js", | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"prepublish": "npm run build" | ||
"prepublish": "yarn build" | ||
}, | ||
@@ -27,7 +27,7 @@ "repository": { | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"babel-preset-latest": "^6.24.1", | ||
"babel-preset-stage-3": "^6.24.1", | ||
"@babel/cli": "^7.2.3", | ||
"@babel/core": "^7.2.2", | ||
"@babel/preset-env": "^7.2.3", | ||
"rimraf": "^2.6.2" | ||
} | ||
} |
@@ -8,3 +8,3 @@ # single-spa-angular | ||
## Example | ||
An example can be found in the [single-spa-examples](https://github.com/CanopyTax/single-spa-examples/blob/master/src/angular2/angular2.app.js) repository. | ||
An example can be found in the [single-spa-examples](https://github.com/CanopyTax/single-spa-examples/blob/master/src/angular/angular.app.js) repository. | ||
@@ -16,2 +16,3 @@ ## Quickstart | ||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; | ||
import {ApplicationRef} from '@angular/core'; | ||
import singleSpaAngular from 'single-spa-angular'; | ||
@@ -21,24 +22,13 @@ import mainModule from './main-module.ts'; | ||
const ngLifecycles = singleSpaAngular({ | ||
domElementGetter, | ||
mainModule, | ||
angularPlatform: platformBrowserDynamic(), | ||
template: `<component-to-render />`, | ||
Router, | ||
export default singleSpaAngular({ | ||
domElementGetter, | ||
mainModule, | ||
angularPlatform: platformBrowserDynamic(), | ||
template: `<component-to-render />`, | ||
Router, | ||
ApplicationRef, | ||
}) | ||
export const bootstrap = [ | ||
ngLifecycles.bootstrap, | ||
]; | ||
export const mount = [ | ||
ngLifecycles.mount, | ||
]; | ||
export const unmount = [ | ||
ngLifecycles.unmount, | ||
]; | ||
function domElementGetter() { | ||
return document.getElementById('angular'); | ||
return document.getElementById('angular'); | ||
} | ||
@@ -54,3 +44,4 @@ ``` | ||
- `template`: (required) An html string that will be put into the DOM Element returned by `domElementGetter`. This template can be anything, but it is recommended that you keeping it simple by making it only one Angular component. For example, `<my-component />` is recommended, but `<div><my-component /><span>Hello</span><another-component /></div>` is allowed. Note that `innerHTML` is used to put the template onto the DOM. | ||
- `Router`: (optional) The angular router class. If not provided, single-spa-angular will assume you are not using @angular/router. | ||
- `Router`: (optional) The angular router class. This is required when you are using `@angular/router` and must be used in conjunction with the `ApplicationRef` option. | ||
- `ApplicationRef`: (optional) The angular application ref interface. This is required when you are using `@angular/router` and must be used in conjunction with the `Router` option. | ||
- `domElementGetter`: (optional) A function that takes in no arguments and returns a DOMElement. This dom element is where the Angular application will be bootstrapped, mounted, and unmounted. | ||
@@ -57,0 +48,0 @@ Note that this opt can only be omitted when domElementGetter is passed in as a [custom prop](https://github.com/CanopyTax/single-spa/blob/master/docs/applications.md#custom-props). So you must either |
@@ -8,2 +8,3 @@ const defaultOpts = { | ||
Router: null, | ||
ApplicationRef: null, | ||
domElementGetter: null, // only optional if you provide a domElementGetter as a custom prop | ||
@@ -34,2 +35,6 @@ }; | ||
if (opts.Router && !opts.ApplicationRef || opts.ApplicationRef && !opts.Router) { | ||
throw Error('For @angular/router to work with single-spa, you must provide both the Router and ApplicationRef opts'); | ||
} | ||
return { | ||
@@ -43,3 +48,21 @@ bootstrap: bootstrap.bind(null, opts), | ||
function bootstrap(opts) { | ||
return Promise.resolve(); | ||
return Promise.resolve().then(() => { | ||
opts.routingEventListener = function(evt) { | ||
/* When popstate and hashchange events occur, single-spa delays them in order to | ||
* check which applications should be active and perform any necessary mounting/unmounting. | ||
* | ||
* ZoneJS freaks out about this because it hears about the events but it wasn't inside of a | ||
* Zone.current.run() block (or similar). I tried out modifying single-spa to call the event listener | ||
* inside of a Zone.run() block, but that didn't seem to help. I think if we could get that working | ||
* that it would be the best solution. | ||
* | ||
* I also tried out trying to detect with single-spa:routing-event events are the ones that actually | ||
* need to trigger an application tick, since not every one of them does. But I wasn't able to find a reliable | ||
* way of detecting it. So I fell back to just always causing an application tick, even though that's probably | ||
* not great for performance. | ||
*/ | ||
const applicationRef = opts.bootstrappedModule.injector.get(opts.ApplicationRef) | ||
applicationRef.tick() | ||
} | ||
}) | ||
} | ||
@@ -64,3 +87,7 @@ | ||
.then(module => { | ||
return opts.bootstrappedModule = module; | ||
opts.bootstrappedModule = module; | ||
if (opts.ApplicationRef) { | ||
window.addEventListener('single-spa:routing-event', opts.routingEventListener) | ||
} | ||
return module | ||
}) | ||
@@ -71,11 +98,14 @@ }) | ||
function unmount(opts, props) { | ||
return new Promise((resolve, reject) => { | ||
return Promise.resolve().then(() => { | ||
if (opts.Router) { | ||
// Workaround for https://github.com/angular/angular/issues/19079 | ||
const routerRef = opts.bootstrappedModule.injector.get(opts.Router); | ||
routerRef.dispose(); | ||
} | ||
if (opts.ApplicationRef) { | ||
window.removeEventListener('single-spa:routing-event', opts.routingEventListener) | ||
} | ||
opts.bootstrappedModule.destroy(); | ||
delete opts.bootstrappedModule; | ||
resolve(); | ||
}); | ||
}) | ||
} | ||
@@ -82,0 +112,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33319
211
50