From 9af485a584e47fd503ed5c62b9f6482574715f1e Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 10 Oct 2016 03:50:11 +0200 Subject: Squashed 'thirdparty/systemjs/' content from commit 5ed69b6 git-subtree-dir: thirdparty/systemjs git-subtree-split: 5ed69b6344e8fc1cd43bf758350b2236f57e1499 --- docs/config-api.md | 292 +++++++++++++++++++++++++++++++++++++++++++ docs/creating-plugins.md | 84 +++++++++++++ docs/es6-modules-overview.md | 108 ++++++++++++++++ docs/module-formats.md | 228 +++++++++++++++++++++++++++++++++ docs/overview.md | 166 ++++++++++++++++++++++++ docs/production-workflows.md | 83 ++++++++++++ docs/system-api.md | 141 +++++++++++++++++++++ 7 files changed, 1102 insertions(+) create mode 100644 docs/config-api.md create mode 100644 docs/creating-plugins.md create mode 100644 docs/es6-modules-overview.md create mode 100644 docs/module-formats.md create mode 100644 docs/overview.md create mode 100644 docs/production-workflows.md create mode 100644 docs/system-api.md (limited to 'docs') diff --git a/docs/config-api.md b/docs/config-api.md new file mode 100644 index 000000000..6ef4c6b92 --- /dev/null +++ b/docs/config-api.md @@ -0,0 +1,292 @@ +## Configuration API + +### Setting Configuration + +Once SystemJS has loaded, configuration can be set on SystemJS by using the configuration function `System.config`: + +```javascript +System.config({ + configA: {}, + configB: 'value' +}); +``` + +This is a helper function which normalizes configuration and sets configuration properties on the SystemJS instance. + +`System.config({ prop: 'value' })` is mostly equivalent to `System.prop = value` except that it will extend configuration objects, +and certain properties will be normalized to be stored correctly. + +For this reason it is usually advisable to use `System.config` instead of setting instance properties directly. + +### Configuration Options + +* [babelOptions](#babeloptions) +* [bundle](#bundle) +* [defaultJSExtensions](#defaultjsextensions) +* [depCache](#depcache) +* [map](#map) +* [meta](#meta) +* [packages](#packages) +* [paths](#paths) +* [traceurOptions](#traceuroptions) +* [transpiler](#transpiler) +* [typescriptOptions](#typescriptoptions) + +#### babelOptions +Type: `Object` +Default: `{}` + +Set the Babel transpiler options when [System.transpiler](#transpiler) is set to `babel`: + +```javascript +System.config({ + babelOptions: { + stage: 1 + } +}); +``` + +A list of options is available in the [Babel project documentation](https://babeljs.io/docs/usage/options/). + +#### bundle +Type: `Object` + +Bundles allow a collection of modules to be downloaded together as a package whenever any module from that collection is requested. +Useful for splitting an application into sub-modules for production. Use with the [SystemJS Builder](https://github.com/systemjs/builder). + +```javascript +System.config({ + bundles: { + bundleA: ['dependencyA', 'dependencyB'] + } +}); +``` + +In the above any require to `dependencyA` or `dependencyB` will first trigger a `System.import('bundleA')` before proceeding with the load of `dependencyA` or `dependencyB`. + +It is an alternative to including a script tag for a bundle in the page, useful for bundles that load dynamically where we want to trigger the bundle load automatically only when needed. + +The bundle itself is a module which contains named System.register and define calls as an output of the builder. The dependency names the bundles config lists should be the same names that are explicitly defined in the bundle. + +#### defaultJSExtensions + +Backwards-compatibility mode for the loader to automatically add '.js' extensions when not present to module requests. + +This allows code written for SystemJS 0.16 or less to work easily in the latest version: + +```javascript +System.defaultJSExtensions = true; + +// requests ./some/module.js instead +System.import('./some/module'); +``` + +Note that this is a compatibility property for transitioning to using explicit extensions and will be deprecated in future. + +#### depCache +Type: `Object` + +An alternative to bundling providing a solution to the latency issue of progressively loading dependencies. +When a module specified in depCache is loaded, asynchronous loading of its pre-cached dependency list begins in parallel. + +```javascript +System.config({ + depCache: { + moduleA: ['moduleB'], // moduleA depends on moduleB + moduleB: ['moduleC'] // moduleB depends on moduleC + } +}); + +// when we do this import, depCache knows we also need moduleB and moduleC, +// it then directly requests those modules as well as soon as we request moduleA +System.import('moduleA') +``` + +Over HTTP/2 this approach may be preferable as it allows files to be individually cached in the browser meaning bundle optimizations are no longer a concern. + +#### map +Type: `Object` + +The map option is similar to paths, but acts very early in the normalization process. It allows you to map a module alias to a +location or package: + +```javascript +System.config({ + map: { + jquery: '//code.jquery.com/jquery-2.1.4.min.js' + } +}); +``` + +```javascript +import $ from 'jquery'; + +``` + +In addition, a map also applies to any subpaths, making it suitable for package folders as well: + +```javascript +System.config({ + map: { + package: 'local/package' + } +}); +``` + +```javascript +// loads /local/package/path.js +System.import('package/path.js'); +``` + +> Note map configuration used to support contextual submaps but this has been deprecated for package configuration. + +#### meta +Type: `Object` +Default: `{}` + +Module meta provides an API for SystemJS to understand how to load modules correctly. + +Meta is how we set the module format of a module, or know how to shim dependencies of a global script. + +```javascript +System.config({ + meta: { + // meaning [baseURL]/vendor/angular.js when no other rules are present + // path is normalized using map and paths configuration + 'vendor/angular.js': { + format: 'global', // load this module as a global + exports: 'angular', // the global property to take as the module value + deps: [ + // dependencies to load before this module + 'jquery' + ] + } + } +}); +``` + +Wildcard meta is also supported and is additive from least to most specific match: + +```javascript +System.config({ + meta: { + '/vendor/*': { format: 'global' } + } +}); +``` + +* [`format`](module-formats.md): + Sets in what format the module is loaded. +* [`exports`](module-formats.md#exports): + For the `global` format, when automatic detection of exports is not enough, a custom exports meta value can be set. + This tells the loader what global name to use as the module's export value. +* [`deps`](module-formats.md#shim-dependencies): + Dependencies to load before this module. Goes through regular paths and map normalization. Only supported for the `cjs`, `amd` and `global` formats. +* [`globals`](module-formats.md#custom-globals): + A map of global names to module names that should be defined only for the execution of this module. + Enables use of legacy code that expects certain globals to be present. + Referenced modules automatically becomes dependencies. Only supported for the `cjs` and `global` formats. +* [`loader`](overview.md#plugin-loaders): + Set a loader for this meta path. +* [`sourceMap`](creating-plugins.md): + For plugin transpilers to set the source map of their transpilation. +* `scriptLoad`: Set to `true` to load the module using ` + +``` + +Any type of module format can be loaded and it will be detected automatically by SystemJS. + +##### File access from files + +> _Note that when running locally, ensure you are running from a local server or a browser with local XHR requests enabled. If not you will get an error message._ + +> _For Chrome on Mac, you can run it with: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files &> /dev/null &`_ + +> _In Firefox this requires navigating to `about:config`, entering `security.fileuri.strict_origin_policy` in the filter box and toggling the option to false._ + +### Loading ES6 + +app/es6-file.js: +```javascript + export class q { + constructor() { + this.es6 = 'yay'; + } + } +``` + +```html + +``` + +ES6 modules define named exports, provided as getters on a special immutable `Module` object. + +* [Read more about ES6 modules and syntax](es6-modules-overview.md). +* To build for production, see the [production workflows](production-workflows.md). +* [Read more about SystemJS module format support](module-formats.md). + +### Loader Configuration + +Some of the standard configuration options and their use cases are described below. + +For a reference see the [Config API](config-api.md) page. + +#### baseURL + +The *baseURL* provides a special mechanism for loading modules relative to a standard reference URL. + +This can be useful for being able to refer to the same module from many different page URLs or environments: + +```javascript +System.config({ + baseURL: '/modules' +}); + + +// loads /modules/jquery.js +System.import('jquery.js'); +``` + +Module names of the above form are referred to as _plain names_ and are always loaded baseURL-relative instead of +parentURL relative like one would expect with ordinary URLs. + +> Note we always run the `System.config` function instead of setting instance properties directly as this will set the correct normalized baseURL in the process. + +#### Map Config + +The baseURL is very useful for providing an absolute reference URL for loading all modules, but we don't necessarily want to +have to locate every single shared dependency from within one folder. + +Sometimes we want to load things from different places. + +Map configuration is useful here to be able to specific exactly where to locate a given package: + +```javascript +System.config({ + map: { + jquery: 'https://code.jquery.com/jquery.js' + } +}); +``` + +Map configuration can also be used to map subpaths: + +```javascript +System.config({ + map: { + app: '/app/' + } +}); + +// will load /app/main.js +System.import('app/main.js'); +``` + +Map configuration is always applied before the baseURL rule in the loader. + +### Plugin Loaders + +Plugins handle alternative loading scenarios, including loading assets such as CSS or images, and providing custom transpilation scenarios. + +Plugins can also inline into bundles or remain separate requests when using [SystemJS Builder](https://github.com/systemjs/builder). + +To create a custom plugin, see the documentation on [creating plugins](creating-plugins.md). + +#### Basic Use + +> Note that if using the `defaultJSExtensions` compatibility feature, plugins for resources with custom extensions will only work by using the [package configuration](config-api.md#packages) `defaultExtension: false` option to override this for specific packages. + +To use a plugin, set up the plugin itself as a standard module, either locating it in the baseURL or providing map configuration for it. + +In this case, we're using the [text plugin](https://github.com/systemjs/plugin-text) as an example. + +Then configure a custom resource to be loaded via the plugin, we then use meta configuration: + +```javascript +System.config({ + // locate the plugin via map configuration + // (alternatively have it in the baseURL) + map: { + text: '/path/to/text-plugin.js' + }, + // use meta configuration to reference which modules + // should use the plugin loader + meta: { + 'templates/*.html': { + loader: 'text' + } + } +}); +``` + +Now any code that loads from `[baseURL]/templates/*.html` will use the text loader plugin and return the loaded content: + +app.js +```javascript +import htmlSource from 'templates/tpl.html'; + +document.querySelector('.container').innerHTML = htmlSource; +``` + +When we build app.js, the text plugin will then automatically inline the templates into the bundle during the build. + +#### Plugin Syntax + +It is also possible to use syntax to load via plugins instead of configuration: + +```javascript +System.import('some/file.txt!text') +``` + +When no plugin is explicitly specified the extension is used as the plugin name itself. + +> Note it is usually advisable to use plugin loader configuration over plugin syntax. diff --git a/docs/production-workflows.md b/docs/production-workflows.md new file mode 100644 index 000000000..6af698915 --- /dev/null +++ b/docs/production-workflows.md @@ -0,0 +1,83 @@ +### Compiling Modules into a Bundle + +[SystemJS builder](https://github.com/systemjs/builder) provides comprehensive support for compiling all +module formats into a single bundle in a way that supports +[circular references and zebra-striping](https://github.com/ModuleLoader/es6-module-loader/blob/v0.17.0/docs/circular-references-bindings.md). + +It also offers the ability to [create self-executing bundles](https://github.com/systemjs/builder#self-executing-sfx-bundles) +that can run without needing SystemJS present at all by embedding a micro-loader implementation. + +### DepCache + +An alternative to bundling into a single bundle is to leave files as separate for loading in production. + +The depcache extension allows specifying the dependencies of all modules upfront through configuration so that loads can +happen in parallel. + +```javascript +System.config({ + depCache: { + 'moduleA': ['moduleB'], // moduleA depends on moduleB + 'moduleB': ['moduleC'] // moduleB depends on moduleC + } +}); + +// when we do this import, depCache knows we also need moduleB and moduleC, +// it then directly requests those modules as well as soon as we request moduleA +System.import('moduleA') +``` + +Over HTTP/2 this approach may be preferable as it allows files to be individually cached in the browser meaning bundle +optimizations are no longer a concern. + +### Bundle Extension + +It can be useful to load bundles of code on-demand instead of having them all included in the HTML page blocking the +initial load. + +The bundle extension will automatically download a bundle as soon as an attempt to import any module in that bundle is made. + +```javascript + // the bundle at build/core.js contains these modules + System.config({ + bundles: { + 'build/core': ['jquery', 'app/app', 'app/dep', 'lib/third-party'] + } + }); + + // when we load 'app/app' the bundle extension interrupts the loading process + // and ensures that build/core.js is loaded first + System.import('app/app'); + + // this way a request to any one of 'jquery', 'app/app', 'app/dep', 'lib/third-party' + // will delegate to the bundle and only a single request is made +``` + +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. + +### CSP-Compatible Production + +SystemJS comes with a separate build for production only. This is fully [CSP](http://www.html5rocks.com/en/tutorials/security/content-security-policy/)-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-production.js`. + +If we have compiled all our modules into a bundle we can then write: + +```html + + +``` + +> Note the main build of SystemJS will also use script tag injection for AMD, register and global modules when it can for maximum CSP compatibility. + It is typically just plugin loaders, CommonJS and custom global metadata options that cause XHR source-loading to be needed. diff --git a/docs/system-api.md b/docs/system-api.md new file mode 100644 index 000000000..803d688fc --- /dev/null +++ b/docs/system-api.md @@ -0,0 +1,141 @@ +## SystemJS API + +For setting SystemJS configuration see the [Configuration API](config-api.md) page. + +#### System.amdDefine +Type: `Function` + +For backwards-compatibility with AMD environments, set `window.define = System.amdDefine`. + +#### System.amdRequire +Type: `Function` + +For backwards-compatibility with AMD environments, set `window.require = System.amdRequire`. + +#### System.config +Type: `Function` + +SystemJS configuration helper function. See the [Configuration API](config-api.md). + +#### System.constructor +Type: `Function` + +This represents the System base class, which can be extended or reinstantiated to create a custom System instance. + +Example: + +```javascript + var clonedSystem = new System.constructor(); + clonedSystem.baseURL = System.baseURL; + clonedSystem.import('x'); // imports in a custom context +``` + +#### System.delete(moduleName) +Type: `Function` + +Deletes a module from the registry by normalized name. + +```javascript +System.delete('http://site.com/normalized/module/name.js'); +``` + +#### System.get(moduleName) -> Module +Type: `Function` + +Returns a module from the registry by normalized name. + +```javascript +System.get('http://site.com/normalized/module/name.js').exportedFunction(); +``` + +#### System.has(moduleName) -> Boolean +Type: `Function` + +Returns whether a given module exists in the registry by normalized module name. + +```javascript +if (System.has('http://site.com/normalized/module/name.js')) { + // ... +} +``` + +#### System.import(moduleName [, normalizedParentName]) -> Promise(Module) +Type: `Function` + +Loads a module by name taking an optional normalized parent name argument. + +Promise resolves to the module value. + +For loading relative to the current module, ES Modules define a `__moduleName` binding, so that: + +```javascript +System.import('./local', __moduleName); +``` + +In CommonJS modules the above would be `module.id` instead. + +This is non-standard, but coverse a use case that will be provided by the spec. + +#### System.newModule(Object) -> Module +Type: `Function` + +Given a plain JavaScript object, return an equivalent `Module` object. + +Useful when writing a custom `instantiate` hook or using `System.set`. + +#### System.register([name ,] deps, declare) +Type: `Function` + +Declaration function for defining modules of the `System.register` polyfill module format. + +[Read more on the format at the loader polyfill page](https://github.com/ModuleLoader/es6-module-loader/blob/v0.17.0/docs/system-register.md) + +#### System.registerDynamic([name ,] deps, executingRequire, declare) +Type: `Function` + +Companion module format to `System.register` for non-ES6 modules. + +Provides a `