compile-js.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright 2018 Scytl Secure Electronic Voting SA
  3. *
  4. * All rights reserved
  5. *
  6. * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
  7. */
  8. /**
  9. * Js Tasks
  10. * @module tasks/compile-js
  11. */
  12. const gulp = require('gulp');
  13. const eslint = require('gulp-eslint');
  14. const cache = require('gulp-cached');
  15. const browserify = require('browserify');
  16. const babelify = require('babelify');
  17. const gutil = require('gulp-util');
  18. const gulpif = require('gulp-if');
  19. const uglify = require('gulp-uglify');
  20. const sourcemaps = require('gulp-sourcemaps');
  21. const source = require('vinyl-source-stream');
  22. const buffer = require('vinyl-buffer');
  23. const KarmaServer = require('karma').Server;
  24. const filesize = require('gulp-size');
  25. const addsrc = require('gulp-add-src');
  26. const concat = require('gulp-concat');
  27. const runSequence = require('run-sequence');
  28. const paths = require('../paths.json');
  29. const {
  30. getCommandArguments,
  31. notificationOnError,
  32. } = require('./helpers');
  33. const argv = getCommandArguments();
  34. const libBundle = browserify({
  35. entries : [paths.js.entryFile],
  36. debug : !argv.production || argv.debug,
  37. paths : [paths.js.src],
  38. cache : true,
  39. transform : [
  40. babelify.configure({
  41. presets : ['es2015'],
  42. sourceMaps : true,
  43. }),
  44. ],
  45. });
  46. /**
  47. * Checks and flags code that doesn't correspond to the
  48. * style guidelines configured under .eslintrc file
  49. *
  50. * @task js-lint
  51. */
  52. gulp.task('js-lint', (done) => {
  53. if (argv['skip-linting']) {
  54. console.log('[!] js-lint skipped [!]');
  55. done();
  56. return;
  57. }
  58. // ESLint ignores files with "node_modules" paths.
  59. // So, it's best to have gulp ignore the directory as well.
  60. // Also, Be sure to return the stream from the task;
  61. // Otherwise, the task may end before the stream has finished.
  62. return gulp.src([
  63. `${paths.js.src}/**/*.js`,
  64. ])
  65. .pipe(cache('js-lint', { optimizeMemory: true }))
  66. // eslint() attaches the lint output to the "eslint" property
  67. // of the file object so it can be used by other modules.
  68. .pipe(eslint())
  69. // eslint.format() outputs the lint results to the console.
  70. // Alternatively use eslint.formatEach() (see Docs).
  71. .pipe(eslint.format())
  72. // To have the process exit with an error code (1) on
  73. // lint error, return the stream and pipe to failOnError last.
  74. .pipe(gulpif(!argv.force, eslint.failAfterError()))
  75. .on('error', notificationOnError('\uD83D\uDE25 Linting errors found!', '<%= error.message %>'));
  76. });
  77. /**
  78. * Runs the unit tests test/unit folder
  79. *
  80. * @task unit-tests
  81. */
  82. gulp.task('unit-tests', (done) => {
  83. if (argv['skip-unit-tests']) {
  84. console.log('[!] unit-tests skipped [!]');
  85. done();
  86. return;
  87. }
  88. runSequence(
  89. 'unit-tests:all',
  90. // 'unit-tests:precompute',
  91. // 'unit-tests:proofs',
  92. done
  93. );
  94. });
  95. gulp.task('unit-tests:all', [], (done) => {
  96. new KarmaServer({
  97. configFile : __dirname + '/../karma.conf.js',
  98. singleRun : true,
  99. }, done).start();
  100. });
  101. gulp.task('unit-tests:precompute', (done) => {
  102. new KarmaServer({
  103. configFile : __dirname + '/../karma-precompute.conf.js',
  104. singleRun : true,
  105. }, done).start();
  106. });
  107. gulp.task('unit-tests:proofs', (done) => {
  108. new KarmaServer({
  109. configFile : __dirname + '/../karma-proofs.conf.js',
  110. singleRun : true,
  111. }, done).start();
  112. });
  113. /**
  114. * Bundles, minifies (if production flag is true), generates the
  115. * source maps and suffixes project's version to the resulted bundle file
  116. * for the provided browserify stream.
  117. *
  118. * @param {BrowserifyObject} browserifyStream
  119. * @param {String} bundleFilename The desired filename for the bundle
  120. */
  121. const compileBundle = (browserifyStream, bundleFilename, uglifyCode = true) => {
  122. return browserifyStream.bundle()
  123. .on('error', gutil.log)
  124. .pipe(source(bundleFilename))
  125. .pipe(buffer())
  126. .pipe(addsrc([`${paths.js.crypto}/forge.min.js`]))
  127. .pipe(addsrc([`${paths.js.crypto}/sjcl.js`]))
  128. .pipe(concat(uglifyCode ? paths.js.bundleMinFile : paths.js.bundleFile))
  129. .pipe(
  130. gulpif(
  131. (!argv.production || argv.debug),
  132. sourcemaps.init({ loadMaps: true })
  133. )
  134. )
  135. .pipe(gulpif(uglifyCode, uglify()))
  136. .pipe(
  137. gulpif(
  138. (!argv.production || argv.debug),
  139. sourcemaps.write('./', { includeContent: true, sourceRoot: '/ov-api' })
  140. )
  141. )
  142. .pipe(filesize({ showFiles: true }));
  143. }
  144. /**
  145. * Bundles, minifies (if production arg is true), generates the source maps
  146. * (if no production arg was passed or debug args is present along with production arg)
  147. * and suffixes project's version to the resulted bundle file for the provided browserify stream.
  148. *
  149. * @task build-js
  150. */
  151. gulp.task('build-js', ['build-js:include-sjcl', 'build-js:include-node-forge'], () => {
  152. return compileBundle(libBundle, paths.js.bundleFile)
  153. .pipe(gulp.dest(`${paths.js.dist}`));
  154. });
  155. gulp.task('build-js:include-node-forge', () => {
  156. return gulp.src(['./node_modules/node-forge/dist/forge.min.js'])
  157. .pipe(gulp.dest(paths.js.crypto));
  158. });
  159. gulp.task('build-js:include-sjcl', () => {
  160. return gulp.src(['./node_modules/sjcl/sjcl.js'])
  161. .pipe(gulp.dest(paths.js.crypto));
  162. });
  163. gulp.task('build-js:for-doc', () => {
  164. return compileBundle(libBundle, paths.js.bundleFile, false)
  165. .pipe(gulp.dest('./dist/doc/src'));
  166. });
  167. gulp.task('watch:js', () => {
  168. gulp.watch(
  169. [
  170. `${paths.js.src}/**/*.js`,
  171. `${paths.js.src}/**/*.coffee`,
  172. ],
  173. [
  174. 'build-js',
  175. ]
  176. );
  177. });