diff --git a/BUILDING.md b/BUILDING.md
index 639809c394a..816ecb20daa 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -1,5 +1,7 @@
# Building plotly.js
+The easiest way to bundle plotly.js into your application is to use one of the distributed plotly.js packages on npm. These distributed packages should just work with **any** build framework. That said, if you're looking to save a few bytes, read the section below corresponding to your building framework.
+
## Webpack
For plotly.js to build with Webpack you will need to install [ify-loader@v1.1.0+](https://github.com/hughsk/ify-loader) and add it to your `webpack.config.json`. This adds Browserify transform compatibility to Webpack which is necessary for some plotly.js dependencies.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4c637c3924e..ff76c5dc699 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -208,7 +208,7 @@ This will produce the following plot, and say you want to simulate a selection p
- All tasks can be run using [`npm run-script`](https://docs.npmjs.com/cli/run-script)
- Tests are `test/`, they are partitioned into `image` and `jasmine` tests
- Test dashboard and image viewer code is in `devtools/`
-- Non-distributed, built files are in `build/` (most files in here are git-ignored, the css and font built files are exceptions)
+- Built files are in `build/` (most files in here are git-ignored, the css and font built files are exceptions)
## Coding style
diff --git a/README.md b/README.md
index f1b1e83fe03..8b2416c21c9 100644
--- a/README.md
+++ b/README.md
@@ -32,28 +32,16 @@ and more.
## Quick start options
-#### Download the latest release
-[Latest Release on Github](https://github.com/plotly/plotly.js/releases/)
-
-and use the plotly.js `dist` file(s). More info [here](https://github.com/plotly/plotly.js/blob/master/dist/README.md).
-
-#### Clone the repo
+### Install with npm
```bash
-git clone https://github.com/plotly/plotly.js.git
+npm install plotly.js-dist
```
-and use the plotly.js `dist` file(s).
-
-#### Install with `npm`
-
-```bash
-npm install plotly.js
-```
+and import plotly.js as `import Plotly from 'plotly.js-dist';` or `var Plotly = require('plotly.js-dist');`.
-and require plotly.js using CommonJS as `var Plotly = require('plotly.js');` or use the plotly.js `dist` file(s).
+### Use the plotly.js CDN hosted by Fastly
-#### Use the plotly.js CDN hosted by Fastly
```html
@@ -62,18 +50,27 @@ and require plotly.js using CommonJS as `var Plotly = require('plotly.js');` or
-
+
```
and use the `Plotly` object in the window scope.
-##### Read the [Getting started page](https://plot.ly/javascript/getting-started/) for more examples.
+### Download the latest release
+
+[Latest Release on Github](https://github.com/plotly/plotly.js/releases/)
+
+and use the plotly.js `dist` file(s). More info [here](https://github.com/plotly/plotly.js/blob/master/dist/README.md).
+
+#### Read the [Getting started page](https://plot.ly/javascript/getting-started/) for more examples.
+
## Modules
-Starting in `v1.15.0`, plotly.js also ships with several _partial_ bundles (more info [here](https://github.com/plotly/plotly.js/blob/master/dist/README.md#partial-bundles)).
+Starting in `v1.15.0`, plotly.js ships with several _partial_ bundles (more info [here](https://github.com/plotly/plotly.js/blob/master/dist/README.md#partial-bundles)).
+
+Starting in `v1.39.0`, plotly.js publishes _distributed_ npm packages with no dependencies. For example, run `npm install plotly.js-geo-dist` and add `import Plotly from 'plotly.js-geo-dist';` to your code to start using the plotly.js geo package.
-If you would like to manually pick which plotly.js modules to include, you can create a *custom* bundle by using `plotly.js/lib/core`, and loading only the trace types that you need (e.g. `pie` or `choropleth`). The recommended way to do this is by creating a *bundling file*:
+If none of the distributed npm packages meet your needs, and you would like to manually pick which plotly.js modules to include, you'll first need to run `npm install plotly.js` and then create a *custom* bundle by using `plotly.js/lib/core`, and loading only the trace types that you need (e.g. `pie` or `choropleth`). The recommended way to do this is by creating a *bundling file*. For example, in CommonJS:
```javascript
// in custom-plotly.js
diff --git a/package.json b/package.json
index 733c9e01b1f..1e7f6df86f8 100644
--- a/package.json
+++ b/package.json
@@ -46,7 +46,8 @@
"baseline": "node tasks/baseline.js",
"preversion": "check-node-version --node 8 --npm 5 && npm-link-check && npm ls --prod",
"version": "npm run build && git add -A dist src build",
- "postversion": "node -e \"console.log('Version bumped and committed. If ok, run: git push && git push --tags')\""
+ "postversion": "node -e \"console.log('Version bumped and committed. If ok, run: git push && git push --tags')\"",
+ "postpublish": "node tasks/sync_package.js"
},
"browserify": {
"transform": [
diff --git a/tasks/stats.js b/tasks/stats.js
index dd7fdb0c972..da597ce71b9 100644
--- a/tasks/stats.js
+++ b/tasks/stats.js
@@ -1,7 +1,6 @@
var path = require('path');
var fs = require('fs');
-var falafel = require('falafel');
var gzipSize = require('gzip-size');
var prettySize = require('prettysize');
@@ -11,7 +10,6 @@ var pkg = require('../package.json');
var pathDistREADME = path.join(constants.pathToDist, 'README.md');
var cdnRoot = 'https://cdn.plot.ly/plotly-';
-var coreModules = ['scatter'];
var ENC = 'utf-8';
var JS = '.js';
@@ -110,6 +108,7 @@ function getMainBundleInfo() {
'- using CDN URL ' + cdnRoot + 'latest' + MINJS + ' OR ' + cdnRoot + pkg.version + MINJS,
'',
'or as raw javascript:',
+ '- using the `plotly.js-dist` npm package (starting in `v1.39.0`)',
'- using dist file `dist/plotly.js`',
'- using CDN URL ' + cdnRoot + 'latest' + JS + ' OR ' + cdnRoot + pkg.version + JS,
'- using CommonJS with `require(\'plotly.js\')`',
@@ -129,7 +128,8 @@ function getMainBundleInfo() {
'Starting in `v1.15.0`, plotly.js also ships with several _partial_ bundles:',
'',
constants.partialBundlePaths.map(makeBundleHeaderInfo).join('\n'),
- ''
+ '',
+ 'Starting in `v1.39.0`, each plotly.js partial bundle has a corresponding npm package with no dependencies.'
];
}
@@ -156,26 +156,55 @@ function makeBundleHeaderInfo(pathObj) {
function makeBundleInfo(pathObj) {
var name = pathObj.name;
var sizes = findSizes(pathObj);
- var moduleList = coreModules.concat(scrapeContent(pathObj));
+ var moduleList = common.findModuleList(pathObj.index);
+ var pkgName = 'plotly.js-' + name + '-dist';
return [
'### plotly.js ' + name,
'',
- formatBundleInfo(name, moduleList),
+ 'The `' + name + '` partial bundle contains trace modules ' + common.formatEnumeration(moduleList) + '.',
+ '',
+ '#### Stats',
+ '',
+ '| Raw size | Minified size | Minified + gzip size |',
+ '|------|-----------------|------------------------|',
+ '| ' + sizes.raw + ' | ' + sizes.minified + ' | ' + sizes.gzipped + ' |',
+ '',
+ '#### CDN links',
+ '',
+ '| Flavor | URL |',
+ '| ------ | --- |',
+ '| Latest | ' + cdnRoot + name + '-latest' + JS + ' |',
+ '| Latest minified | ' + cdnRoot + name + '-latest' + MINJS + ' |',
+ '| Tagged | ' + cdnRoot + name + '-' + pkg.version + JS + ' |',
+ '| Tagged minified | ' + cdnRoot + name + '-' + pkg.version + MINJS + ' |',
+ '',
+ '#### npm package (starting in `v1.39.0`)',
+ '',
+ 'Install [`' + pkgName + '`](https://www.npmjs.com/package/' + pkgName + ') with',
+ '```',
+ 'npm install ' + pkgName,
+ '```',
+ '',
+ 'ES6 module usage:',
+ '```js',
+ 'import Plotly from \'' + pkgName + '\'',
+ '```',
+ '',
+ 'CommonJS usage:',
+ '```js',
+ 'var Plotly = require(\'' + pkgName + '\');',
+ '```',
'',
- '| Way to import | Location |',
+ '#### Other plotly.js entry points',
+ '',
+ '| Flavor | Location |',
'|---------------|----------|',
'| dist bundle | ' + '`dist/plotly-' + name + JS + '` |',
'| dist bundle (minified) | ' + '`dist/plotly-' + name + MINJS + '` |',
- '| CDN URL (latest) | ' + cdnRoot + name + '-latest' + JS + ' |',
- '| CDN URL (latest minified) | ' + cdnRoot + name + '-latest' + MINJS + ' |',
- '| CDN URL (tagged) | ' + cdnRoot + name + '-' + pkg.version + JS + ' |',
- '| CDN URL (tagged minified) | ' + cdnRoot + name + '-' + pkg.version + MINJS + ' |',
+ '| ES6 module | ' + '`import Plotly from \'plotly.js/lib/' + 'index-' + name + '\'`' + ' |',
'| CommonJS | ' + '`require(\'plotly.js/lib/' + 'index-' + name + '\')`' + ' |',
'',
- '| Raw size | Minified size | Minified + gzip size |',
- '|------|-----------------|------------------------|',
- '| ' + sizes.raw + ' | ' + sizes.minified + ' | ' + sizes.gzipped + ' |',
''
].join('\n');
}
@@ -197,50 +226,3 @@ function findSizes(pathObj) {
return sizes;
}
-
-function scrapeContent(pathObj) {
- var code = fs.readFileSync(pathObj.index, ENC);
- var moduleList = [];
-
- falafel(code, function(node) {
- if(isModuleNode(node)) {
- var moduleName = node.value.replace('./', '');
- moduleList.push(moduleName);
- }
- });
-
- return moduleList;
-}
-
-function isModuleNode(node) {
- return (
- node.type === 'Literal' &&
- node.parent &&
- node.parent.type === 'CallExpression' &&
- node.parent.callee &&
- node.parent.callee.type === 'Identifier' &&
- node.parent.callee.name === 'require' &&
- node.parent.parent &&
- node.parent.parent.type === 'ArrayExpression'
- );
-}
-
-function formatBundleInfo(bundleName, moduleList) {
- var enumeration = moduleList.map(function(moduleName, i) {
- var len = moduleList.length,
- ending;
-
- if(i === len - 2) ending = ' and';
- else if(i < len - 1) ending = ',';
- else ending = '';
-
- return '`' + moduleName + '`' + ending;
- });
-
- return [
- 'The', '`' + bundleName + '`',
- 'partial bundle contains the',
- enumeration.join(' '),
- 'trace modules.'
- ].join(' ');
-}
diff --git a/tasks/sync_packages.js b/tasks/sync_packages.js
new file mode 100644
index 00000000000..2002c3d4ca9
--- /dev/null
+++ b/tasks/sync_packages.js
@@ -0,0 +1,139 @@
+var path = require('path');
+var fs = require('fs-extra');
+var exec = require('child_process').exec;
+var runSeries = require('run-series');
+
+var common = require('./util/common');
+var constants = require('./util/constants');
+var pkg = require('../package.json');
+
+var packagesSpecs = constants.partialBundlePaths
+ .map(function(d) {
+ return {
+ name: 'plotly.js-' + d.name + '-dist',
+ index: d.index,
+ main: 'plotly-' + d.name + '.js',
+ dist: d.dist,
+ desc: 'Ready-to-use plotly.js ' + d.name + ' distributed bundle.',
+ };
+ })
+ .concat([{
+ name: 'plotly.js-dist',
+ index: path.join(constants.pathToLib, 'index.js'),
+ main: 'plotly.js',
+ dist: constants.pathToPlotlyDist,
+ desc: 'Ready-to-use plotly.js distributed bundle.',
+ }]);
+
+packagesSpecs.forEach(function(d) {
+ var pkgPath = path.join(constants.pathToBuild, d.name);
+
+ function initDirectory(cb) {
+ if(common.doesDirExist(pkgPath)) {
+ cb();
+ } else {
+ fs.mkdir(pkgPath, cb);
+ }
+ }
+
+ function writePackageJSON(cb) {
+ var cnt = {
+ name: d.name,
+ version: pkg.version,
+ description: d.desc,
+ license: pkg.license,
+ main: d.main,
+ repository: pkg.repository,
+ bugs: pkg.bugs,
+ author: pkg.author,
+ keywords: pkg.keywords,
+ files: [
+ 'LICENSE',
+ 'README.md',
+ d.main
+ ]
+ };
+
+ fs.writeFile(
+ path.join(pkgPath, 'package.json'),
+ JSON.stringify(cnt, null, 2) + '\n',
+ cb
+ );
+ }
+
+ function writeREADME(cb) {
+ var moduleList = common.findModuleList(d.index);
+
+ var cnt = [
+ '# ' + d.name,
+ '',
+ d.desc,
+ '',
+ 'Contains trace modules ' + common.formatEnumeration(moduleList) + '.',
+ '',
+ 'For more info on plotly.js, go to https://github.com/plotly/plotly.js',
+ '',
+ '## Installation',
+ '',
+ '```',
+ 'npm install ' + d.name,
+ '```',
+ '## Usage',
+ '',
+ '```js',
+ '// ES6 module',
+ 'import Plotly from \'' + d.name + '\';',
+ '',
+ '// CommonJS',
+ 'var Plotly = require(\'' + d.name + '\');',
+ '```',
+ '',
+ '## Copyright and license',
+ '',
+ 'Code and documentation copyright 2018 Plotly, Inc.',
+ '',
+ 'Code released under the [MIT license](https://github.com/plotly/plotly.js/blob/master/LICENSE).',
+ '',
+ 'Docs released under the [Creative Commons license](https://github.com/plotly/documentation/blob/source/LICENSE).',
+ ''
+ ];
+
+ fs.writeFile(
+ path.join(pkgPath, 'README.md'),
+ cnt.join('\n'),
+ cb
+ );
+ }
+
+ function copyMain(cb) {
+ fs.copy(d.dist, path.join(pkgPath, d.main), cb);
+ }
+
+ function copyLicense(cb) {
+ fs.copy(
+ path.join(constants.pathToRoot, 'LICENSE'),
+ path.join(pkgPath, 'LICENSE'),
+ cb
+ );
+ }
+
+ function publishToNPM(cb) {
+ if(process.env.DRYRUN) {
+ console.log('dry run, did not publish ' + d.name);
+ cb();
+ return;
+ }
+ exec('npm publish', {cwd: pkgPath}, cb).stdout.pipe(process.stdout);
+ }
+
+ runSeries([
+ initDirectory,
+ writePackageJSON,
+ writeREADME,
+ copyMain,
+ copyLicense,
+ publishToNPM
+ ], function(err) {
+ if(err) throw err;
+ });
+});
diff --git a/tasks/util/common.js b/tasks/util/common.js
index b9330febd56..e3dcd6859c1 100644
--- a/tasks/util/common.js
+++ b/tasks/util/common.js
@@ -1,5 +1,6 @@
var fs = require('fs');
var exec = require('child_process').exec;
+var falafel = require('falafel');
exports.execCmd = function(cmd, cb, errorCb) {
cb = cb ? cb : function() {};
@@ -66,3 +67,41 @@ exports.touch = function(filePath) {
exports.throwOnError = function(err) {
if(err) throw err;
};
+
+exports.findModuleList = function(pathToIndex) {
+ var code = fs.readFileSync(pathToIndex, 'utf-8');
+ // In v1.x, all partial bundles include the 'scatter' module
+ var moduleList = ['scatter'];
+
+ falafel(code, function(node) {
+ if(
+ node.type === 'Literal' &&
+ node.parent &&
+ node.parent.type === 'CallExpression' &&
+ node.parent.callee &&
+ node.parent.callee.type === 'Identifier' &&
+ node.parent.callee.name === 'require' &&
+ node.parent.parent &&
+ node.parent.parent.type === 'ArrayExpression'
+ ) {
+ var moduleName = node.value.replace('./', '');
+ moduleList.push(moduleName);
+ }
+ });
+
+ return moduleList;
+};
+
+exports.formatEnumeration = function(list) {
+ var len = list.length;
+
+ return list.map(function(l, i) {
+ var ending;
+
+ if(i === len - 2) ending = ' and';
+ else if(i < len - 1) ending = ',';
+ else ending = '';
+
+ return '`' + l + '`' + ending;
+ }).join(' ');
+};