vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
7.5 KiB

  1. var fs = require('fs');
  2. var async = require('async');
  3. var gulp = require('gulp');
  4. var eslint = require('gulp-eslint');
  5. var gutil = require('gulp-util');
  6. var concat = require('gulp-concat');
  7. var cleanCSS = require('gulp-clean-css');
  8. var rename = require("gulp-rename");
  9. var webpack = require('webpack');
  10. var uglify = require('uglify-js');
  11. var rimraf = require('rimraf');
  12. var argv = require('yargs').argv;
  13. var ENTRY = './index.js';
  14. var HEADER = './lib/header.js';
  15. var DIST = __dirname + '/dist';
  16. var VIS_JS = 'vis.js';
  17. var VIS_MAP = 'vis.map';
  18. var VIS_MIN_JS = 'vis.min.js';
  19. var VIS_CSS = 'vis.css';
  20. var VIS_MIN_CSS = 'vis.min.css';
  21. var INDIVIDUAL_JS_BUNDLES = [
  22. {entry: './index-timeline-graph2d.js', filename: 'vis-timeline-graph2d.min.js'},
  23. {entry: './index-network.js', filename: 'vis-network.min.js'},
  24. {entry: './index-graph3d.js', filename: 'vis-graph3d.min.js'}
  25. ];
  26. var INDIVIDUAL_CSS_BUNDLES = [
  27. {entry: ['./lib/shared/**/*.css', './lib/timeline/**/*.css'], filename: 'vis-timeline-graph2d.min.css'},
  28. {entry: ['./lib/shared/**/*.css', './lib/network/**/*.css'], filename: 'vis-network.min.css'}
  29. ];
  30. // generate banner with today's date and correct version
  31. function createBanner() {
  32. var today = gutil.date(new Date(), 'yyyy-mm-dd'); // today, formatted as yyyy-mm-dd
  33. var version = require('./package.json').version;
  34. return String(fs.readFileSync(HEADER))
  35. .replace('@@date', today)
  36. .replace('@@version', version);
  37. }
  38. var bannerPlugin = new webpack.BannerPlugin({
  39. banner: createBanner(),
  40. entryOnly: true,
  41. raw: true
  42. });
  43. var webpackModule = {
  44. loaders: [
  45. {
  46. test: /\.js$/,
  47. exclude: /node_modules/,
  48. loader: 'babel-loader',
  49. query: {
  50. cacheDirectory: true, // use cache to improve speed
  51. babelrc: true // use the .baberc file
  52. }
  53. }
  54. ],
  55. // exclude requires of moment.js language files
  56. wrappedContextRegExp: /$^/
  57. };
  58. var webpackConfig = {
  59. entry: ENTRY,
  60. output: {
  61. library: 'vis',
  62. libraryTarget: 'umd',
  63. path: DIST,
  64. filename: VIS_JS,
  65. sourcePrefix: ' '
  66. },
  67. module: webpackModule,
  68. plugins: [ bannerPlugin ],
  69. cache: true,
  70. // generate details sourcempas of webpack modules
  71. devtool: 'source-map'
  72. //debug: true,
  73. //bail: true
  74. };
  75. var uglifyConfig = {
  76. outSourceMap: VIS_MAP,
  77. output: {
  78. comments: /@license/
  79. }
  80. };
  81. // create a single instance of the compiler to allow caching
  82. var compiler = webpack(webpackConfig);
  83. function handleCompilerCallback (err, stats) {
  84. if (err) {
  85. gutil.log(err.toString());
  86. }
  87. if (stats && stats.compilation && stats.compilation.errors) {
  88. // output soft errors
  89. stats.compilation.errors.forEach(function (err) {
  90. gutil.log(err.toString());
  91. });
  92. if (err || stats.compilation.errors.length > 0) {
  93. gutil.beep(); // TODO: this does not work on my system
  94. }
  95. }
  96. }
  97. // clean the dist/img directory
  98. gulp.task('clean', function (cb) {
  99. rimraf(DIST + '/img', cb);
  100. });
  101. gulp.task('bundle-js', function (cb) {
  102. // update the banner contents (has a date in it which should stay up to date)
  103. bannerPlugin.banner = createBanner();
  104. compiler.run(function (err, stats) {
  105. handleCompilerCallback(err, stats);
  106. cb();
  107. });
  108. });
  109. // create individual bundles for timeline+graph2d, network, graph3d
  110. gulp.task('bundle-js-individual', function (cb) {
  111. // update the banner contents (has a date in it which should stay up to date)
  112. bannerPlugin.banner = createBanner();
  113. async.each(INDIVIDUAL_JS_BUNDLES, function (item, callback) {
  114. var webpackTimelineConfig = {
  115. entry: item.entry,
  116. output: {
  117. library: 'vis',
  118. libraryTarget: 'umd',
  119. path: DIST,
  120. filename: item.filename,
  121. sourcePrefix: ' '
  122. },
  123. module: webpackModule,
  124. plugins: [ bannerPlugin, new webpack.optimize.UglifyJsPlugin() ],
  125. cache: true
  126. };
  127. var compiler = webpack(webpackTimelineConfig);
  128. compiler.run(function (err, stats) {
  129. handleCompilerCallback(err, stats);
  130. callback();
  131. });
  132. }, cb);
  133. });
  134. // bundle and minify css
  135. gulp.task('bundle-css', function () {
  136. return gulp.src('./lib/**/*.css')
  137. .pipe(concat(VIS_CSS))
  138. .pipe(gulp.dest(DIST))
  139. // TODO: nicer to put minifying css in a separate task?
  140. .pipe(cleanCSS())
  141. .pipe(rename(VIS_MIN_CSS))
  142. .pipe(gulp.dest(DIST));
  143. });
  144. // bundle and minify individual css
  145. gulp.task('bundle-css-individual', function (cb) {
  146. async.each(INDIVIDUAL_CSS_BUNDLES, function (item, callback) {
  147. return gulp.src(item.entry)
  148. .pipe(concat(item.filename))
  149. .pipe(cleanCSS())
  150. .pipe(rename(item.filename))
  151. .pipe(gulp.dest(DIST))
  152. .on('end', callback);
  153. }, cb);
  154. });
  155. gulp.task('copy', ['clean'], function () {
  156. var network = gulp.src('./lib/network/img/**/*')
  157. .pipe(gulp.dest(DIST + '/img/network'));
  158. return network;
  159. });
  160. gulp.task('minify', ['bundle-js'], function (cb) {
  161. var result = uglify.minify([DIST + '/' + VIS_JS], uglifyConfig);
  162. // note: we add a newline '\n' to the end of the minified file to prevent
  163. // any issues when concatenating the file downstream (the file ends
  164. // with a comment).
  165. fs.writeFileSync(DIST + '/' + VIS_MIN_JS, result.code + '\n');
  166. fs.writeFileSync(DIST + '/' + VIS_MAP, result.map.replace(/"\.\/dist\//g, '"'));
  167. cb();
  168. });
  169. gulp.task('bundle', ['bundle-js', 'bundle-js-individual', 'bundle-css', 'bundle-css-individual', 'copy']);
  170. // read command line arguments --bundle and --minify
  171. var bundle = 'bundle' in argv;
  172. var minify = 'minify' in argv;
  173. var watchTasks = [];
  174. if (bundle || minify) {
  175. // do bundling and/or minifying only when specified on the command line
  176. watchTasks = [];
  177. if (bundle) watchTasks.push('bundle');
  178. if (minify) watchTasks.push('minify');
  179. }
  180. else {
  181. // by default, do both bundling and minifying
  182. watchTasks = ['bundle', 'minify'];
  183. }
  184. // The watch task (to automatically rebuild when the source code changes)
  185. gulp.task('watch', watchTasks, function () {
  186. gulp.watch(['index.js', 'lib/**/*'], watchTasks);
  187. });
  188. ////////////////////////////////////////////////////////////////////////////////////////
  189. // Linting
  190. //
  191. // Linting has intentionally NOT been added yet to the default task; there are simply
  192. // too many errors at the moment to make this comfortable. Run it separately with:
  193. //
  194. // > gulp lint or > gulp lint-<module name>
  195. //
  196. // This is set up so that 'gulp lint' runs the linting over the complete lib directory.
  197. // You can also run linting on the separate modules, e.g. 'gulp lint-network' for just
  198. // the network module. Scan the tasks below for the available lint commands.
  199. //
  200. // Note that currently a separate lint is missing for Graph2d, DataSet and DataGroup.
  201. ////////////////////////////////////////////////////////////////////////////////////////
  202. function runLintTask(pathPrefix) {
  203. return gulp.src([ pathPrefix + '/**/*.js', '!node_modules/**'])
  204. .pipe(eslint())
  205. .pipe(eslint.format())
  206. .pipe(eslint.failAfterError());
  207. }
  208. gulp.task('lint', function () {return runLintTask('lib');});
  209. gulp.task('lint-timeline', function () {return runLintTask('lib/timeline');});
  210. gulp.task('lint-network', function () {return runLintTask('lib/network');});
  211. gulp.task('lint-graph3d', function () {return runLintTask('lib/graph3d');});
  212. ////////////////////////////////////////////////////////////////////////////////////////
  213. // End Linting
  214. ////////////////////////////////////////////////////////////////////////////////////////
  215. // The default task (called when you run `gulp`)
  216. gulp.task('default', ['clean', 'bundle', 'minify']);