webpack.config.js 5.85 KB
Newer Older
1 2
'use strict';

3
var fs = require('fs');
4 5 6
var path = require('path');
var webpack = require('webpack');
var StatsPlugin = require('stats-webpack-plugin');
7
var CompressionPlugin = require('compression-webpack-plugin');
8
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
9

10
var ROOT_PATH = path.resolve(__dirname, '..');
11
var IS_PRODUCTION = process.env.NODE_ENV === 'production';
12
var IS_DEV_SERVER = process.argv[1].indexOf('webpack-dev-server') !== -1;
13
var DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808;
14
var DEV_SERVER_LIVERELOAD = process.env.DEV_SERVER_LIVERELOAD !== 'false';
15
var WEBPACK_REPORT = process.env.WEBPACK_REPORT;
16 17

var config = {
18
  context: path.join(ROOT_PATH, 'app/assets/javascripts'),
19
  entry: {
20
    common:               './commons/index.js',
21
    common_vue:           ['vue', 'vue-resource'],
22
    common_d3:            ['d3'],
23
    main:                 './main.js',
24 25
    blob_edit:            './blob_edit/blob_edit_bundle.js',
    boards:               './boards/boards_bundle.js',
Phil Hughes's avatar
Phil Hughes committed
26
    simulate_drag:        './test_utils/simulate_drag.js',
27
    cycle_analytics:      './cycle_analytics/cycle_analytics_bundle.js',
28
    commit_pipelines:     './commit/pipelines/pipelines_bundle.js',
29 30
    diff_notes:           './diff_notes/diff_notes_bundle.js',
    environments:         './environments/environments_bundle.js',
Filipa Lacerda's avatar
Filipa Lacerda committed
31
    environments_folder:  './environments/folder/environments_folder_bundle.js',
32
    filtered_search:      './filtered_search/filtered_search_bundle.js',
33
    graphs:               './graphs/graphs_bundle.js',
34
    groups_list:          './groups_list.js',
35
    issuable:             './issuable/issuable_bundle.js',
36 37 38 39 40 41 42 43
    merge_conflicts:      './merge_conflicts/merge_conflicts_bundle.js',
    merge_request_widget: './merge_request_widget/ci_bundle.js',
    network:              './network/network_bundle.js',
    profile:              './profile/profile_bundle.js',
    protected_branches:   './protected_branches/protected_branches_bundle.js',
    snippet:              './snippet/snippet_bundle.js',
    terminal:             './terminal/terminal_bundle.js',
    users:                './users/users_bundle.js',
Mike Greiling's avatar
Mike Greiling committed
44
    vue_pipelines:        './vue_pipelines_index/index.js',
45 46 47 48 49
  },

  output: {
    path: path.join(ROOT_PATH, 'public/assets/webpack'),
    publicPath: '/assets/webpack/',
50
    filename: IS_PRODUCTION ? '[name].[chunkhash].bundle.js' : '[name].bundle.js'
51 52
  },

53
  devtool: 'inline-source-map',
54

55
  module: {
Mike Greiling's avatar
Mike Greiling committed
56
    rules: [
57
      {
58 59
        test: /\.(js|es6)$/,
        exclude: /(node_modules|vendor\/assets)/,
60
        loader: 'babel-loader',
Mike Greiling's avatar
Mike Greiling committed
61 62 63 64 65
        options: {
          presets: [
            ["es2015", {"modules": false}],
            'stage-2'
          ]
66
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
67 68 69 70
      },
      {
        test: /\.svg$/,
        use: 'raw-loader'
71 72 73 74
      }
    ]
  },

75 76 77 78 79 80 81 82 83
  plugins: [
    // manifest filename must match config.webpack.manifest_filename
    // webpack-rails only needs assetsByChunkName to function properly
    new StatsPlugin('manifest.json', {
      chunkModules: false,
      source: false,
      chunks: false,
      modules: false,
      assets: true
Phil Hughes's avatar
Phil Hughes committed
84
    }),
Mike Greiling's avatar
Mike Greiling committed
85 86

    // prevent pikaday from including moment.js
Phil Hughes's avatar
Phil Hughes committed
87
    new webpack.IgnorePlugin(/moment/, /pikaday/),
Mike Greiling's avatar
Mike Greiling committed
88

89 90 91 92 93 94
    // fix legacy jQuery plugins which depend on globals
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
    }),

95 96 97 98
    // use deterministic module ids in all environments
    IS_PRODUCTION ?
      new webpack.HashedModuleIdsPlugin() :
      new webpack.NamedModulesPlugin(),
99

100 101 102 103 104 105 106 107 108 109 110 111 112 113
    // create cacheable common library bundle for all vue chunks
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common_vue',
      chunks: [
        'boards',
        'commit_pipelines',
        'cycle_analytics',
        'diff_notes',
        'environments',
        'environments_folder',
        'issuable',
        'merge_conflicts',
        'vue_pipelines',
      ],
114 115 116
      minChunks: function(module, count) {
        return module.resource && (/vue_shared/).test(module.resource);
      },
117 118
    }),

119 120 121 122 123 124
    // create cacheable common library bundle for all d3 chunks
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common_d3',
      chunks: ['graphs', 'users'],
    }),

125
    // create cacheable common library bundles
126
    new webpack.optimize.CommonsChunkPlugin({
127
      names: ['main', 'common', 'runtime'],
128
    }),
129 130 131
  ],

  resolve: {
Mike Greiling's avatar
Mike Greiling committed
132
    extensions: ['.js', '.es6', '.js.es6'],
133
    alias: {
134
      '~':              path.join(ROOT_PATH, 'app/assets/javascripts'),
135
      'emojis':         path.join(ROOT_PATH, 'fixtures/emojis'),
136
      'empty_states':   path.join(ROOT_PATH, 'app/views/shared/empty_states'),
137
      'icons':          path.join(ROOT_PATH, 'app/views/shared/icons'),
138
      'vendor':         path.join(ROOT_PATH, 'vendor/assets/javascripts'),
139
      'vue$':           'vue/dist/vue.common.js',
140
    }
141
  }
142 143
}

144
if (IS_PRODUCTION) {
145
  config.devtool = 'source-map';
146
  config.plugins.push(
147
    new webpack.NoEmitOnErrorsPlugin(),
Mike Greiling's avatar
Mike Greiling committed
148 149 150 151
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),
152
    new webpack.optimize.UglifyJsPlugin({
Mike Greiling's avatar
Mike Greiling committed
153
      sourceMap: true
154 155 156
    }),
    new webpack.DefinePlugin({
      'process.env': { NODE_ENV: JSON.stringify('production') }
157 158 159
    }),
    new CompressionPlugin({
      asset: '[path].gz[query]',
Mike Greiling's avatar
Mike Greiling committed
160
    })
161
  );
162 163 164
}

if (IS_DEV_SERVER) {
165 166
  config.devServer = {
    port: DEV_SERVER_PORT,
167 168
    headers: { 'Access-Control-Allow-Origin': '*' },
    stats: 'errors-only',
169
    inline: DEV_SERVER_LIVERELOAD
170 171 172 173
  };
  config.output.publicPath = '//localhost:' + DEV_SERVER_PORT + config.output.publicPath;
}

174 175 176 177 178 179 180 181 182 183 184 185
if (WEBPACK_REPORT) {
  config.plugins.push(
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
      generateStatsFile: true,
      openAnalyzer: false,
      reportFilename: path.join(ROOT_PATH, 'webpack-report/index.html'),
      statsFilename: path.join(ROOT_PATH, 'webpack-report/stats.json'),
    })
  );
}

186
module.exports = config;