Skip to content

NPM pkg for dist bundles #2670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 5, 2018
2 changes: 2 additions & 0 deletions BUILDING.md
Original file line number Diff line number Diff line change
@@ -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 [[email protected]+](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.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 17 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<!-- Latest compiled and minified plotly.js JavaScript -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
Expand All @@ -62,18 +50,27 @@ and require plotly.js using CommonJS as `var Plotly = require('plotly.js');` or
<script src="https://cdn.plot.ly/plotly-1.5.0.min.js"></script>

<!-- OR an un-minified version is also available -->
<script src="https://cdn.plot.ly/plotly-latest.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.js" charset="utf-8"></script>
```

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
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
102 changes: 42 additions & 60 deletions tasks/stats.js
Original file line number Diff line number Diff line change
@@ -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');

Expand All @@ -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';
Expand Down Expand Up @@ -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\')`',
Expand All @@ -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.'
];
}

Expand All @@ -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');
}
Expand All @@ -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(' ');
}
139 changes: 139 additions & 0 deletions tasks/sync_packages.js
Original file line number Diff line number Diff line change
@@ -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;
});
});
Loading