webpack.config.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*eslint-env node*/
  2. var path = require('path'),
  3. webpack = require('webpack'),
  4. ExtractTextPlugin = require('extract-text-webpack-plugin');
  5. var staticPrefix = 'src/sentry/static/sentry',
  6. distPath = staticPrefix + '/dist';
  7. // this is set by setup.py sdist
  8. if (process.env.SENTRY_STATIC_DIST_PATH) {
  9. distPath = process.env.SENTRY_STATIC_DIST_PATH;
  10. }
  11. var babelQuery = {
  12. plugins: [],
  13. extra: {}
  14. };
  15. // only extract po files if we need to
  16. if (process.env.SENTRY_EXTRACT_TRANSLATIONS === '1') {
  17. babelQuery.plugins.push('babel-gettext-extractor');
  18. babelQuery.extra.gettext = {
  19. fileName: 'build/javascript.po',
  20. baseDirectory: path.join(__dirname, 'src/sentry'),
  21. functionNames: {
  22. gettext: ['msgid'],
  23. ngettext: ['msgid', 'msgid_plural', 'count'],
  24. gettextComponentTemplate: ['msgid'],
  25. t: ['msgid'],
  26. tn: ['msgid', 'msgid_plural', 'count'],
  27. tct: ['msgid']
  28. },
  29. };
  30. }
  31. var config = {
  32. context: path.join(__dirname, staticPrefix),
  33. entry: {
  34. // js
  35. 'app': 'app',
  36. 'translations': [
  37. 'app/translations'
  38. ],
  39. 'vendor': [
  40. 'babel-core/polyfill',
  41. 'bootstrap/js/dropdown',
  42. 'bootstrap/js/tab',
  43. 'bootstrap/js/tooltip',
  44. 'bootstrap/js/alert',
  45. 'crypto-js/md5',
  46. 'jed',
  47. 'jquery',
  48. 'marked',
  49. 'moment',
  50. 'moment-timezone',
  51. 'raven-js',
  52. 'react-document-title',
  53. 'react-router',
  54. 'react-bootstrap',
  55. 'reflux',
  56. 'select2',
  57. 'flot/jquery.flot',
  58. 'flot/jquery.flot.stack',
  59. 'flot/jquery.flot.time',
  60. 'flot-tooltip/jquery.flot.tooltip',
  61. 'vendor/simple-slider/simple-slider'
  62. ],
  63. // css
  64. // NOTE: this will also create an empty 'sentry.js' file
  65. // TODO: figure out how to not generate this
  66. 'sentry': 'less/sentry.less'
  67. },
  68. module: {
  69. loaders: [
  70. {
  71. test: /\.jsx?$/,
  72. loader: 'babel-loader',
  73. include: path.join(__dirname, staticPrefix),
  74. exclude: /(vendor|node_modules)/,
  75. query: babelQuery
  76. },
  77. {
  78. test: /\.po$/,
  79. loader: 'po-catalog-loader',
  80. query: {
  81. referenceExtensions: ['.js', '.jsx'],
  82. domain: 'sentry'
  83. }
  84. },
  85. {
  86. test: /\.json$/,
  87. loader: 'json-loader'
  88. },
  89. {
  90. test: /\.less$/,
  91. include: path.join(__dirname, staticPrefix),
  92. loader: ExtractTextPlugin.extract('style-loader', 'css-loader!less-loader')
  93. },
  94. {
  95. test: /\.(woff|woff2|ttf|eot|svg|png|gif|ico|jpg)($|\?)/,
  96. loader: 'file-loader?name=' + '[name].[ext]'
  97. }
  98. ]
  99. },
  100. plugins: [
  101. new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
  102. new webpack.optimize.DedupePlugin(),
  103. new webpack.ProvidePlugin({
  104. $: 'jquery',
  105. jQuery: 'jquery',
  106. 'window.jQuery': 'jquery',
  107. 'root.jQuery': 'jquery',
  108. Raven: 'raven-js'
  109. }),
  110. new ExtractTextPlugin('[name].css')
  111. ],
  112. resolve: {
  113. alias: {
  114. 'flot': path.join(__dirname, staticPrefix, 'vendor', 'jquery-flot'),
  115. 'flot-tooltip': path.join(__dirname, staticPrefix, 'vendor', 'jquery-flot-tooltip')
  116. },
  117. modulesDirectories: [path.join(__dirname, staticPrefix), 'node_modules'],
  118. extensions: ['', '.jsx', '.js', '.json']
  119. },
  120. output: {
  121. path: distPath,
  122. filename: '[name].js',
  123. libraryTarget: 'var',
  124. library: 'exports',
  125. sourceMapFilename: '[name].js.map',
  126. },
  127. devtool: 'source-map'
  128. };
  129. module.exports = config;