-
-
Notifications
You must be signed in to change notification settings - Fork 254
Configuring Packages for jspm
This guide covers how to configure packages for jspm compatibility, describing the package.json configuration options. If you are stuck, or would like to request help with getting a package configured for jspm, simply post an issue to the registry repo here.
When requesting a package, either downloaded with the CLI or through a CDN endpoint, jspm uses certain optional package.json configuration properties to be able to understand the package.
Note: These package.json configurations extend the existing package.json spec, shared with npm. You can write these properties at the base of your package.json, or if you don't want to change existing properties that you'd like to use specifically for
npm
, you can write your jspm-specific configuration inside thejspm
property of package.json, and jspm will prefer the settings found there over the stuff at the root level.
For a given package, we need to work out where it is located. Currently the endpoints supported are GitHub and npm. It is important to ensure that the package source is well-maintained and ideally an official repository for the package. Otherwise the package will go out of date over time.
Packages hosted on npm are best to use because they are normally small and already configured correctly to work with their dependencies managed through jspm.
When using npm, most of the steps here can be skipped, and one can get straight to just testing the repo.
If loading a module from npm that is not CommonJS style you will need to add a
format
override to the package as all modules are by default treated as CommonJS on npm.
When using a package from GitHub one has to consider file size quite carefully.
- Try downloading the release tarball and see how long it takes. This will be replicated every time someone downloads this package, so ensure this isn't too big.
- For GitHub projects that use custom GitHub release assets, the asset zip file or tarball will be used instead of cloning the git repo, which allows a much quicker download when installing Bootstrap for example.
Having worked out the package name, it will be something like github:some/repo
or npm:repo
. Now we can start testing package configuration.
The jspm CLI provides an option to specify the package override for testing.
Simply add the -o
option to an install to set the package override:
jspm install github:twbs/bootstrap -o "{ registry: 'jspm', main: 'js/bootstrap', shim: { 'js/bootstrap': ['jquery'] } }"
The registry property is always needed for jspm to understand dependencies. npm packages use
registry: "npm"
by default.
Once tested the exact override can then be included in the registry with a pull request.
The options for these overrides are described in the rest of this document.
When creating a package.json file for a package, sometimes it can be necessary to separate the jspm-specific configuration from npm or other systems.
The jspm
package.json property allows us to do this:
{
"name": "my-package",
"jspm": {
"main": "jspm-main"
}
}
When processed, the jspm
property is treated as an override of the underlying package.json itself.
You may wish to use the jspm
property for all jspm configuration, or not use it at all - this is entirely your own preference.
The first thing to consider is what package files jspm is using for the package. Most packages have different folders for testing and development, so it is important to indicate exactly where our module files are to be used.
If the main module files for use are all in a folder within the package, we can set this folder with the directories.lib
option.
For example, if we had the main libraries in a folder called src
, we would write:
{
"directories": {
"lib": "src"
}
}
jspm will now only use this folder within the package. All file paths will now be relative to this lib folder.
Here's another example. Suppose you have the following override, notice the repetitive dist/famous-angular
:
{
"registry": "jspm",
"main": "dist/famous-angular",
"dependencies": {
"famous": "^0.3.0",
"angular": "^1.2.0",
"css": "*"
},
"shim": {
"dist/famous-angular": {
deps: ["./famous-angular.css!"]
}
}
}
You can change that to the following to avoid repeating the dist/
directory in main:
and shim:
:
{
"registry": "jspm",
"directories" : {
"lib": "dist"
},
"main": "famous-angular",
"dependencies": {
"famous": "^0.3.0",
"angular": "^1.2.0",
"css": "*"
},
"shim": {
"famous-angular": {
deps: ["./famous-angular.css!"]
}
}
}
Just like npm, if there are only a few files (or folders) to include, they can be individually listed in a files array.
This array also supports glob patterns.
Also like npm, if there are certain specific files or folders to ignore, they can be listed in an array.
Both files
and ignore
are applied before using the directories.lib
so should still include the lib
path.
While jspm will detect the module format automatically and accurately in the majority of cases, it is typically best to include the module format.
Options are es6
, amd
, cjs
and global
.
When loading modules from
npm
, the module format is treated ascjs
by default and no automatic detection is run. To load modules of another format you will need to override this property manually.
This is the module name of the main entry point of the package. It isn't necessary to include the .js
extension, or start the name with relative syntax (./
), although this will still work.
jspm only understands dependencies in the context of a registry. Without a registry set, jspm will ignore the dependencies.
When loading packages from npm, jspm will set the default registry to npm
, and treat the dependencies accordingly.
When loading packages from other endpoints, the registry must be set explicitly to jspm
to enable the dependencies and allow for jspm registry support.
Note: To avoid headaches, just always set the registry property unless you know what you're doing. :)
For example,
{
"jspm": {
"registry": "jspm",
"dependencies": {
"famous": "github:trusktr/famous@jspm",
"infamous": "github:infamous/infamous@master"
}
}
or
{
"jspm": {
"registry": "npm",
"dependencies": {
"famous": "^0.3.4",
"infamous": "^0.0.20"
}
}
The jspm
registry allows dependencies of the following forms as would be found inside package.json:
"name": "version"
"name": "name@version"
"name": "endpoint:name@version"
In #1, the "name"
key means jspm will look for a package called name
in the jspm registry to determine what endpoint to get the package from and what overrides to apply.
In #2, the "name"
property can be anything you want, creating an alias to a package, and jspm will look for the non-aliased package name (the right-hand name) in the jspm registry. For example, "dollar": "[email protected]"
would let you do var $ = require('dollar')
in your code to load jquery.
In #3, you can also set the left-hand name
to whatever you want to make an alias, but now jspm will try to find the package at the endpoint you've specified without looking in the jspm registry.
Typically semver-compatible versions should be used of the form ^x.y.z
. The full description of allowed version formats are described in the version section on https://jspm.io.
Shims allow you to specify dependencies for specific files in a project. This configuration is identical to the way it is defined in other loaders such as RequireJS.
Packages written as globals need a shim configuration to work properly in a modular environment. To shim a file some/global.js
within the package, we can write:
{
"shim": {
"some/global": {
"deps": ["jquery"],
"exports": "globalExportName"
}
}
Both deps
and exports
are optional.
exports
is detected automatically by the SystemJS loader as any globals written by the script. In most cases this detection will work out correctly.
The shortcut form of "some/global": ["jquery"]
is also supported if there is no exports
.
Shims aren't limited to globals. As in the above directories.lib examples, a shim can be used to define the dependencies of any file in a project:
{
"registry": "jspm",
"directories" : {
"lib": "dist"
},
"main": "famous-angular",
"dependencies": {
"famous": "^0.3.0",
"angular": "^1.2.0",
"css": "*"
},
"shim": {
"famous-angular": {
deps: ["./famous-angular.css!"]
}
}
}
That shim configuration will cause dist/famous-angular.css
to get loaded first (by the systemjs css plugin) any time dist/famous-angular.js
gets loaded.
This configuration option is rarely used since dependencies
covers most rewriting needs. But sometimes internal requires within a module need to be rewritten in various other ways.
Map configuration will rewrite internal requires to point to different local or external modules.
Consider a package which includes its own dependency, dep
located at third_party/dep
. It could have a require statement internally something like:
require('dep');
In order to use the local version, we can write:
{
"map": {
"dep": "./third_party/dep"
}
}
Map configuration can also reference external packages without the ./
.