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.

95 lines
2.8 KiB

4 years ago
  1. var stripANSI = require('strip-ansi');
  2. var path = require('path');
  3. var objectAssign = require('object-assign');
  4. var os = require('os');
  5. var notifier = require('node-notifier');
  6. var DEFAULT_LOGO = path.join(__dirname, 'logo.png');
  7. var WebpackNotifierPlugin = module.exports = function(options) {
  8. this.options = options || {};
  9. this.lastBuildSucceeded = false;
  10. this.isFirstBuild = true;
  11. };
  12. WebpackNotifierPlugin.prototype.compileMessage = function(stats) {
  13. function findFirstDFS(compilation, key) {
  14. var match = compilation[key][0];
  15. if (match) {
  16. return match;
  17. }
  18. var children = compilation.children;
  19. for (var i = 0; i < children.length; ++i) {
  20. match = findFirstDFS(children[i], key);
  21. if (match) {
  22. return match;
  23. }
  24. }
  25. }
  26. if (this.isFirstBuild) {
  27. this.isFirstBuild = false;
  28. if (this.options.skipFirstNotification) {
  29. return;
  30. }
  31. }
  32. var error;
  33. if (stats.hasErrors()) {
  34. error = findFirstDFS(stats.compilation, 'errors');
  35. } else if (stats.hasWarnings() && !this.options.excludeWarnings) {
  36. error = findFirstDFS(stats.compilation, 'warnings');
  37. } else if (!this.lastBuildSucceeded || this.options.alwaysNotify) {
  38. this.lastBuildSucceeded = true;
  39. return (hasEmoji ? '✅ ' : '') + 'Build successful';
  40. } else {
  41. return;
  42. }
  43. this.lastBuildSucceeded = false;
  44. var message;
  45. if (error.module && error.module.rawRequest)
  46. message = error.module.rawRequest + '\n';
  47. var hasEmoji = this.options.emoji;
  48. if (error.error)
  49. message = (hasEmoji ? '❌ ' : '') + 'Error: ' + message + error.error.toString();
  50. else if (error.warning)
  51. message = (hasEmoji ? '⚠️ ' : '') + 'Warning: ' + message + error.warning.toString();
  52. else if (error.message) {
  53. message = (hasEmoji ? '⚠️ ' : '') + 'Warning: ' + message + error.message.toString();
  54. }
  55. return stripANSI(message);
  56. };
  57. WebpackNotifierPlugin.prototype.compilationDone = function(stats) {
  58. var msg = this.compileMessage(stats);
  59. if (msg) {
  60. var contentImage = ('contentImage' in this.options) ?
  61. this.options.contentImage : DEFAULT_LOGO;
  62. notifier.notify(objectAssign({
  63. title: 'Webpack',
  64. message: msg,
  65. contentImage: contentImage,
  66. icon: (os.platform() === 'win32' || os.platform() === 'linux') ? contentImage : undefined
  67. }, this.options));
  68. }
  69. };
  70. WebpackNotifierPlugin.prototype.apply = function(compiler) {
  71. if (compiler.hooks) {
  72. var plugin = { name: 'Notifier' };
  73. compiler.hooks.done.tap(plugin, this.compilationDone.bind(this));
  74. } else {
  75. compiler.plugin('done', this.compilationDone.bind(this));
  76. }
  77. };