From 5d290de8c9555c94a764b2f4ec4dcfee3e0d6a4e Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Wed, 21 Dec 2016 12:43:32 +0000 Subject: [PATCH 01/11] Whitelist files that can be embedded through url-loader Change the current catch-all loader to use file-loader instead of url-loader, and exclude common image file extensons. Add another url-loader for images, configured identically to the original catch-all loader. Part of issue #1293. --- .../config/webpack.config.dev.js | 33 ++++++++++++------- .../config/webpack.config.prod.js | 31 ++++++++++------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index a952969e00f..214373b81b8 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -134,15 +134,34 @@ module.exports = { // When adding a new loader, you must add its `test` // as a new entry in the `exclude` list for "url" loader. - // "url" loader embeds assets smaller than specified size as data URLs to avoid requests. - // Otherwise, it acts like the "file" loader. + // "file" loader makes sure those assets get served by WebpackDevServer. + // When you `import` an asset, you get its (virtual) filename. + // In production, they would get copied to the `build` folder. { exclude: [ /\.html$/, /\.(js|jsx)$/, /\.css$/, /\.json$/, - /\.svg$/ + /\.bmp$/, + /\.gif$/, + /\.jpe?g$/, + /\.png$/ + ], + loader: 'file-loader', + options: { + name: 'static/media/[name].[hash:8].[ext]' + } + }, + // "url" loader works like "file" loader except that it embeds assets + // smaller than specified limit in bytes as data URLs to avoid requests. + // A missing `test` is equivalent to a match. + { + test: [ + /\.bmp$/, + /\.gif$/, + /\.jpe?g$/, + /\.png$/ ], loader: 'url-loader', options: { @@ -198,14 +217,6 @@ module.exports = { } } ] - }, - // "file" loader for svg - { - test: /\.svg$/, - loader: 'file-loader', - options: { - name: 'static/media/[name].[hash:8].[ext]' - } } // ** STOP ** Are you adding a new loader? // Remember to add the new extension(s) to the "url" loader exclusion list. diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 86b38f76714..2edb73f0c23 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -138,15 +138,32 @@ module.exports = { // When adding a new loader, you must add its `test` // as a new entry in the `exclude` list in the "url" loader. - // "url" loader embeds assets smaller than specified size as data URLs to avoid requests. - // Otherwise, it acts like the "file" loader. + // "file" loader makes sure those assets end up in the `build` folder. + // When you `import` an asset, you get its filename. { exclude: [ /\.html$/, /\.(js|jsx)$/, /\.css$/, /\.json$/, - /\.svg$/ + /\.bmp$/, + /\.gif$/, + /\.jpe?g$/, + /\.png$/ + ], + loader: 'file-loader', + query: { + name: 'static/media/[name].[hash:8].[ext]' + } + }, + // "url" loader works just like "file" loader but it also embeds + // assets smaller than specified size as data URLs to avoid requests. + { + test: [ + /\.bmp$/, + /\.gif$/, + /\.jpe?g$/, + /\.png$/ ], loader: 'url-loader', options: { @@ -209,14 +226,6 @@ module.exports = { ] }, extractTextPluginOptions)) // Note: this won't work without `new ExtractTextPlugin()` in `plugins`. - }, - // "file" loader for svg - { - test: /\.svg$/, - loader: 'file-loader', - options: { - name: 'static/media/[name].[hash:8].[ext]' - } } // ** STOP ** Are you adding a new loader? // Remember to add the new extension(s) to the "url" loader exclusion list. From 8fab470e1ea5ee5f2afef1f88a75ba32ffc1974e Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Wed, 22 Feb 2017 09:05:41 +0000 Subject: [PATCH 02/11] Update tests to reflect change in loader config --- packages/react-scripts/config/webpack.config.prod.js | 2 +- .../fixtures/kitchensink/integration/webpack.test.js | 4 ++-- .../kitchensink/src/features/webpack/NoExtInclusion.js | 2 +- .../kitchensink/src/features/webpack/UnknownExtInclusion.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 2edb73f0c23..5a2388d29c3 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -152,7 +152,7 @@ module.exports = { /\.png$/ ], loader: 'file-loader', - query: { + options: { name: 'static/media/[name].[hash:8].[ext]' } }, diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 3eaa662b3d1..b54567f63a9 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -28,8 +28,7 @@ describe('Integration', () => { it('no ext inclusion', async () => { const doc = await initDOM('no-ext-inclusion') - expect(doc.getElementById('feature-no-ext-inclusion').textContent) - .to.equal('This is just a file without an extension.') + expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/^\/static\/media\/.*\/aFileWithoutExt$/) }) it('json inclusion', async () => { @@ -48,6 +47,7 @@ describe('Integration', () => { const doc = await initDOM('unknown-ext-inclusion') expect(doc.getElementById('feature-unknown-ext-inclusion').textContent).to.equal('Whoooo, spooky!.') + expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/^\/static\/media\/.*\/aFileWithExt.unknown$/); }) }) }) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js index fb07359fdc9..b3bdbe9fcbc 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/NoExtInclusion.js @@ -15,5 +15,5 @@ const text = aFileWithoutExt.includes('base64') : aFileWithoutExt export default () => ( -

{text}.

+ aFileWithoutExt ) diff --git a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js index 8734064c882..a9ac8f00cf1 100644 --- a/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/src/features/webpack/UnknownExtInclusion.js @@ -15,5 +15,5 @@ const text = aFileWithExtUnknown.includes('base64') : aFileWithExtUnknown export default () => ( -

{text}.

+ aFileWithExtUnknown ) From 23bb44e0018ba6f8befef84bcc3d988bfe8ac927 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Wed, 22 Feb 2017 16:27:23 +0000 Subject: [PATCH 03/11] Integration test fix --- .../fixtures/kitchensink/integration/webpack.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index b54567f63a9..3b5d9da988d 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -28,7 +28,7 @@ describe('Integration', () => { it('no ext inclusion', async () => { const doc = await initDOM('no-ext-inclusion') - expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/^\/static\/media\/.*\/aFileWithoutExt$/) + expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/.*\/aFileWithoutExt$/) }) it('json inclusion', async () => { @@ -47,7 +47,7 @@ describe('Integration', () => { const doc = await initDOM('unknown-ext-inclusion') expect(doc.getElementById('feature-unknown-ext-inclusion').textContent).to.equal('Whoooo, spooky!.') - expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/^\/static\/media\/.*\/aFileWithExt.unknown$/); + expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/\/static\/media\/.*\/aFileWithExt\.unknown$/); }) }) }) From ecfdb0b98d934013cfb0ebb244a7e7ea2687f5c3 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Thu, 23 Feb 2017 16:39:30 +0000 Subject: [PATCH 04/11] More CI fixes --- .../fixtures/kitchensink/integration/webpack.test.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 3b5d9da988d..0e5cacffb66 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -28,7 +28,7 @@ describe('Integration', () => { it('no ext inclusion', async () => { const doc = await initDOM('no-ext-inclusion') - expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/.*\/aFileWithoutExt$/) + expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/aFileWithoutExt$/) }) it('json inclusion', async () => { @@ -46,8 +46,7 @@ describe('Integration', () => { it('unknown ext inclusion', async () => { const doc = await initDOM('unknown-ext-inclusion') - expect(doc.getElementById('feature-unknown-ext-inclusion').textContent).to.equal('Whoooo, spooky!.') - expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/\/static\/media\/.*\/aFileWithExt\.unknown$/); + expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/\/static\/media\/aFileWithExt\.[a-f0-9]{8}\.unknown$/); }) }) }) From 17306c31501431ce06d97763491b81db2c622ce7 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Fri, 24 Feb 2017 14:10:16 +0000 Subject: [PATCH 05/11] Work around broken loader-utils behaviour in integration tests --- .../kitchensink/integration/webpack.test.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 0e5cacffb66..51c1614c97d 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -28,7 +28,24 @@ describe('Integration', () => { it('no ext inclusion', async () => { const doc = await initDOM('no-ext-inclusion') - expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/aFileWithoutExt$/) + // The expected pattern here is wrong. Due to: + // + // https://github.com/webpack/loader-utils/pull/71 + // + // ...the loader-utils module gets the interpolated name wrong when + // there's no file extension and there's a period in source directory + // path (which happens here due to generated temp directories). You + // end up with something like: + // + // /static/media/.cb7eb057.OEs6g9SsPz/test-kitchensink/src/features/webpack/assets/aFileWithoutExt + // + // instead of: + // + // /static/media/aFileWithoutExt.[hash].bin + // + // At some point loader-utils will be fixed, and the pattern can be + // fixed too. + expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/.*aFileWithoutExt$/) }) it('json inclusion', async () => { From 8b465bca53d9b8c07292043468aab8a4aa6be705 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Fri, 24 Feb 2017 15:07:04 +0000 Subject: [PATCH 06/11] Revise the documentation around file loading --- packages/react-scripts/template/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 8454fd983ea..88353656ea5 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -23,7 +23,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Adding a Stylesheet](#adding-a-stylesheet) - [Post-Processing CSS](#post-processing-css) - [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc) -- [Adding Images and Fonts](#adding-images-and-fonts) +- [Adding Images, Fonts and Files](#adding-images-fonts-and-files) - [Using the `public` Folder](#using-the-public-folder) - [Changing the HTML](#changing-the-html) - [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system) @@ -466,11 +466,11 @@ Then we can change `start` and `build` scripts to include the CSS preprocessor c Now running `npm start` and `npm run build` also builds Sass files. Note that `node-sass` seems to have an [issue recognizing newly created files on some systems](https://github.com/sass/node-sass/issues/1891) so you might need to restart the watcher when you create a file until it’s resolved. -## Adding Images and Fonts +## Adding Images, Fonts and Files With Webpack, using static assets like images and fonts works similarly to CSS. -You can **`import` an image right in a JavaScript module**. This tells Webpack to include that image in the bundle. Unlike CSS imports, importing an image or a font gives you a string value. This value is the final image path you can reference in your code. +You can **`import` a file right in a JavaScript module**. This tells Webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the `src` attribute of an image or the `href` of a link to a PDF. For images less than 10,000 bytes, importing them will return a `data:` URL instead of a path, so that they are inlined instead of requiring an extra request to the server to fetch them. To be clear, importing any file with an unknown extension will return the final path to that file. Here is an example: From e4412eef7320903c6839a3896b63f32b5d72b4a2 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Fri, 24 Feb 2017 15:54:22 +0000 Subject: [PATCH 07/11] Documentation tweaks --- packages/react-scripts/template/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 88353656ea5..78f538b27b0 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -23,7 +23,7 @@ You can find the most recent version of this guide [here](https://github.com/fac - [Adding a Stylesheet](#adding-a-stylesheet) - [Post-Processing CSS](#post-processing-css) - [Adding a CSS Preprocessor (Sass, Less etc.)](#adding-a-css-preprocessor-sass-less-etc) -- [Adding Images, Fonts and Files](#adding-images-fonts-and-files) +- [Adding Images, Fonts, and Files](#adding-images-fonts-and-files) - [Using the `public` Folder](#using-the-public-folder) - [Changing the HTML](#changing-the-html) - [Adding Assets Outside of the Module System](#adding-assets-outside-of-the-module-system) @@ -466,11 +466,13 @@ Then we can change `start` and `build` scripts to include the CSS preprocessor c Now running `npm start` and `npm run build` also builds Sass files. Note that `node-sass` seems to have an [issue recognizing newly created files on some systems](https://github.com/sass/node-sass/issues/1891) so you might need to restart the watcher when you create a file until it’s resolved. -## Adding Images, Fonts and Files +## Adding Images, Fonts, and Files With Webpack, using static assets like images and fonts works similarly to CSS. -You can **`import` a file right in a JavaScript module**. This tells Webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the `src` attribute of an image or the `href` of a link to a PDF. For images less than 10,000 bytes, importing them will return a `data:` URL instead of a path, so that they are inlined instead of requiring an extra request to the server to fetch them. To be clear, importing any file with an unknown extension will return the final path to that file. +You can **`import` a file right in a JavaScript module**. This tells Webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the `src` attribute of an image or the `href` of a link to a PDF. + +To reduce the number of requests to the server, importing images that are less than 10,000 bytes return a [data URI](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) instead of a path. This applies to the following file extensions: bmp, gif, jpg, jpeg, and png. SVG files are excluded due to [#1153](https://github.com/facebookincubator/create-react-app/issues/1153). Here is an example: From 9baee05708de914f3fc8ed72f1c383ca0e9536cf Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Fri, 24 Feb 2017 16:23:24 +0000 Subject: [PATCH 08/11] Docs tweak --- packages/react-scripts/template/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/template/README.md b/packages/react-scripts/template/README.md index 78f538b27b0..d8576d6949f 100644 --- a/packages/react-scripts/template/README.md +++ b/packages/react-scripts/template/README.md @@ -472,7 +472,7 @@ With Webpack, using static assets like images and fonts works similarly to CSS. You can **`import` a file right in a JavaScript module**. This tells Webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the `src` attribute of an image or the `href` of a link to a PDF. -To reduce the number of requests to the server, importing images that are less than 10,000 bytes return a [data URI](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) instead of a path. This applies to the following file extensions: bmp, gif, jpg, jpeg, and png. SVG files are excluded due to [#1153](https://github.com/facebookincubator/create-react-app/issues/1153). +To reduce the number of requests to the server, importing images that are less than 10,000 bytes returns a [data URI](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) instead of a path. This applies to the following file extensions: bmp, gif, jpg, jpeg, and png. SVG files are excluded due to [#1153](https://github.com/facebookincubator/create-react-app/issues/1153). Here is an example: From f27998b9e829d1dce7f77017c1e760f5af1645bb Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Mon, 6 Mar 2017 15:14:48 +0000 Subject: [PATCH 09/11] Update test now that webpack/loader-utils has been updated --- .../kitchensink/integration/webpack.test.js | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 51c1614c97d..43b3f1209f7 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -28,24 +28,7 @@ describe('Integration', () => { it('no ext inclusion', async () => { const doc = await initDOM('no-ext-inclusion') - // The expected pattern here is wrong. Due to: - // - // https://github.com/webpack/loader-utils/pull/71 - // - // ...the loader-utils module gets the interpolated name wrong when - // there's no file extension and there's a period in source directory - // path (which happens here due to generated temp directories). You - // end up with something like: - // - // /static/media/.cb7eb057.OEs6g9SsPz/test-kitchensink/src/features/webpack/assets/aFileWithoutExt - // - // instead of: - // - // /static/media/aFileWithoutExt.[hash].bin - // - // At some point loader-utils will be fixed, and the pattern can be - // fixed too. - expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/.*aFileWithoutExt$/) + expect(doc.getElementById('feature-no-ext-inclusion').href).to.match(/\/static\/media\/aFileWithoutExt\.[a-f0-9]{8}\.bin$/) }) it('json inclusion', async () => { @@ -63,7 +46,7 @@ describe('Integration', () => { it('unknown ext inclusion', async () => { const doc = await initDOM('unknown-ext-inclusion') - expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/\/static\/media\/aFileWithExt\.[a-f0-9]{8}\.unknown$/); + expect(doc.getElementById('feature-unknown-ext-inclusion').href).to.match(/\/static\/media\/aFileWithExt\.[a-f0-9]{8}\.unknown$/) }) }) }) From 6fe635ea775c54a0c519a61d255f5ac4e2879c5c Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Mon, 6 Mar 2017 15:45:42 +0000 Subject: [PATCH 10/11] Update react-scripts to depend on babel-loader@7.0.0-alpha.2 --- packages/react-scripts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index 33258dd8df3..e5483116912 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -27,7 +27,7 @@ "babel-core": "6.23.1", "babel-eslint": "7.1.1", "babel-jest": "18.0.0", - "babel-loader": "6.3.2", + "babel-loader": "7.0.0-alpha.2", "babel-preset-react-app": "^2.1.1", "babel-runtime": "^6.20.0", "case-sensitive-paths-webpack-plugin": "1.1.4", From 824926ecd71d3a005ffa2497dce24e61d7d7fc0b Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Tue, 7 Mar 2017 00:58:34 -0500 Subject: [PATCH 11/11] Bump deps --- packages/react-scripts/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json index e5483116912..9c67b721c5d 100644 --- a/packages/react-scripts/package.json +++ b/packages/react-scripts/package.json @@ -27,14 +27,14 @@ "babel-core": "6.23.1", "babel-eslint": "7.1.1", "babel-jest": "18.0.0", - "babel-loader": "7.0.0-alpha.2", + "babel-loader": "7.0.0-alpha.3", "babel-preset-react-app": "^2.1.1", "babel-runtime": "^6.20.0", "case-sensitive-paths-webpack-plugin": "1.1.4", "chalk": "1.1.3", "connect-history-api-fallback": "1.3.0", "cross-spawn": "4.0.2", - "css-loader": "0.26.1", + "css-loader": "0.26.2", "detect-port": "1.0.1", "dotenv": "2.0.0", "eslint": "3.16.1", @@ -45,16 +45,16 @@ "eslint-plugin-jsx-a11y": "4.0.0", "eslint-plugin-react": "6.4.1", "extract-text-webpack-plugin": "2.0.0", - "file-loader": "0.10.0", + "file-loader": "0.10.1", "fs-extra": "0.30.0", "html-webpack-plugin": "2.28.0", "http-proxy-middleware": "0.17.3", "jest": "18.1.0", "object-assign": "4.1.1", - "postcss-loader": "1.3.1", + "postcss-loader": "1.3.3", "promise": "7.1.1", "react-dev-utils": "^0.5.2", - "style-loader": "0.13.1", + "style-loader": "0.13.2", "url-loader": "0.5.7", "webpack": "2.2.1", "webpack-dev-server": "2.4.1",