-
Notifications
You must be signed in to change notification settings - Fork 1
/
createWebpackPlugins.js
162 lines (140 loc) · 4.86 KB
/
createWebpackPlugins.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// @flow
import AssetsPlugin from 'assets-webpack-plugin';
import BabiliPlugin from 'babili-webpack-plugin';
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
import CompressionPlugin from 'compression-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import chalk from 'chalk';
import ServerManager from '../ServerManager';
import ServerListenerPlugin from '../ServerListenerPlugin';
import WatchMissingNodeModulesPlugin from 'react-dev-utils/WatchMissingNodeModulesPlugin';
import webpack from 'webpack';
// detect offline plugin
let OfflinePlugin;
try {
OfflinePlugin = require('offline-plugin');
} catch (e) {}
export default function createWebpackPlugins(
{
isDev,
isServer,
serverBundlePath,
serverManager,
useBabili,
}: {
clientBundlePath: string,
serverBundlePath: string,
isDev: boolean,
isServer: boolean,
serverManager: ?ServerManager,
useBabili: boolean,
},
envVariables: Object,
): Array<any> {
let serverListenerPlugin;
if (isDev && isServer) {
if (serverManager == null) {
throw new Error('Server manager must be provided during development');
}
serverListenerPlugin = new ServerListenerPlugin(serverManager);
}
return [
// add module names to factory functions so they appear in browser profiler
!isServer && isDev ? new webpack.NamedModulesPlugin() : null,
// define variables client side and server side
new webpack.DefinePlugin({
...envVariables,
'process.env.IS_SERVER': JSON.stringify(isServer),
'process.env.IS_CLIENT': JSON.stringify(!isServer),
}),
// hot module replacement, only client side and dev
isDev && !isServer ? new webpack.HotModuleReplacementPlugin() : null,
// case sensitive paths plugin, only dev, both sides
isDev ? new CaseSensitivePathsPlugin() : null,
// watch missing node modules plugin, only dev, both sides
isDev ? new WatchMissingNodeModulesPlugin() : null,
// webpack 3.0's
!isDev && webpack.optimize.ModuleConcatenationPlugin
? new webpack.optimize.ModuleConcatenationPlugin()
: null,
// make everything that is pointed from 2 and more places a chunk
!isDev && !isServer
? new webpack.optimize.CommonsChunkPlugin({
async: true,
children: true,
minChunks: (module, count) => count >= 2,
})
: null,
// uglify js, only client side and prod mode
!isDev && !isServer && !useBabili
? new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
comparisons: false,
},
output: {
comments: false,
},
sourceMap: true,
})
: null,
// babili, only client side and prod mode
!isDev && !isServer && useBabili
? new BabiliPlugin(
{},
{
babel: require('babel-core'),
babili: require.resolve('babel-preset-babili'),
comments: false,
},
)
: null,
// ignore locales imported by momentjs, both sides, requires you to require them explicitly
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// extract css, only client side and prod
!isDev && !isServer
? new ExtractTextPlugin({
filename: 'static/css/[name].[hash:8].css',
allChunks: true,
})
: null,
// compress to gz, only client side assets and prod
!isDev && !isServer
? new CompressionPlugin({
asset: '[path].gz',
algorithm: 'gzip',
})
: null,
// offline plugin , only client side assets and prod mode
!isDev && !isServer && OfflinePlugin != null
? new OfflinePlugin({
AppCache: false,
autoUpdate: true,
caches: {
main: ['**/vendor.*.{css,js}', '**/main.*.{css,js}'],
additional: [':rest:'],
// main: ['**/vendor-*.{css,js}', '**/main-*.{css,js}'],
// additional: ['**/*.{css,js,jpg,jpeg,png,ogg,svg,woff,woff2,ttf}'],
// additional: [':rest:'],
},
excludes: ['**/*.map', '**/*.map.gz'],
publicPath: '/',
safeToUseOptionalCaches: true,
ServiceWorker: {
// emit events so we can react to them in client/index.js
events: true,
output: './static/js/sw.js',
publicPath: '/static/js/sw.js',
},
})
: null,
// limit chunks to only one file on server side (useful for react-loadable)
isServer ? new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }) : null,
// assets plugin, only client side and prod mode
!isServer
? new AssetsPlugin({ path: serverBundlePath, fullPath: true, prettyPrint: true })
: null,
// server listener plugin to manage exported server instance
serverListenerPlugin,
].filter(Boolean);
}