server.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import Promise from 'bluebird';
  2. import browserify from 'browserify';
  3. import budo from 'budo';
  4. import fs from 'fs';
  5. import glob from 'glob';
  6. import mkdirp from 'mkdirp';
  7. import path from 'path';
  8. /* eslint no-console: 0 */
  9. const pkg = require(path.join(__dirname, '../package.json'));
  10. // Replace "%s" tokens with the plugin name in a string.
  11. const nameify = (str) =>
  12. str.replace(/%s/g, pkg.name.split('/').reverse()[0]);
  13. const srces = {
  14. js: 'src/plugin.js',
  15. tests: glob.sync('test/**/*.test.js')
  16. };
  17. const dests = {
  18. js: nameify('dist/%s.js'),
  19. tests: 'test/dist/bundle.js'
  20. };
  21. const bundlers = {
  22. js: browserify({
  23. debug: true,
  24. entries: [srces.js],
  25. standalone: nameify('%s'),
  26. transform: [
  27. 'babelify'
  28. ]
  29. }),
  30. tests: browserify({
  31. debug: true,
  32. entries: srces.tests,
  33. transform: [
  34. 'babelify',
  35. 'browserify-shim'
  36. ]
  37. })
  38. };
  39. const bundle = (name) => {
  40. return new Promise((resolve, reject) => {
  41. bundlers[name]
  42. .bundle()
  43. .pipe(fs.createWriteStream(dests[name]))
  44. .on('finish', resolve)
  45. .on('error', reject);
  46. });
  47. };
  48. mkdirp.sync('dist');
  49. // Start the server _after_ the initial bundling is done.
  50. Promise.all([bundle('js'), bundle('tests')]).then(() => {
  51. const server = budo({
  52. port: 9999,
  53. stream: process.stdout
  54. }).on('reload', (f) => console.log('reloading %s', f || 'everything'));
  55. /**
  56. * A collection of functions which are mapped to strings that are used to
  57. * generate RegExp objects. If a filepath matches the RegExp, the function
  58. * will be used to handle that watched file.
  59. *
  60. * @type {Object}
  61. */
  62. const handlers = {
  63. /**
  64. * Handler for JavaScript source.
  65. *
  66. * @param {String} event
  67. * @param {String} file
  68. */
  69. '^src/.+\.js$'(event, file) {
  70. console.log('re-bundling javascript and tests');
  71. Promise.all([bundle('js'), bundle('tests')]).then(() => server.reload());
  72. },
  73. /**
  74. * Handler for JavaScript tests.
  75. *
  76. * @param {String} event
  77. * @param {String} file
  78. */
  79. '^test/.+\.test\.js$'(event, file) {
  80. console.log('re-bundling tests');
  81. bundle('tests').then(() => server.reload());
  82. }
  83. };
  84. /**
  85. * Finds the first handler function for the file that matches a RegExp
  86. * derived from the keys.
  87. *
  88. * @param {String} file
  89. * @return {Function|Undefined}
  90. */
  91. const findHandler = (file) => {
  92. const keys = Object.keys(handlers);
  93. for (let i = 0; i < keys.length; i++) {
  94. let regex = new RegExp(keys[i]);
  95. if (regex.test(file)) {
  96. return handlers[keys[i]];
  97. }
  98. }
  99. };
  100. server
  101. .live()
  102. .watch([
  103. 'index.html',
  104. 'src/**/*.js',
  105. 'test/**/*.test.js',
  106. 'test/index.html'
  107. ])
  108. .on('watch', (event, file) => {
  109. const handler = findHandler(file);
  110. console.log(`detected a "${event}" event in "${file}"`);
  111. if (handler) {
  112. handler(event, file);
  113. } else {
  114. server.reload();
  115. }
  116. });
  117. });