Module bundler with support for code splitting, ES6 & CommonJS modules.
Splittable is a next-generation module bundler for JavaScript with support for
Requires java for one dependency to run.
npm i -g splittable
splittable path/to/module1.js path/to/module2.js
It is recommended to run splittable from the root directory of your project.
write-to
: Output directory for bundles. Default: ./out/
warnings
: Whether to show closure compiler warnings. Default: false
var splittable = require('splittable');
splittable({
// Create bundles from 2 entry modules `./lib/a` and `./lib/b`.
modules: ['./lib/a', './lib/b'],
writeTo: 'out/',
}).then(function(info) {
if (info.warnings) {
console.warn(info.warnings);
console.log('Compilation successful with warnings.');
} else {
console.log('Compilation successful.');
}
}, function(reason) {
console.error('Compilation failed', reason);
});
writeTo
: Output directory for bundles. Default: ./out/
warnings
: Whether to show closure compiler warnings. Default: false
babel
: (Experimental, feedback appreciated) Allows specifying babel options. By default splittable also reads from your .babelrc
. Please note, though. We highly recommend turning off transpilation of ES6 modules. Otherwise the generated code will be very poor (splittable compiles ES6 modules at a later stage).splittable({
modules: ['./test/module-regression/custom-babel-config.js'],
writeTo: 'test-out/',
babel: {
presets: [
['es2015', { loose: true, modules: false /* IMPORTANT! */ }],
'stage-0'
],
plugins: [
'transform-object-rest-spread',
['transform-react-jsx', { pragma:'h' }]
],
}
})
The above will write 3 files (plus sourcemaps) to the directory out
.
./lib/a
and its dependencies../lib/b
and its dependencies._base.js
that contains the shared dependencies of the entry modules.By default bundles are generated into the out/
directory (can be overridden via writeTo
option).
System.import
The generated _base.js
bundle ships with a System.import
polyfill. It can be used to load modules exposed as bundles via splittable. The System.import
function returns a promise for an object that exposes the exports of the loaded module.
System.baseURL = '/path/to/bundles/';
System.import('module/path').then(function(module) {
module.exportedFunction();
})
module/path
must be a path to a module as used in your splittable command line config or JS calls. It is not a relative path with respect to the actual JS module you call this from.
System.baseURL = '/path/to/bundles/';
must be supplied, so the loader knows where to find the bundles. This should be the directory, where you deployed your splittable bundles.
Note: The polyfill requires promises. If you chose to use System.import
and are targeting older browsers, please supply your own polyfill such as PJS.
Loading splittable bundles is super straightforward with async
script tags. You do not need to worry about the order in which they execute. Example:
<script async src="out/_base.js"></script>
<script async src="out/lib-a.js"></script>
<script async src="out/lib-b.js"></script>
For an example and advanced usage such as JS initiated loading see the sample.
This section is for entertainment only. All of the above bundlers certainly have dozens of other features that makes them more useful than splittable and/or could use splittable as plugin to get the best of all worlds.
Splittable is a wrapper around both Browserify, Babel and Closure Compiler. It uses the former 2 to resolve modules and their dependencies, and then uses Closure Compiler for efficient compilation of code.
Splittable takes a list of entry modules as its input and then creates bundles for each of them, as well as an additional bundle with the share dependencies.
(May also apply to other common JS modules.
require("module-name")
must be used to load NPM modules. This is even the case inside of ES6 modules.--rename_prefix_namespace
at the trade off of slightly more verbose generated code.