Skip to content

Custom bundle script details #5527

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 24 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9fe3255
improve partial bundle script
archmoj Feb 25, 2021
ca4d557
fixup defaults
archmoj Feb 26, 2021
ba00b93
dev-install exorcist v1.0.1
archmoj Mar 1, 2021
cbb431e
externalize the source map file
archmoj Mar 1, 2021
5aa2234
drop sourcemap and unminified options
archmoj Mar 1, 2021
7de7be9
remove keepIndex option and keep index in lib for sourcemap
archmoj Mar 1, 2021
df8005a
fixup including calendars and transforms in extra bundles
archmoj Mar 1, 2021
efa9357
do not expose calendars option for now - unti one could safely drop them
archmoj Mar 1, 2021
9ca5d44
centralize function to create transforms and traces lists
archmoj Mar 1, 2021
9d34652
fixup debug X sourcemap intersect
archmoj Mar 1, 2021
0869970
filter filenames when creating traces and transforms lists
archmoj Mar 1, 2021
7d0145a
make only minified with sourcemap
archmoj Mar 1, 2021
fa35c86
drop unused require
archmoj Mar 1, 2021
65efc42
centralize function to test filenames with lowercase
archmoj Mar 1, 2021
b05beef
pass extra options to uglify for sourcemap
archmoj Mar 1, 2021
fc25200
point to bundle
archmoj Mar 1, 2021
bcb7967
improve config
archmoj Mar 1, 2021
9411d7f
put derequire back
archmoj Mar 1, 2021
1e21747
uninstall exorcist v1.0.1 until there prototype pollution is fixed
archmoj Mar 2, 2021
34c09c3
drop sourcemap option
archmoj Mar 2, 2021
6974914
add unminified option
archmoj Mar 2, 2021
4b0f1da
delete index-custom after bundle
archmoj Mar 2, 2021
90bf969
update comment
archmoj Mar 2, 2021
3693985
add a comma to end of calendars require so that it could be easily dr…
archmoj Mar 2, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
"elliptic": "^6.5.3",
"eslint": "^7.17.0",
"espree": "^7.3.1",
"exorcist": "^1.0.1",
"extra-iterable": "^2.5.14",
"falafel": "^2.2.4",
"fs-extra": "^9.0.1",
Expand Down
4 changes: 3 additions & 1 deletion tasks/extra_bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ for(var i = 0; i < partialBundlePaths.length; i++) {
index: opts.index,
dist: opts.dist,
distMin: opts.distMin,
traceList: opts.traceList
traceList: opts.traceList,
transformList: opts.transformList,
calendars: opts.calendars
});
}

Expand Down
124 changes: 83 additions & 41 deletions tasks/partial_bundle.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var path = require('path');
var minimist = require('minimist');
var runSeries = require('run-series');
var prependFile = require('prepend-file');

Expand All @@ -7,41 +8,69 @@ var common = require('./util/common');
var _bundle = require('./util/browserify_wrapper');

var header = constants.licenseDist + '\n';
var allTransforms = constants.allTransforms;
var allTraces = constants.allTraces;
var mainIndex = constants.mainIndex;

var argv = process.argv;

if(argv.length > 2) {
// command line

var traceList = ['scatter']; // added by default
var name;
for(var i = 2; i < argv.length; i++) {
var a = argv[i];

function createList(outList, inList, allList, type) {
for(var i = 0; i < inList.length; i++) {
var t = inList[i];
if(
allTraces.indexOf(a) !== -1 && // requested
traceList.indexOf(a) === -1 // not added before
outList.indexOf(t) === -1 // not added before
) {
traceList.push(a);
if(allList.indexOf(t) === -1) {
console.error(t, 'is not a valid ' + type + '!', 'Valid ' + type + 's are:', allList);
} else {
outList.push(t);
}
}
if(a.indexOf('--name=') === 0) name = a.replace('--name=', '');
}
if(!name) name = 'custom';
traceList = traceList.sort();

var opts = {
traceList: traceList,
name: name,
return outList.sort();
}

function isFalse(a) {
return (
a === 'none' ||
a === 'false'
);
}

index: path.join(constants.pathToBuild, 'index-' + name + '.js'),
dist: path.join(constants.pathToDist, 'plotly-' + name + '.js'),
distMin: path.join(constants.pathToDist, 'plotly-' + name + '.min.js')
function inputArray(a, dflt) {
dflt = dflt.slice();

return (
isFalse(a) ? [] :
!a || a === 'all' ? dflt :
a.split(',')
);
}

if(process.argv.length > 2) {
// command line

var args = minimist(process.argv.slice(2), {});

// parse arguments
var out = args.out ? args.out : 'custom';
var traces = inputArray(args.traces, allTraces);
var transforms = inputArray(args.transforms, allTransforms);

var opts = {
traceList: createList(['scatter'], traces, allTraces, 'trace'),
transformList: createList([], transforms, allTransforms, 'transform'),

name: out,
index: path.join(constants.pathToLib, 'index-' + out + '.js'),
sourceMap: path.join(constants.pathToDist, 'plotly-' + out + '.js.map'),
dist: path.join(constants.pathToDist, 'plotly-' + out + '.js'),
distMin: path.join(constants.pathToDist, 'plotly-' + out + '.min.js')
};

console.log(opts);

opts.calendars = true;

var tasks = [];

partialBundle(tasks, opts);
Expand All @@ -58,40 +87,53 @@ function partialBundle(tasks, opts) {
var dist = opts.dist;
var distMin = opts.distMin;
var traceList = opts.traceList;
var transformList = opts.transformList;
var calendars = opts.calendars;
var sourceMap = opts.sourceMap;

tasks.push(function(done) {
var partialIndex = mainIndex;
allTraces.forEach(function(trace) {
if(traceList.indexOf(trace) === -1) {
var WHITESPACE_BEFORE = '\\s*';
// remove require
var newCode = partialIndex.replace(
new RegExp(
WHITESPACE_BEFORE +
'require\\(\'\\./' + trace + '\'\\),',
'g'), ''
);

// test removal
if(newCode === partialIndex) throw 'Unable to find and drop require for trace: "' + trace + '"';

partialIndex = newCode;

var all = ['calendars'].concat(allTransforms).concat(allTraces);
var includes = (calendars ? ['calendars'] : []).concat(transformList).concat(traceList);
var excludes = all.filter(function(e) { return includes.indexOf(e) === -1; });

excludes.forEach(function(t) {
var WHITESPACE_BEFORE = '\\s*';
// remove require
var newCode = partialIndex.replace(
new RegExp(
WHITESPACE_BEFORE +
'require\\(\'\\./' + t + '\'\\)' +
(t === 'calendars' ? '' : ','), // there is no comma after calendars require
Copy link
Collaborator

Choose a reason for hiding this comment

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

Feels a bit fragile - can we either just make the comma optional in the pattern, or add the comma in lib/index so all the lines are equivalent?

'g'), ''
);

// test removal
if(newCode === partialIndex) {
console.error('Unable to find and drop require for ' + t);
throw 'Error generating index for partial bundle!';
}

partialIndex = newCode;
});

common.writeFile(index, partialIndex, done);
});

tasks.push(function(done) {
_bundle(index, dist, {
var bundleOpts = {
pathToSourceMap: sourceMap,
standalone: 'Plotly',
pathToMinBundle: distMin
}, function() {
};

_bundle(index, dist, bundleOpts, function() {
var headerDist = header.replace('plotly.js', 'plotly.js (' + name + ')');
var headerDistMin = header.replace('plotly.js', 'plotly.js (' + name + ' - minified)');

prependFile(dist, headerDist, common.throwOnError);
prependFile(distMin, headerDistMin, common.throwOnError);
if(dist) prependFile(dist, headerDist, common.throwOnError);
if(distMin) prependFile(distMin, headerDistMin, common.throwOnError);

done();
});
Expand Down
36 changes: 24 additions & 12 deletions tasks/util/browserify_wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var browserify = require('browserify');
var minify = require('minify-stream');
var derequire = require('derequire');
var through = require('through2');
var exorcist = require('exorcist');

var constants = require('./constants');
var strictD3 = require('./strict_d3');
Expand All @@ -22,9 +23,8 @@ var strictD3 = require('./strict_d3');
* - noCompress {boolean} skip attribute meta compression?
* @param {function} cb callback
*
* Outputs one bundle (un-minified) file if opts.pathToMinBundle is omitted
* or opts.debug is true. Otherwise outputs two file: one un-minified bundle and
* one minified bundle.
* Outputs one bundle (un-minified) file if opts.pathToMinBundle is omitted.
* Otherwise outputs two file: one un-minified bundle and one minified bundle.
*
* Logs basename of bundle when completed.
*/
Expand All @@ -35,7 +35,8 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {

var browserifyOpts = {};
browserifyOpts.standalone = opts.standalone;
browserifyOpts.debug = opts.debug;
var sourceMap = opts.pathToSourceMap;
browserifyOpts.debug = opts.debug || sourceMap;

if(opts.noCompress) {
browserifyOpts.ignoreTransform = './tasks/compress_attributes.js';
Expand All @@ -47,7 +48,7 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
}

var b = browserify(pathToIndex, browserifyOpts);
var pending = pathToMinBundle ? 2 : 1;
var pending = (pathToMinBundle && pathToBundle) ? 2 : 1;

function done() {
if(cb && --pending === 0) cb(null);
Expand All @@ -71,13 +72,24 @@ module.exports = function _bundle(pathToIndex, pathToBundle, opts, cb) {
});
}

bundleStream
.pipe(applyDerequire())
.pipe(fs.createWriteStream(pathToBundle))
.on('finish', function() {
logger(pathToBundle);
done();
});
if(sourceMap) {
bundleStream
.pipe(applyDerequire())
.pipe(exorcist(sourceMap))
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is generating the sourcemap of the unminified bundle. The real value is in a sourcemap of the minified bundle (which, for clarity, gets extension .min.js.map), then you never need the unminified bundle.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. Addressed in 7d0145a.

.pipe(fs.createWriteStream(pathToBundle))
.on('finish', function() {
logger(pathToBundle);
done();
});
} else {
bundleStream
.pipe(applyDerequire())
.pipe(fs.createWriteStream(pathToBundle))
.on('finish', function() {
logger(pathToBundle);
done();
});
}
};

function logger(pathToOutput) {
Expand Down
15 changes: 12 additions & 3 deletions tasks/util/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,15 @@ var pathToBuild = path.join(pathToRoot, 'build/');

var pathToPlotlyIndex = path.join(pathToLib, 'index.js');
var mainIndex = fs.readFileSync(pathToPlotlyIndex, 'utf-8');
var pathToPlotlyTraces = path.join(pathToSrc, 'traces');
var allTraces = fs.readdirSync(pathToPlotlyTraces);
var allTraces = fs.readdirSync(path.join(pathToSrc, 'traces'))
.filter(function(v) {
return v.charAt(0) !== v.charAt(0).toUpperCase();
});
var allTransforms = fs.readdirSync(path.join(pathToSrc, 'transforms'))
.filter(function(v) {
return v.charAt(0) !== v.charAt(0).toUpperCase() && v !== 'helpers.js';
})
.map(function(e) { return e.replace('.js', ''); });

var pathToTopojsonSrc;
try {
Expand Down Expand Up @@ -140,6 +147,8 @@ function makePartialBundleOpts(name) {
return {
name: name,
traceList: partialBundleTraces[name],
transformList: allTransforms,
calendars: true,
index: path.join(pathToLib, 'index-' + name + '.js'),
dist: path.join(pathToDist, 'plotly-' + name + '.js'),
distMin: path.join(pathToDist, 'plotly-' + name + '.min.js')
Expand All @@ -157,10 +166,10 @@ module.exports = {
pathToBuild: pathToBuild,
pathToDist: pathToDist,

allTransforms: allTransforms,
allTraces: allTraces,
mainIndex: mainIndex,
pathToPlotlyIndex: pathToPlotlyIndex,
pathToPlotlyTraces: pathToPlotlyTraces,
pathToPlotlyCore: path.join(pathToSrc, 'core.js'),
pathToPlotlyVersion: path.join(pathToSrc, 'version.js'),
pathToPlotlyBuild: path.join(pathToBuild, 'plotly.js'),
Expand Down