Most of the API is for telling sofe how to resolve a service name to an actual file location. Because we don't want to favor any specific back-end technology, sofe tries to favor configuration over convention. As a result, there are a variety of approaches to setting up your project.
npmcdn to find urls and host files
Any npm package can be coerced into being a sofe service, since npmcdn.com hosts all files for all npm packages. This is automatically done by sofe whenever the package.json for an npm package does not have a valid sofe
property.
npmcdn to find urls, your own CDN for files
Simply put a distributable file on a CDN, modify the package.json, and publish the service to npm -- then any application can automatically resolve and load the service.
For example, a sofe-hello-world
service could automatically be resolved if sofe-hello-world
is published to npm with the following
package.json
:
{
"name": "sofe-hello-world",
"version": "1.0.0",
"sofe": {
"url": "https://npmcdn.com/[email protected]/hello.js"
}
}
Put urls to all the services into the System.config
Instead of automatically resolving services, provide a manifest of services with associated service deployable locations:
System.config({
sofe: {
manifest: {
"sofe-hello-world": "https://npmcdn.com/[email protected]/hello.js"
}
}
});
Put a url to a manifest file (which, in turn points to the source files) into the System.config
.
System.config({
sofe: {
manifestUrl: 'https://cdn.canopytax.com/canopy-services.json'
}
});
Manifest file format:
{
"sofe": {
"manifest": {
"sofe-hello-world": "https://npmcdn.com/[email protected]/hello.js"
}
}
}
Browser storage
In addition to automatic resolution or manifest resolution, the urls to individual sofe services can be overridden with sessionStorage and/or localStorage. This is meant for times when you want to test out new changes to a service on an application where you can't easily change the System.config
(i.e., you don't own the code to the application). An override is a sessionStorage/localStorage item whose key is sofe:service-name
and whose value is a url.
Example:
window.localStorage.setItem('sofe-hello-world', 'https://npmcdn.com/[email protected]/hello.js');
// OR
window.sessionStorage.setItem('sofe-hello-world', 'https://npmcdn.com/[email protected]/hello.js');
If there are multiple urls that a service could be resolved to, sofe will resolve the service url in the following order (highest precedence to lowest precedence):
- Session storage
- Local storage
- The
manifest
property inside of thesofe
attribute of theSystem.config
or manifest file - The
manifestUrl
property inside ofsofe
attribute of theSystem.config
or manifest file - The
url
property inside of thesofe
attribute of the NPM package's package.json file - The
main
file inside of the NPM package's package.json file, at thelatest
version. The files themselves are retrieved from npmcdn.com.
Because services are loaded at run-time, they cannot be bundled inside the application. Avoid bundling by using System.import
syntax instead of import
. The problem is System.import
can be cumbersome to use for all imports. If you bundle a JSPM project with sofe import
statements, you are likely to get errors that say: Uncaught (in promise) Error: This sofe service was bundled and needs to be removed from System.register
. Removing the service from System.register will allow it to be loaded at run-time, even if the project is bundled.
For example:
// main file to be bundled
import hello from 'sofe-hello-world!sofe';
hello();
<script src="dist/app-bundle.js"></script>
<script>
System.delete(System.normalizeSync('sofe-hello-world!sofe'));
</script>
Alternatively, if your project uses webpack, use the sofe-babel-plugin which allows the use of import
in bundled projects.
Sofe's configuration API exists within a System.config
property:
System.config({
sofe: {
manifest: Object, // Map of services with their distributable urls
manifestUrl: String, // Url for a manifest of available services
registry: String // Provide a custom registry defaults to "https://npmcdn.com"
}
});
Manifest file format:
{
"sofe": {
"manifest": Object // Map of services with their distrubable urls
}
}