Skip to content

Introducing partial dist bundles #740

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 12 commits into from
Jul 22, 2016
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"preprocess": "node tasks/preprocess.js",
"bundle": "node tasks/bundle.js",
"header": "node tasks/header.js",
"build": "npm run preprocess && npm run bundle && npm run header",
"stats": "node tasks/stats.js",
"build": "npm run preprocess && npm run bundle && npm run header && npm run stats",
"cibuild": "npm run preprocess && node tasks/cibundle.js",
"watch": "node tasks/watch_plotly.js",
"lint": "eslint . || true",
Expand Down Expand Up @@ -95,6 +96,7 @@
"fs-extra": "^0.30.0",
"fuse.js": "^2.2.0",
"glob": "^7.0.0",
"gzip-size": "^3.0.0",
"jasmine-core": "^2.4.1",
"karma": "^1.1.0",
"karma-browserify": "^5.0.1",
Expand Down
206 changes: 206 additions & 0 deletions tasks/stats.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
var path = require('path');
var fs = require('fs');

var falafel = require('falafel');
var gzipSize = require('gzip-size');
var prettySize = require('prettysize');

var constants = require('./util/constants');
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';
var MINJS = '.min.js';


// general info about distributed files
var infoContent = [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@rreusser rreusser Jul 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a fail-(slightly-)safe(r), can you include an html comment at the top of the markdown:

'<!--***********************************************************',
'         This file is auto-generated by `npm run stats`.',
'         Please do not edit this file directly.',
'***************************************************************-->',

'# Using distributed files',
'',
'All plotly.js dist bundles inject an object `Plotly` into the global scope.',
'',
'Import plotly.js as:',
'',
'```html',
'<script type="text/javascript" src="plotly.min.js"></script>',
'```',
'',
'or the un-minified version as:',
'',
'```html',
'<script type="text/javascript" src="plotly.js" charset="utf-8"></script>',
'```',
'',
'To support IE9, put:',
'',
'```html',
'<script>if(typeof window.Int16Array !== \'function\')document.write("<scri"+"pt src=\'extras/typedarray.min.js\'></scr"+"ipt>");</script>',
'```',
'',
'before the plotly.js script tag.',
'',
'To add MathJax, put',
'',
'```html',
'<script type="text/javascript" src="mathjax/MathJax.js?config=TeX-AMS-MML_SVG"></script>',
'```',
'',
'before the plotly.js script tag. You can grab the relevant MathJax files in `./dist/extras/mathjax/`.',
''
];

// add bundle content/size info
var mainSizes = findSizes({
dist: constants.pathToPlotlyDist,
distMin: constants.pathToPlotlyDistMin,
withMeta: constants.pathToPlotlyDistWithMeta
});
var bundleInfo = [
'# Bundle information',
'',
'The main plotly.js bundle includes all the official (non-beta) trace modules.',
'',
'It be can imported as minified javascript',
'- using dist file `dist/plotly.min.js`',
'- using CDN URL ' + cdnRoot + 'plotly-latest.min.js OR ' + cdnRoot + 'plotly-' + pkg.version + MINJS,
'',
'or as raw javascript:',
'- using dist file `dist/plotly.js`',
'- using CDN URL ' + cdnRoot + 'plotly-latest.js OR ' + cdnRoot + 'plotly-' + pkg.version + JS,
'- using CommonJS with `require(\'plotly.js\')`',
'',
'If you would like to have access to the attribute meta information ' +
'(including attribute descriptions as on the [schema reference page](https://plot.ly/javascript/reference/)), ' +
'use dist file `dist/plotly-with-meta.js`',
'',
'The main plotly.js bundle weights in at:',
'',
'| plotly.js | plotly.min.js | plotly.min.js + gzip | plotly-with-meta.js |',
'|-----------|---------------|----------------------|---------------------|',
'| ' + mainSizes.raw + ' | ' + mainSizes.minified + ' | ' + mainSizes.gzipped + ' | ' + mainSizes.withMeta + ' |',
'',
'## Partial bundles',
'',
'Starting in `v1.15.0`, plotly.js also ships with several _partial_ bundles:',
'',
constants.partialBundlePaths.map(makeBundleHeaderInfo).join('\n'),
''
]
.concat(
constants.partialBundlePaths.map(makeBundleInfo)
);

// footer info
var footer = [
'----------------',
'',
'_This file is auto-generated by `npm run stats`. ' +
'Please do not edit this file directly._'
];

var content = infoContent.concat(bundleInfo).concat(footer);

fs.writeFile(pathDistREADME, content.join('\n'), function(err) {
if(err) throw err;
});

function makeBundleHeaderInfo(pathObj) {
var name = pathObj.name;
return '- [' + name + '](#plotly.js-' + name + ')';
}

function makeBundleInfo(pathObj) {
var name = pathObj.name;
var sizes = findSizes(pathObj);
var moduleList = coreModules.concat(scrapeContent(pathObj));

return [
'### plotly.js ' + name,
'',
formatBundleInfo(name, moduleList),
'',
'| Way to import | 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 + ' |',
'| CommonJS | ' + '`require(\'plotly.js/lib/' + 'index-' + name + '\')`' + ' |',
'',
'| Raw size | Minified size | Minified + gzip size |',
'|------|-----------------|------------------------|',
'| ' + sizes.raw + ' | ' + sizes.minified + ' | ' + sizes.gzipped + ' | ',
''
].join('\n');
}

function findSizes(pathObj) {
var codeDist = fs.readFileSync(pathObj.dist, ENC),
codeDistMin = fs.readFileSync(pathObj.distMin, ENC);

var sizes = {
raw: prettySize(codeDist.length),
minified: prettySize(codeDistMin.length),
gzipped: prettySize(gzipSize.sync(codeDistMin))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it. 🍻

};

if(pathObj.withMeta) {
var codeWithMeta = fs.readFileSync(pathObj.withMeta, ENC);
sizes.withMeta = prettySize(codeWithMeta.length);
}

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(' ');
}