BigW Consortium Gitlab

webpack.config.js 6.92 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
var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
10

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

var config = {
20
  context: path.join(ROOT_PATH, 'app/assets/javascripts'),
21
  entry: {
22 23
    blob:                 './blob_edit/blob_bundle.js',
    boards:               './boards/boards_bundle.js',
24
    common:               './commons/index.js',
25
    common_vue:           ['vue', './vue_shared/common_vue.js'],
26
    common_d3:            ['d3'],
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 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
    group:                './group.js',
35
    groups:               './groups/index.js',
36
    issuable:             './issuable/issuable_bundle.js',
37 38
    issue_show:           './issue_show/index.js',
    main:                 './main.js',
39 40
    merge_conflicts:      './merge_conflicts/merge_conflicts_bundle.js',
    merge_request_widget: './merge_request_widget/ci_bundle.js',
41
    monitoring:           './monitoring/monitoring_bundle.js',
42
    network:              './network/network_bundle.js',
43
    notebook_viewer:      './blob/notebook_viewer.js',
44
    pdf_viewer:           './blob/pdf_viewer.js',
45
    pipelines:            './pipelines/index.js',
46 47
    profile:              './profile/profile_bundle.js',
    protected_branches:   './protected_branches/protected_branches_bundle.js',
48
    protected_tags:       './protected_tags',
49
    snippet:              './snippet/snippet_bundle.js',
50
    sketch_viewer:        './blob/sketch_viewer.js',
Phil Hughes committed
51
    stl_viewer:           './blob/stl_viewer.js',
52
    terminal:             './terminal/terminal_bundle.js',
53
    u2f:                  ['vendor/u2f'],
54
    users:                './users/users_bundle.js',
55 56 57 58 59
  },

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

63
  devtool: 'cheap-module-source-map',
64

65
  module: {
66
    rules: [
67
      {
68
        test: /\.js$/,
69
        exclude: /(node_modules|vendor\/assets)/,
70
        loader: 'babel-loader',
71
      },
72 73
      {
        test: /\.vue$/,
74
        loader: 'vue-loader',
75
      },
76 77
      {
        test: /\.svg$/,
78 79
        loader: 'raw-loader',
      },
Sam Rose committed
80 81 82 83 84
      {
        test: /\.gif$/,
        loader: 'url-loader',
        query: { mimetype: 'image/gif' },
      },
85 86
      {
        test: /\.(worker\.js|pdf)$/,
87 88 89
        exclude: /node_modules/,
        loader: 'file-loader',
      },
90 91 92
    ]
  },

93 94 95 96 97 98 99 100 101
  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 committed
102
    }),
103 104

    // prevent pikaday from including moment.js
105
    new webpack.IgnorePlugin(/moment/, /pikaday/),
106

107 108 109 110 111 112
    // fix legacy jQuery plugins which depend on globals
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
    }),

113 114 115 116
    // use deterministic module ids in all environments
    IS_PRODUCTION ?
      new webpack.HashedModuleIdsPlugin() :
      new webpack.NamedModulesPlugin(),
117

118 119 120 121 122 123 124 125 126 127 128
    // 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',
129
        'issue_show',
130
        'merge_conflicts',
131
        'notebook_viewer',
132
        'pdf_viewer',
133
        'pipelines',
134
      ],
135 136 137
      minChunks: function(module, count) {
        return module.resource && (/vue_shared/).test(module.resource);
      },
138 139
    }),

140 141 142
    // create cacheable common library bundle for all d3 chunks
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common_d3',
143 144 145 146 147
      chunks: [
        'graphs',
        'users',
        'monitoring',
      ],
148 149
    }),

150
    // create cacheable common library bundles
151
    new webpack.optimize.CommonsChunkPlugin({
152
      names: ['main', 'common', 'runtime'],
153
    }),
154 155 156
  ],

  resolve: {
157
    extensions: ['.js'],
158
    alias: {
159
      '~':              path.join(ROOT_PATH, 'app/assets/javascripts'),
160
      'emojis':         path.join(ROOT_PATH, 'fixtures/emojis'),
161
      'empty_states':   path.join(ROOT_PATH, 'app/views/shared/empty_states'),
162
      'icons':          path.join(ROOT_PATH, 'app/views/shared/icons'),
163
      'vendor':         path.join(ROOT_PATH, 'vendor/assets/javascripts'),
164
      'vue$':           'vue/dist/vue.esm.js',
165
    }
166
  }
167 168
}

169
if (IS_PRODUCTION) {
170
  config.devtool = 'source-map';
171
  config.plugins.push(
172
    new webpack.NoEmitOnErrorsPlugin(),
173 174 175 176
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),
177
    new webpack.optimize.UglifyJsPlugin({
178
      sourceMap: true
179 180 181
    }),
    new webpack.DefinePlugin({
      'process.env': { NODE_ENV: JSON.stringify('production') }
182 183 184
    }),
    new CompressionPlugin({
      asset: '[path].gz[query]',
Mike Greiling committed
185
    })
186
  );
187 188 189
}

if (IS_DEV_SERVER) {
190
  config.devtool = 'cheap-module-eval-source-map';
191
  config.devServer = {
192
    host: DEV_SERVER_HOST,
193
    port: DEV_SERVER_PORT,
194 195
    headers: { 'Access-Control-Allow-Origin': '*' },
    stats: 'errors-only',
196
    inline: DEV_SERVER_LIVERELOAD
197
  };
198
  config.output.publicPath = '//' + DEV_SERVER_HOST + ':' + DEV_SERVER_PORT + config.output.publicPath;
199 200 201 202
  config.plugins.push(
    // watch node_modules for changes if we encounter a missing module compile error
    new WatchMissingNodeModulesPlugin(path.join(ROOT_PATH, 'node_modules'))
  );
203 204
}

205 206 207 208 209 210 211 212 213 214 215 216
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'),
    })
  );
}

217
module.exports = config;