mirror of
https://github.com/systemjs/systemjs.git
synced 2026-01-25 14:57:38 +00:00
documentation separation
This commit is contained in:
parent
65a6e370fd
commit
be22989d6d
349
README.md
349
README.md
@ -1,12 +1,12 @@
|
||||
SystemJS
|
||||
========
|
||||
|
||||
Spec-compliant universal module loader - loads ES6 modules, AMD, CommonJS and global scripts.
|
||||
Universal dynamic module loader - loads ES6 modules, AMD, CommonJS and global scripts in the browser and NodeJS.
|
||||
|
||||
Designed as a collection of small extensions to the ES6 specification System loader, which can also be applied individually.
|
||||
Designed as a collection of extensions to the [ES6 module loader](https://github.com/ModuleLoader/es6-module-loader) which can also be applied individually.
|
||||
|
||||
* Loads any module format, by detecting the format automatically. Modules can also [specify their format with meta config](#meta-configuration).
|
||||
* Provides comprehensive and exact replications of AMD, CommonJS and ES6 circular reference handling.
|
||||
* [Loads any module format](https://github.com/systemjs/systemjs/wiki/Module-Format-Support).
|
||||
* Provides comprehensive and exact replications of AMD, CommonJS and ES6 [circular reference handling](https://github.com/ModuleLoader/es6-module-loader/wiki/Circular-References-&-Bindings).
|
||||
* Loads [ES6 modules compiled into the `System.register` form for production](#es6-systemregister-compilation), maintaining full circular references support.
|
||||
* Supports RequireJS-style [map](#map-configuration), [paths](https://github.com/ModuleLoader/es6-module-loader#paths-implementation), [bundles](#bundles), [shim](#global-module-format-support) and [plugins](#plugins).
|
||||
* Tracks package versions, and resolves semver-compatibile requests through [package version syntax](#versions) - `package@x.y.z`, `package^@x.y.z`.
|
||||
@ -18,7 +18,20 @@ Runs in IE8+ and NodeJS.
|
||||
|
||||
For discussion, [see the Google Group](https://groups.google.com/group/systemjs).
|
||||
|
||||
Basic Configuration
|
||||
Documentation
|
||||
---
|
||||
|
||||
* [Loader Configuration](https://github.com/ModuleLoader/es6-module-loader/wiki/Configuring-the-Loader)
|
||||
* [Map Configuration](https://github.com/systemjs/systemjs/wiki/Map-Configuration)
|
||||
* [Meta Configuration](https://github.com/systemjs/systemjs/wiki/Meta-Configuration)
|
||||
* [Module Format Support](https://github.com/systemjs/systemjs/wiki/Module-Format-Support)
|
||||
* [Relative Dynamic Loading](https://github.com/systemjs/systemjs/wiki/Relative-Dynamic-Loading)
|
||||
* [Versions Extension](https://github.com/systemjs/systemjs/wiki/Versions-Extension)
|
||||
* [Production Workflows](https://github.com/systemjs/systemjs/wiki/Production-Workflows)
|
||||
* [Creating Plugins](https://github.com/systemjs/systemjs/wiki/Creating-a-Plugin)
|
||||
* [Creating a Custom Module Format](https://github.com/systemjs/systemjs/wiki/Creating-a-Custom-Format-Extension)
|
||||
|
||||
Getting Started
|
||||
---
|
||||
|
||||
### Setup
|
||||
@ -43,7 +56,7 @@ index.html:
|
||||
System.config({
|
||||
|
||||
// set all requires to "lib" for library code
|
||||
baseURL: '/lib',
|
||||
baseURL: '/lib/',
|
||||
|
||||
// set "app" as an exception for our application code
|
||||
paths: {
|
||||
@ -102,222 +115,12 @@ To build for production, see the [System.register build workflow](#es6-systemreg
|
||||
|
||||
For further infomation on ES6 module loading, see the [ES6 Module Loader polyfill documentation](https://github.com/ModuleLoader/es6-module-loader).
|
||||
|
||||
### Loading Other Formats
|
||||
|
||||
When loading from CommonJS, AMD or globals, SystemJS will detect the format automatically.
|
||||
|
||||
Any module type can be loaded from any other type.
|
||||
|
||||
When loading CommonJS, AMD or globals from ES6, use the `default` import syntax:
|
||||
|
||||
app/es6-loading-commonjs:
|
||||
```javascript
|
||||
import _ from './underscore';
|
||||
```
|
||||
|
||||
Where underscore.js is located in the same folder.
|
||||
|
||||
Features
|
||||
---
|
||||
|
||||
### Map Configuration
|
||||
|
||||
Map configuration alters the module name at the normalization stage. It is useful for creating aliases:
|
||||
|
||||
```javascript
|
||||
System.map['jquery'] = 'location/for/jquery';
|
||||
|
||||
System.import('jquery') // -> 'location/for/jquery'
|
||||
System.import('jquery/submodule') // -> `location/for/jquery/submodule'
|
||||
```
|
||||
|
||||
Contexual map configuration can also be used to provide maps only for certain modules, which is useful for version mappings:
|
||||
|
||||
```javascript
|
||||
System.map['some-module'] = {
|
||||
jquery: 'jquery@2.0.3'
|
||||
};
|
||||
|
||||
// some-module.js now gets 'jquery@2.0.3'
|
||||
// everything else still gets 'location/for/jquery'
|
||||
```
|
||||
|
||||
Contextual maps apply from the most specific module name match only.
|
||||
|
||||
### Meta Configuration
|
||||
|
||||
The ES6 module loader uses a special `metadata` object that is passed between hooks.
|
||||
|
||||
An example of meta config is the module format of a module, which is stored at `metadata.format`.
|
||||
|
||||
The meta extension opens up this object for setting defaults through `System.meta` as well as inline module syntax.
|
||||
|
||||
In this way, we can specify the module format of a module through config:
|
||||
|
||||
```javascript
|
||||
System.meta['some/module'] = {
|
||||
format: 'amd'
|
||||
};
|
||||
|
||||
System.import('some/module') // always loaded as AMD even if it is a UMD module
|
||||
```
|
||||
|
||||
Or the module can even specify its own meta:
|
||||
|
||||
some/module.js
|
||||
```javascript
|
||||
"format amd";
|
||||
|
||||
if (typeof module != 'undefined' && module.exports)
|
||||
module.exports = 'cjs';
|
||||
else
|
||||
define(function() { return 'amd' });
|
||||
```
|
||||
|
||||
Since it is impossible to write 100% accurate module detection, this inline `format` hint provides a useful way of informing the module format of a module.
|
||||
|
||||
The format options are - `register`, `es6`, `amd`, `cjs`, `global`.
|
||||
|
||||
### Global Module Format Support
|
||||
|
||||
When a module is loaded as a global, the global object is detected automatically from the change in the `window` properties:
|
||||
|
||||
app/sample-global.js
|
||||
```javascript
|
||||
hello = 'world';
|
||||
```
|
||||
|
||||
```javascript
|
||||
System.import('app/sample-global').then(function(m) {
|
||||
m == 'world';
|
||||
});
|
||||
```
|
||||
|
||||
When multiple global properties are detected, the module object becomes the collection of those objects:
|
||||
|
||||
app/multi-global.js
|
||||
```javascript
|
||||
first = 'global1';
|
||||
var second = 'global2';
|
||||
```
|
||||
|
||||
```javascript
|
||||
System.import('app/multi-global').then(function(m) {
|
||||
m.first == 'global1';
|
||||
m.second == 'global2';
|
||||
});
|
||||
```
|
||||
|
||||
Global dependencies can be specified with the `deps` [meta config](#meta-configuration):
|
||||
|
||||
app/another-global.js
|
||||
```javascript
|
||||
$(document).fn();
|
||||
this.is = 'a global dependent on jQuery';
|
||||
```
|
||||
|
||||
```javascript
|
||||
System.meta['app/another-global'] = { deps: ['jquery'] };
|
||||
```
|
||||
|
||||
Note that the name used in `System.meta` must be the fully normalized name that is returned by `Promise.resolve(System.normalize('module-name')).then(console.log.bind(console))`.
|
||||
|
||||
The `exports` meta config can also be set (using inline meta as an example):
|
||||
|
||||
app/more-global.js
|
||||
```javascript
|
||||
"format global";
|
||||
"deps jquery";
|
||||
"exports my.export";
|
||||
|
||||
(function(global) {
|
||||
global.my = {
|
||||
export: 'value'
|
||||
};
|
||||
$(document).fn();
|
||||
})(typeof window != 'undefined' ? window : global);
|
||||
```
|
||||
|
||||
There is also supports for the `init` function meta config just like RequireJS as well.
|
||||
|
||||
**IE8 Support**
|
||||
|
||||
In IE8, automatic global detection does not work for globals declared as variables or implicitly:
|
||||
|
||||
```javascript
|
||||
var someGlobal = 'IE8 wont detect this';
|
||||
anotherGlobal = 'unless using an explicit shim';
|
||||
```
|
||||
|
||||
IF IE8 support is needed, these exports will need to be declared manually with configuration.
|
||||
|
||||
### Versions
|
||||
|
||||
An optional syntax for version support can be used: `moduleName@version`.
|
||||
|
||||
For example, consider an app which wants to specify the jQuery version through config:
|
||||
|
||||
```javascript
|
||||
System.versions['jquery'] = '2.0.3';
|
||||
```
|
||||
|
||||
Now an import of the form:
|
||||
|
||||
```javascript
|
||||
System.import('jquery');
|
||||
```
|
||||
|
||||
will load a load will be made to the file `/lib/jquery@2.0.3.js`.
|
||||
|
||||
This centralises the version management to the configuration file, which is key to handling versions with correct caching.
|
||||
|
||||
For multi-version support, provide an array of versions:
|
||||
|
||||
```javascript
|
||||
System.versions['jquery'] = ['2.0.3', '1.8.3'];
|
||||
```
|
||||
|
||||
These correspond to `/lib/jquery@2.0.3.js` and `/lib/jquery@1.8.3.js`.
|
||||
|
||||
Semver-compatible requires of any of the following forms can be used:
|
||||
|
||||
```javascript
|
||||
System.import('jquery') // -> /lib/jquery@2.0.3.js
|
||||
System.import('jquery@2') // -> /lib/jquery@2.0.3.js
|
||||
System.import('jquery@2.0') // -> /lib/jquery@2.0.3.js
|
||||
|
||||
System.import('jquery@1') // -> /lib/jquery@1.8.3.js
|
||||
System.import('jquery@1.8') // -> /lib/jquery@1.8.3.js
|
||||
System.import('jquery@1.8.2') // -> /lib/jquery@1.8.2.js
|
||||
|
||||
// semver compatible form (caret operator ^)
|
||||
System.import('jquery@^2') // -> /lib/jquery@2.0.3.js
|
||||
System.import('jquery@^1.8.2') // -> /lib/jquery@1.8.3.js
|
||||
System.import('jquery@^1.8') // -> /lib/jquery@1.8.3.js
|
||||
```
|
||||
|
||||
### Relative Dynamic Loading
|
||||
|
||||
Modules can check their own name from the global variable `__moduleName`. `__moduleAddress` is also available.
|
||||
|
||||
This allows easy relative dynamic loading, allowing modules to load additional functionality after the initial load:
|
||||
|
||||
```javascript
|
||||
export function moreFunctionality() {
|
||||
return System.import('./extrafunctionality', { name: __moduleName });
|
||||
}
|
||||
```
|
||||
|
||||
This can be useful for modules that may only know during runtime which functionality they need to load.
|
||||
[For further details about SystemJS module format support, see the wiki page](https://github.com/systemjs/systemjs/wiki/Module-Format-Support).
|
||||
|
||||
### Plugins
|
||||
|
||||
Plugins handle alternative loading scenarios, including loading assets such as CSS or images, and providing custom transpilation scenarios.
|
||||
|
||||
Plugins are indicated by `!` syntax, which unlike RequireJS is appended at the end of the module name, not the beginning.
|
||||
|
||||
The plugin name is just a module name itself, and if not specified, is assumed to be the extension name of the module.
|
||||
|
||||
Supported Plugins:
|
||||
|
||||
* [CSS](https://github.com/systemjs/plugin-css) `System.import('my/file.css!')`
|
||||
@ -325,113 +128,15 @@ Supported Plugins:
|
||||
* [JSON](https://github.com/systemjs/plugin-json) `System.import('some/data.json!').then(function(json){})`
|
||||
* [Text](https://github.com/systemjs/plugin-text) `System.import('some/text.txt!text').then(function(text) {})`
|
||||
|
||||
Additional Plugins:
|
||||
Additional Community Plugins:
|
||||
|
||||
* [JSX](https://github.com/floatdrop/plugin-jsx) `System.import('template.jsx!')`
|
||||
* [Markdown](https://github.com/guybedford/plugin-md) `System.import('app/some/project/README.md!').then(function(html) {})`
|
||||
* [WebFont](https://github.com/guybedford/plugin-font) `System.import('google Port Lligat Slab, Droid Sans !font')`
|
||||
|
||||
Creating custom plugins can be quite simple. See the plugins above, and [read the guide here](https://github.com/systemjs/systemjs/wiki/Creating-a-Plugin).
|
||||
Additional plugin submissions to the above are welcome.
|
||||
|
||||
### ES6 System.register Compilation
|
||||
|
||||
If writing an application in ES6, we can compile into ES5 with Traceur:
|
||||
|
||||
```
|
||||
npm install traceur -g
|
||||
```
|
||||
|
||||
```
|
||||
traceur --dir app app-built --modules=instantiate
|
||||
```
|
||||
|
||||
This will compile all ES6 files in the directory `app` into corresponding ES5 `System.register` files in `app-built`.
|
||||
|
||||
The `instantiate` modules option writes the modules out using a `System.register` call, which is supported by SystemJS.
|
||||
|
||||
Then include [`traceur-runtime.js`](https://raw.githubusercontent.com/jmcriffey/bower-traceur/0.0.72/traceur-runtimr.js) (also found inside traceur's `bin` folder when installed via npm) before es6-module-loader.js:
|
||||
|
||||
```html
|
||||
<script src="traceur-runtime.js"></script>
|
||||
<script src="system.js"></script>
|
||||
<script>
|
||||
System.paths['app/*'] = 'app-built/*.js';
|
||||
</script>
|
||||
```
|
||||
|
||||
We can then use map or paths config to ensure that `app/main` gets directed to the new folder. Alternatively rename `app-built` to replace `app`.
|
||||
|
||||
Now the application will continue to behave identically without needing to compile ES6 in the browser.
|
||||
|
||||
### Compiling ES6 to ES5 and AMD
|
||||
|
||||
The same method above can also be used to compile ES6 into AMD with `--modules=amd`.
|
||||
|
||||
We can then use the r.js optimizer to create a bundle with named defines, which are supported by SystemJS.
|
||||
|
||||
Note that the ES6 live bindings and circular references don't work in AMD, although circular references still work in many cases.
|
||||
|
||||
### Bundles
|
||||
|
||||
Bundles configuration allows a single bundle file to be loaded in place of separate module files.
|
||||
|
||||
```javascript
|
||||
System.bundles['build/core'] = ['jquery', 'app/app', 'app/dep', 'lib/third-party'];
|
||||
|
||||
// loads "app/app" from the module "build/core".
|
||||
System.import('app/app');
|
||||
|
||||
// a request to any one of 'jquery', 'app/app', 'app/dep', 'lib/third-party'
|
||||
// would delegate to the "build/core" module
|
||||
```
|
||||
|
||||
A built file must contain the exact named defines or named `System.register` statements for the modules
|
||||
it contains. Mismatched names will result in separate requests still being made.
|
||||
|
||||
We can create a custom bundle with Traceur by combining together a module with all its dependencies into a single file:
|
||||
|
||||
```
|
||||
traceur --out build.js app/main.js app/core.js app/another.js
|
||||
```
|
||||
|
||||
Each file will be traced and all its dependencies included in the final build file.
|
||||
|
||||
We can also just include this bundle with a `<script>` tag in the page.
|
||||
|
||||
### CSP-Compatible Production
|
||||
|
||||
SystemJS comes with a separate build for production only. This is fully CSP-compatible using script tag injection to load scripts, while still remaining an
|
||||
extension of the ES6 Module Loader.
|
||||
|
||||
Replace the `system.js` file with `dist/system-csp.js`.
|
||||
|
||||
If we have compiled all our modules into a `System.register` bundle, we can do:
|
||||
|
||||
```html
|
||||
<script src="system-csp.js"></script>
|
||||
<script>
|
||||
System.paths['app-built'] = '/app-built.js';
|
||||
System.bundles['app-built'] = ['app/main'];
|
||||
System.import('app/main').then(function(m) {
|
||||
// loads app/main from the app-built bundle
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
To make all module formats work with CSP, we need to ensure everything is built with a suitable wrapper.
|
||||
|
||||
See [SystemJS Builder](https://github.com/systemjs/builder) for a single-file build workflow that can wrap up all module formats.
|
||||
|
||||
### RequireJS Support
|
||||
|
||||
To use SystemJS side-by-side in a RequireJS project, make sure to include RequireJS after ES6 Module Loader but before SystemJS.
|
||||
|
||||
Conversely, to have SystemJS provide a RequireJS-like API in an application set:
|
||||
|
||||
```javascript
|
||||
window.define = System.amdDefine;
|
||||
window.require = window.requirejs = System.amdRequire;
|
||||
```
|
||||
[Read the guide here on creating plugins](https://github.com/systemjs/systemjs/wiki/Creating-a-Plugin).
|
||||
|
||||
### NodeJS Usage
|
||||
|
||||
@ -452,19 +157,11 @@ System.import('./app').then(function(m) {
|
||||
});
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome. The goal of SystemJS is to encourage loaders made out of small self-contained features.
|
||||
|
||||
Since different builds can be created for different use cases, new builds or new features are welcome to be submitted for
|
||||
consideration with pull requests.
|
||||
|
||||
#### Running the tests
|
||||
|
||||
To install the dependencies correctly, run `bower install` from the root of the repo, then open `test/test.html` in a browser with a local server
|
||||
or file access flags enabled.
|
||||
|
||||
|
||||
License
|
||||
---
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user