Skip to content

Commit ea4dc6f

Browse files
andriijasgaearon
authored andcommittedMay 20, 2018
- [x] Upgrade to webpack 4.8.X (facebook#4077)
- [x] Utilize webpack 4 development and production modes - [x] Upgrade webpack dev server - [x] Webpack 4 compatible release of thread-loader - [x] Webpack 4 compatible release of HtmlWebpackPlugin - [x] Webpack 4 compatible release of SwPrecacheWebpackPlugin - [x] Webpack 4 compatible release of WebpackManifestPlugin - [x] Update README - [x] Update WebpackDevServerUtils - [x] Update InterpolateHtmlPlugin - [x] Update ModuleScopePlugin - [x] Update WatchMissingNodeModulesPlugin - [x] Move UglifyJS options to webpack 4 optimize - [x] Move InterpolateHtmlPlugin to make it tapable on HtmlWebpackPlugin - [x] vendor splitting via splitChunks.splitChunks (https://twitter.com/wSokra/status/969633336732905474) - [x] long term caching via splitChunks.runtimeChunk (https://twitter.com/wSokra/status/969679223278505985) - [x] Make sure process.env.NODE_ENV is proxied correctly to `react-error-overlay` - [x] Implicit webpack.NamedModulesPlugin in dev config as its default in webpack 4 - [x] Disable webpack performance hints as we have our own filesize reporter - [x] Replace ExtractTextPlugin with MiniCssExtractPlugin - [x] Switch to css whole file minification via OptimizeCSSAssetsPlugin rather than per module css minification to gain performance
1 parent aa718b5 commit ea4dc6f

File tree

4 files changed

+157
-173
lines changed

4 files changed

+157
-173
lines changed
 

‎config/webpack.config.dev.js

+36-29
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,6 @@ const publicUrl = '';
3131
// Get environment variables to inject into our app.
3232
const env = getClientEnvironment(publicUrl);
3333

34-
// Options for PostCSS as we reference these options twice
35-
// Adds vendor prefixing based on your specified browser support in
36-
// package.json
37-
const postCSSLoaderOptions = {
38-
// Necessary for external CSS imports to work
39-
// https://github.com/facebook/create-react-app/issues/2677
40-
ident: 'postcss',
41-
plugins: () => [
42-
require('postcss-flexbugs-fixes'),
43-
autoprefixer({
44-
flexbox: 'no-2009',
45-
}),
46-
],
47-
};
48-
4934
// style files regexes
5035
const cssRegex = /\.css$/;
5136
const cssModuleRegex = /\.module\.css$/;
@@ -61,8 +46,21 @@ const getStyleLoaders = (cssOptions, preProcessor) => {
6146
options: cssOptions,
6247
},
6348
{
49+
// Options for PostCSS as we reference these options twice
50+
// Adds vendor prefixing based on your specified browser support in
51+
// package.json
6452
loader: require.resolve('postcss-loader'),
65-
options: postCSSLoaderOptions,
53+
options: {
54+
// Necessary for external CSS imports to work
55+
// https://github.com/facebook/create-react-app/issues/2677
56+
ident: 'postcss',
57+
plugins: () => [
58+
require('postcss-flexbugs-fixes'),
59+
autoprefixer({
60+
flexbox: 'no-2009',
61+
}),
62+
],
63+
},
6664
},
6765
];
6866
if (preProcessor) {
@@ -75,6 +73,7 @@ const getStyleLoaders = (cssOptions, preProcessor) => {
7573
// It is focused on developer experience and fast rebuilds.
7674
// The production configuration is different and lives in a separate file.
7775
module.exports = {
76+
mode: 'development',
7877
// You may want 'eval' instead if you prefer to see the compiled output in DevTools.
7978
// See the discussion in https://github.com/facebook/create-react-app/issues/343.
8079
devtool: 'cheap-module-source-map',
@@ -116,6 +115,18 @@ module.exports = {
116115
devtoolModuleFilenameTemplate: info =>
117116
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
118117
},
118+
optimization: {
119+
// Automatically split vendor and commons
120+
// https://twitter.com/wSokra/status/969633336732905474
121+
// https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
122+
splitChunks: {
123+
chunks: 'all',
124+
name: 'vendors',
125+
},
126+
// Keep the runtime chunk seperated to enable long term caching
127+
// https://twitter.com/wSokra/status/969679223278505985
128+
runtimeChunk: true,
129+
},
119130
resolve: {
120131
// This allows you to set a fallback for where Webpack should look for modules.
121132
// We placed these paths second because we want `node_modules` to "win"
@@ -335,18 +346,16 @@ module.exports = {
335346
],
336347
},
337348
plugins: [
338-
// Makes some environment variables available in index.html.
339-
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
340-
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
341-
// In development, this will be an empty string.
342-
new InterpolateHtmlPlugin(env.raw),
343349
// Generates an `index.html` file with the <script> injected.
344350
new HtmlWebpackPlugin({
345351
inject: true,
346352
template: paths.appHtml,
347353
}),
348-
// Add module names to factory functions so they appear in browser profiler.
349-
new webpack.NamedModulesPlugin(),
354+
// Makes some environment variables available in index.html.
355+
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
356+
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
357+
// In development, this will be an empty string.
358+
new InterpolateHtmlPlugin(env.raw),
350359
// Makes some environment variables available to the JS code, for example:
351360
// if (process.env.NODE_ENV === 'development') { ... }. See `./env.js`.
352361
new webpack.DefinePlugin(env.stringified),
@@ -368,6 +377,7 @@ module.exports = {
368377
// You can remove this if you don't use Moment.js:
369378
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
370379
],
380+
371381
// Some libraries import Node modules but don't use them in the browser.
372382
// Tell Webpack to provide empty mocks for them so importing them works.
373383
node: {
@@ -377,10 +387,7 @@ module.exports = {
377387
tls: 'empty',
378388
child_process: 'empty',
379389
},
380-
// Turn off performance hints during development because we don't do any
381-
// splitting or minification in interest of speed. These warnings become
382-
// cumbersome.
383-
performance: {
384-
hints: false,
385-
},
390+
// Turn off performance processing because we utilize
391+
// our own hints via the FileSizeReporter
392+
performance: false,
386393
};

‎config/webpack.config.prod.js

+88-112
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const path = require('path');
1313
const webpack = require('webpack');
1414
const HtmlWebpackPlugin = require('html-webpack-plugin');
1515
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
16-
const ExtractTextPlugin = require('extract-text-webpack-plugin');
16+
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
17+
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
1718
const ManifestPlugin = require('webpack-manifest-plugin');
1819
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
1920
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
@@ -26,9 +27,6 @@ const getClientEnvironment = require('./env');
2627
// Webpack uses `publicPath` to determine where the app is being served from.
2728
// It requires a trailing slash, or the file assets will get an incorrect path.
2829
const publicPath = paths.servedPath;
29-
// Some apps do not use client-side routing with pushState.
30-
// For these, "homepage" can be set to "." to enable relative asset paths.
31-
const shouldUseRelativeAssetPaths = publicPath === './';
3230
// Source maps are resource heavy and can cause out of memory issue for large source files.
3331
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
3432
// `publicUrl` is just like `publicPath`, but we will provide it to our app
@@ -44,34 +42,6 @@ if (env.stringified['process.env'].NODE_ENV !== '"production"') {
4442
throw new Error('Production builds must have NODE_ENV=production.');
4543
}
4644

47-
// Note: defined here because it will be used more than once.
48-
const cssFilename = 'static/css/[name].[contenthash:8].css';
49-
50-
// ExtractTextPlugin expects the build output to be flat.
51-
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
52-
// However, our output is structured with css, js and media folders.
53-
// To have this structure working with relative paths, we have to use custom options.
54-
const extractTextPluginOptions = shouldUseRelativeAssetPaths
55-
? // Making sure that the publicPath goes back to to build folder.
56-
{ publicPath: Array(cssFilename.split('/').length).join('../') }
57-
: {};
58-
59-
// Options for PostCSS as we reference these options twice
60-
// Adds vendor prefixing based on your specified browser support in
61-
// package.json
62-
const postCSSLoaderOptions = {
63-
// Necessary for external CSS imports to work
64-
// https://github.com/facebook/create-react-app/issues/2677
65-
ident: 'postcss',
66-
plugins: () => [
67-
require('postcss-flexbugs-fixes'),
68-
autoprefixer({
69-
flexbox: 'no-2009',
70-
}),
71-
],
72-
sourceMap: shouldUseSourceMap,
73-
};
74-
7545
// style files regexes
7646
const cssRegex = /\.css$/;
7747
const cssModuleRegex = /\.module\.css$/;
@@ -81,13 +51,28 @@ const sassModuleRegex = /\.module\.(scss|sass)$/;
8151
// common function to get style loaders
8252
const getStyleLoaders = (cssOptions, preProcessor) => {
8353
const loaders = [
54+
MiniCssExtractPlugin.loader,
8455
{
8556
loader: require.resolve('css-loader'),
8657
options: cssOptions,
8758
},
8859
{
60+
// Options for PostCSS as we reference these options twice
61+
// Adds vendor prefixing based on your specified browser support in
62+
// package.json
8963
loader: require.resolve('postcss-loader'),
90-
options: postCSSLoaderOptions,
64+
options: {
65+
// Necessary for external CSS imports to work
66+
// https://github.com/facebook/create-react-app/issues/2677
67+
ident: 'postcss',
68+
plugins: () => [
69+
require('postcss-flexbugs-fixes'),
70+
autoprefixer({
71+
flexbox: 'no-2009',
72+
}),
73+
],
74+
sourceMap: shouldUseSourceMap,
75+
},
9176
},
9277
];
9378
if (preProcessor) {
@@ -98,26 +83,14 @@ const getStyleLoaders = (cssOptions, preProcessor) => {
9883
},
9984
});
10085
}
101-
return ExtractTextPlugin.extract(
102-
Object.assign(
103-
{
104-
fallback: {
105-
loader: require.resolve('style-loader'),
106-
options: {
107-
hmr: false,
108-
},
109-
},
110-
use: loaders,
111-
},
112-
extractTextPluginOptions
113-
)
114-
);
86+
return loaders;
11587
};
11688

11789
// This is the production configuration.
11890
// It compiles slowly and is focused on producing a fast and minimal bundle.
11991
// The development configuration is different and lives in a separate file.
12092
module.exports = {
93+
mode: 'production',
12194
// Don't attempt to continue if there are any errors.
12295
bail: true,
12396
// We generate sourcemaps in production. This is slow but gives good results.
@@ -141,6 +114,58 @@ module.exports = {
141114
.relative(paths.appSrc, info.absoluteResourcePath)
142115
.replace(/\\/g, '/'),
143116
},
117+
optimization: {
118+
minimizer: [
119+
new UglifyJsPlugin({
120+
uglifyOptions: {
121+
parse: {
122+
// we want uglify-js to parse ecma 8 code. However, we don't want it
123+
// to apply any minfication steps that turns valid ecma 5 code
124+
// into invalid ecma 5 code. This is why the 'compress' and 'output'
125+
// sections only apply transformations that are ecma 5 safe
126+
// https://github.com/facebook/create-react-app/pull/4234
127+
ecma: 8,
128+
},
129+
compress: {
130+
ecma: 5,
131+
warnings: false,
132+
// Disabled because of an issue with Uglify breaking seemingly valid code:
133+
// https://github.com/facebook/create-react-app/issues/2376
134+
// Pending further investigation:
135+
// https://github.com/mishoo/UglifyJS2/issues/2011
136+
comparisons: false,
137+
},
138+
mangle: {
139+
safari10: true,
140+
},
141+
output: {
142+
ecma: 5,
143+
comments: false,
144+
// Turned on because emoji and regex is not minified properly using default
145+
// https://github.com/facebook/create-react-app/issues/2488
146+
ascii_only: true,
147+
},
148+
},
149+
// Use multi-process parallel running to improve the build speed
150+
// Default number of concurrent runs: os.cpus().length - 1
151+
parallel: true,
152+
// Enable file caching
153+
cache: true,
154+
sourceMap: shouldUseSourceMap,
155+
}),
156+
new OptimizeCSSAssetsPlugin(),
157+
],
158+
// Automatically split vendor and commons
159+
// https://twitter.com/wSokra/status/969633336732905474
160+
// https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
161+
splitChunks: {
162+
chunks: 'all',
163+
name: 'vendors',
164+
},
165+
// Keep the runtime chunk seperated to enable long term caching
166+
// https://twitter.com/wSokra/status/969679223278505985
167+
runtimeChunk: true,
168+
},
144169
resolve: {
145170
// This allows you to set a fallback for where Webpack should look for modules.
146171
// We placed these paths second because we want `node_modules` to "win"
@@ -284,41 +309,29 @@ module.exports = {
284309
},
285310
],
286311
},
287-
// The notation here is somewhat confusing.
288312
// "postcss" loader applies autoprefixer to our CSS.
289313
// "css" loader resolves paths in CSS and adds assets as dependencies.
290-
// "style" loader normally turns CSS into JS modules injecting <style>,
291-
// but unlike in development configuration, we do something different.
292-
// `ExtractTextPlugin` first applies the "postcss" and "css" loaders
293-
// (second argument), then grabs the result CSS and puts it into a
294-
// separate file in our build process. This way we actually ship
295-
// a single CSS file in production instead of JS code injecting <style>
296-
// tags. If you use code splitting, however, any async bundles will still
297-
// use the "style" loader inside the async code so CSS from them won't be
298-
// in the main CSS file.
314+
// `MiniCSSExtractPlugin` extracts styles into CSS
315+
// files. If you use code splitting, async bundles will have their own separate CSS chunk file.
299316
// By default we support CSS Modules with the extension .module.css
300317
{
301318
test: cssRegex,
302319
exclude: cssModuleRegex,
303320
loader: getStyleLoaders({
304321
importLoaders: 1,
305-
minimize: true,
306322
sourceMap: shouldUseSourceMap,
307323
}),
308-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
309324
},
310325
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
311326
// using the extension .module.css
312327
{
313328
test: cssModuleRegex,
314329
loader: getStyleLoaders({
315330
importLoaders: 1,
316-
minimize: true,
317331
sourceMap: shouldUseSourceMap,
318332
modules: true,
319333
getLocalIdent: getCSSModuleLocalIdent,
320334
}),
321-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
322335
},
323336
// Opt-in support for SASS. The logic here is somewhat similar
324337
// as in the CSS routine, except that "sass-loader" runs first
@@ -331,12 +344,10 @@ module.exports = {
331344
loader: getStyleLoaders(
332345
{
333346
importLoaders: 2,
334-
minimize: true,
335347
sourceMap: shouldUseSourceMap,
336348
},
337349
'sass-loader'
338350
),
339-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
340351
},
341352
// Adds support for CSS Modules, but using SASS
342353
// using the extension .module.scss or .module.sass
@@ -345,14 +356,12 @@ module.exports = {
345356
loader: getStyleLoaders(
346357
{
347358
importLoaders: 2,
348-
minimize: true,
349359
sourceMap: shouldUseSourceMap,
350360
modules: true,
351361
getLocalIdent: getCSSModuleLocalIdent,
352362
},
353363
'sass-loader'
354364
),
355-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
356365
},
357366
// The GraphQL loader preprocesses GraphQL queries in .graphql files.
358367
{
@@ -381,12 +390,6 @@ module.exports = {
381390
],
382391
},
383392
plugins: [
384-
// Makes some environment variables available in index.html.
385-
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
386-
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
387-
// In production, it will be an empty string unless you specify "homepage"
388-
// in `package.json`, in which case it will be the pathname of that URL.
389-
new InterpolateHtmlPlugin(env.raw),
390393
// Generates an `index.html` file with the <script> injected.
391394
new HtmlWebpackPlugin({
392395
inject: true,
@@ -404,52 +407,22 @@ module.exports = {
404407
minifyURLs: true,
405408
},
406409
}),
410+
// Makes some environment variables available in index.html.
411+
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
412+
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
413+
// In production, it will be an empty string unless you specify "homepage"
414+
// in `package.json`, in which case it will be the pathname of that URL.
415+
new InterpolateHtmlPlugin(env.raw),
407416
// Makes some environment variables available to the JS code, for example:
408417
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
409418
// It is absolutely essential that NODE_ENV was set to production here.
410419
// Otherwise React will be compiled in the very slow development mode.
411420
new webpack.DefinePlugin(env.stringified),
412-
// Minify the code.
413-
new UglifyJsPlugin({
414-
uglifyOptions: {
415-
parse: {
416-
// we want uglify-js to parse ecma 8 code. However, we don't want it
417-
// to apply any minfication steps that turns valid ecma 5 code
418-
// into invalid ecma 5 code. This is why the 'compress' and 'output'
419-
// sections only apply transformations that are ecma 5 safe
420-
// https://github.com/facebook/create-react-app/pull/4234
421-
ecma: 8,
422-
},
423-
compress: {
424-
ecma: 5,
425-
warnings: false,
426-
// Disabled because of an issue with Uglify breaking seemingly valid code:
427-
// https://github.com/facebook/create-react-app/issues/2376
428-
// Pending further investigation:
429-
// https://github.com/mishoo/UglifyJS2/issues/2011
430-
comparisons: false,
431-
},
432-
mangle: {
433-
safari10: true,
434-
},
435-
output: {
436-
ecma: 5,
437-
comments: false,
438-
// Turned on because emoji and regex is not minified properly using default
439-
// https://github.com/facebook/create-react-app/issues/2488
440-
ascii_only: true,
441-
},
442-
},
443-
// Use multi-process parallel running to improve the build speed
444-
// Default number of concurrent runs: os.cpus().length - 1
445-
parallel: true,
446-
// Enable file caching
447-
cache: true,
448-
sourceMap: shouldUseSourceMap,
449-
}),
450-
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
451-
new ExtractTextPlugin({
452-
filename: cssFilename,
421+
new MiniCssExtractPlugin({
422+
// Options similar to the same options in webpackOptions.output
423+
// both options are optional
424+
filename: 'static/css/[name].[contenthash:8].css',
425+
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
453426
}),
454427
// Generate a manifest file which contains a mapping of all asset filenames
455428
// to their corresponding output file so that tools can pick it up without
@@ -503,4 +476,7 @@ module.exports = {
503476
tls: 'empty',
504477
child_process: 'empty',
505478
},
479+
// Turn off performance processing because we utilize
480+
// our own hints via the FileSizeReporter
481+
performance: false,
506482
};

‎config/webpackDevServer.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ module.exports = function(proxy, allowedHost) {
6969
// as we specified in the config. In development, we always serve from /.
7070
publicPath: config.output.publicPath,
7171
// WebpackDevServer is noisy by default so we emit custom message instead
72-
// by listening to the compiler events with `compiler.plugin` calls above.
72+
// by listening to the compiler events with `compiler.hooks[...].tap` calls above.
7373
quiet: true,
7474
// Reportedly, this avoids CPU overload on some systems.
7575
// https://github.com/facebook/create-react-app/issues/293

‎package.json

+32-31
Original file line numberDiff line numberDiff line change
@@ -23,56 +23,57 @@
2323
"dependencies": {
2424
"@babel/core": "7.0.0-beta.46",
2525
"@babel/runtime": "7.0.0-beta.46",
26-
"autoprefixer": "7.2.5",
26+
"autoprefixer": "8.5.0",
2727
"babel-core": "7.0.0-bridge.0",
28-
"babel-eslint": "8.2.2",
29-
"babel-jest": "22.4.1",
28+
"babel-eslint": "8.2.3",
29+
"babel-jest": "22.4.3",
3030
"babel-loader": "8.0.0-beta.0",
3131
"babel-plugin-named-asset-import": "^0.1.0",
3232
"babel-preset-react-app": "^3.1.1",
33-
"case-sensitive-paths-webpack-plugin": "2.1.1",
34-
"chalk": "2.3.0",
35-
"css-loader": "0.28.9",
36-
"dotenv": "5.0.0",
33+
"case-sensitive-paths-webpack-plugin": "2.1.2",
34+
"chalk": "2.4.1",
35+
"css-loader": "0.28.11",
36+
"dotenv": "5.0.1",
3737
"dotenv-expand": "4.2.0",
38-
"eslint": "4.15.0",
38+
"eslint": "4.19.1",
3939
"eslint-config-react-app": "^2.1.0",
40-
"eslint-loader": "1.9.0",
41-
"eslint-plugin-flowtype": "2.41.0",
42-
"eslint-plugin-import": "2.8.0",
40+
"eslint-loader": "2.0.0",
41+
"eslint-plugin-flowtype": "2.46.3",
42+
"eslint-plugin-import": "2.11.0",
4343
"eslint-plugin-jsx-a11y": "6.0.3",
44-
"eslint-plugin-react": "7.7.0",
45-
"extract-text-webpack-plugin": "3.0.2",
46-
"file-loader": "1.1.6",
44+
"eslint-plugin-react": "7.8.2",
45+
"file-loader": "1.1.11",
4746
"fs-extra": "5.0.0",
48-
"graphql": "0.12.3",
49-
"graphql-tag": "2.6.1",
50-
"html-webpack-plugin": "2.30.1",
47+
"graphql": "0.13.2",
48+
"graphql-tag": "2.9.2",
49+
"html-webpack-plugin": "3.2.0",
5150
"identity-obj-proxy": "3.0.0",
52-
"jest": "22.4.1",
5351
"loader-utils": "^1.1.0",
52+
"jest": "22.4.3",
53+
"mini-css-extract-plugin": "^0.4.0",
5454
"object-assign": "4.1.1",
55-
"postcss-flexbugs-fixes": "3.2.0",
56-
"postcss-loader": "2.0.10",
55+
"postcss-flexbugs-fixes": "3.3.1",
56+
"optimize-css-assets-webpack-plugin": "^4.0.1",
57+
"postcss-loader": "2.1.5",
5758
"promise": "8.0.1",
5859
"raf": "3.4.0",
5960
"react-dev-utils": "^5.0.0",
6061
"resolve": "1.6.0",
6162
"sass-loader": "7.0.1",
62-
"style-loader": "0.19.1",
63+
"style-loader": "0.21.0",
6364
"svgr": "1.9.2",
64-
"sw-precache-webpack-plugin": "0.11.4",
65-
"thread-loader": "1.1.2",
66-
"uglifyjs-webpack-plugin": "1.1.6",
67-
"url-loader": "0.6.2",
68-
"webpack": "3.10.0",
69-
"webpack-dev-server": "2.11.0",
70-
"webpack-manifest-plugin": "1.3.2",
71-
"whatwg-fetch": "2.0.3"
65+
"sw-precache-webpack-plugin": "0.11.5",
66+
"thread-loader": "1.1.5",
67+
"uglifyjs-webpack-plugin": "1.2.5",
68+
"url-loader": "1.0.1",
69+
"webpack": "4.8.3",
70+
"webpack-dev-server": "3.1.4",
71+
"webpack-manifest-plugin": "2.0.2",
72+
"whatwg-fetch": "2.0.4"
7273
},
7374
"devDependencies": {
74-
"react": "^16.0.0",
75-
"react-dom": "^16.0.0"
75+
"react": "^16.3.2",
76+
"react-dom": "^16.3.2"
7677
},
7778
"optionalDependencies": {
7879
"fsevents": "1.2.0"

0 commit comments

Comments
 (0)
Please sign in to comment.