From 493a379c21064a32a567b3b3fd13487264f71121 Mon Sep 17 00:00:00 2001 From: Mike Kusold Date: Tue, 15 May 2018 19:03:22 -0600 Subject: [PATCH 01/17] Map (css|sass|scss) modules to identity-obj-proxy in jest (#4419) --- packages/react-scripts/scripts/utils/createJestConfig.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index 593d17090a7..aa84d7637ff 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -45,11 +45,11 @@ module.exports = (resolve, rootDir, srcRoots) => { }, transformIgnorePatterns: [ '[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$', - '^.+\\.module\\.css$', + '^.+\\.module\\.(css|sass|scss)$', ], moduleNameMapper: { '^react-native$': 'react-native-web', - '^.+\\.module\\.css$': 'identity-obj-proxy', + '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', }, moduleFileExtensions: [ 'web.js', From 543ae5305be7b42b932f1a336e03d9b505c3e79d Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Tue, 15 May 2018 19:35:54 -0700 Subject: [PATCH 02/17] disable module concatenation --- packages/react-scripts/config/webpack.config.prod.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 4d04909a8b4..968f75219f6 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -479,4 +479,8 @@ module.exports = { // Turn off performance processing because we utilize // our own hints via the FileSizeReporter performance: false, + optimization: { + // webpack-manifest-plugin currently does not play well with ConcatenatedModule + concatenateModules: false, + }, }; From 2983c237f412074fd71f6e5d674b62983a7b3d8c Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Thu, 17 May 2018 13:45:04 -0700 Subject: [PATCH 03/17] fix cleanup --- tasks/e2e-kitchensink.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index b40a487ae4b..2044845f0a1 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -26,7 +26,7 @@ function cleanup { ps -ef | grep 'react-scripts' | grep -v grep | awk '{print $2}' | xargs kill -9 cd "$root_path" # TODO: fix "Device or resource busy" and remove ``|| $CI` - rm -rf "$temp_app_path" "$temp_module_path" || $CI + // rm -rf "$temp_app_path" "$temp_module_path" || $CI npm set registry "$original_npm_registry_url" yarn config set registry "$original_yarn_registry_url" } From 918f5494f14c0839219f6adbb259168a20cd02a0 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Thu, 17 May 2018 13:49:59 -0700 Subject: [PATCH 04/17] fix optimization --- packages/react-scripts/config/webpack.config.prod.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 968f75219f6..77d30c067ed 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -115,6 +115,8 @@ module.exports = { .replace(/\\/g, '/'), }, optimization: { + // webpack-manifest-plugin currently does not play well with ConcatenatedModule + concatenateModules: false, minimizer: [ new UglifyJsPlugin({ uglifyOptions: { @@ -479,8 +481,4 @@ module.exports = { // Turn off performance processing because we utilize // our own hints via the FileSizeReporter performance: false, - optimization: { - // webpack-manifest-plugin currently does not play well with ConcatenatedModule - concatenateModules: false, - }, }; From 327f334213b4a40efc6f8575b13a23f5b41d3e63 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Thu, 17 May 2018 14:03:26 -0700 Subject: [PATCH 05/17] restore tmp removal --- tasks/e2e-kitchensink.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index 2044845f0a1..b40a487ae4b 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -26,7 +26,7 @@ function cleanup { ps -ef | grep 'react-scripts' | grep -v grep | awk '{print $2}' | xargs kill -9 cd "$root_path" # TODO: fix "Device or resource busy" and remove ``|| $CI` - // rm -rf "$temp_app_path" "$temp_module_path" || $CI + rm -rf "$temp_app_path" "$temp_module_path" || $CI npm set registry "$original_npm_registry_url" yarn config set registry "$original_yarn_registry_url" } From 5528edaeb1940e5a457b1611367e3d362995f0cb Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Fri, 18 May 2018 21:48:42 -0700 Subject: [PATCH 06/17] preserve --- tasks/e2e-kitchensink.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index b40a487ae4b..cb671c9de40 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -26,7 +26,7 @@ function cleanup { ps -ef | grep 'react-scripts' | grep -v grep | awk '{print $2}' | xargs kill -9 cd "$root_path" # TODO: fix "Device or resource busy" and remove ``|| $CI` - rm -rf "$temp_app_path" "$temp_module_path" || $CI + # rm -rf "$temp_app_path" "$temp_module_path" || $CI npm set registry "$original_npm_registry_url" yarn config set registry "$original_yarn_registry_url" } From ed43e5c0f3950bd6494875d5b6f30a43fe11ed77 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 11:39:17 -0700 Subject: [PATCH 07/17] fix css tests --- .../kitchensink/integration/initDOM.js | 19 +-- .../kitchensink/integration/webpack.test.js | 110 ++++++++++-------- 2 files changed, 69 insertions(+), 60 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js index 3d0eb7a1c9c..36e8de9999f 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/initDOM.js @@ -12,7 +12,7 @@ const path = require('path'); const { expect } = require('chai'); let getMarkup; -let resourceLoader; +export let resourceLoader; if (process.env.E2E_FILE) { const file = path.isAbsolute(process.env.E2E_FILE) @@ -47,14 +47,11 @@ if (process.env.E2E_FILE) { resourceLoader = (resource, callback) => resource.defaultFetch(callback); } else { - it.only( - 'can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', - () => { - expect( - new Error("This isn't the error you are looking for.") - ).to.be.undefined(); - } - ); + it.only('can run jsdom (at least one of "E2E_FILE" or "E2E_URL" environment variables must be provided)', () => { + expect( + new Error("This isn't the error you are looking for.") + ).to.be.undefined(); + }); } export default feature => @@ -62,10 +59,6 @@ export default feature => const markup = await getMarkup(); const host = process.env.E2E_URL || 'http://www.example.org/spa:3000'; const doc = jsdom.jsdom(markup, { - features: { - FetchExternalResources: ['script', 'css'], - ProcessExternalResources: ['script'], - }, created: (_, win) => win.addEventListener('ReactFeatureDidMount', () => resolve(doc), true), deferClose: true, diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index c8dd07f0922..000f643334b 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -6,77 +6,89 @@ */ import { expect } from 'chai'; -import initDOM from './initDOM'; +import initDOM, { resourceLoader } from './initDOM'; describe('Integration', () => { describe('Webpack plugins', () => { it('css inclusion', async () => { const doc = await initDOM('css-inclusion'); - - expect( - doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') - ).to.match(/html\{/); - expect( - doc.getElementsByTagName('style')[1].textContent.replace(/\s/g, '') - ).to.match(/#feature-css-inclusion\{background:.+;color:.+}/); + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[1].href) }, + (_, textContent) => { + expect(textContent).to.match(/html\{/); + expect(textContent).to.match( + /#feature-css-inclusion\{background:.+;color:.+}/ + ); + } + ); }); it('css modules inclusion', async () => { const doc = await initDOM('css-modules-inclusion'); - - expect( - doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') - ).to.match(/.+style_cssModulesInclusion__.+\{background:.+;color:.+}/); - expect( - doc.getElementsByTagName('style')[1].textContent.replace(/\s/g, '') - ).to.match( - /.+assets_cssModulesIndexInclusion__.+\{background:.+;color:.+}/ + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[2].href) }, + (_, textContent) => { + expect(textContent).to.match( + /.+style_cssModulesInclusion__.+\{background:.+;color:.+}/ + ); + expect(textContent).to.match( + /.+assets_cssModulesIndexInclusion__.+\{background:.+;color:.+}/ + ); + } ); }); it('scss inclusion', async () => { const doc = await initDOM('scss-inclusion'); - - expect( - doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') - ).to.match(/#feature-scss-inclusion\{background:.+;color:.+}/); + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[2].href) }, + (_, textContent) => { + expect(textContent).to.match( + /#feature-scss-inclusion\{background:.+;color:.+}/ + ); + } + ); }); it('scss modules inclusion', async () => { const doc = await initDOM('scss-modules-inclusion'); - - expect( - doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') - ).to.match( - /.+scss-styles_scssModulesInclusion.+\{background:.+;color:.+}/ - ); - expect( - doc.getElementsByTagName('style')[1].textContent.replace(/\s/g, '') - ).to.match( - /.+assets_scssModulesIndexInclusion.+\{background:.+;color:.+}/ + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[2].href) }, + (_, textContent) => { + expect(textContent).to.match( + /.+scss-styles_scssModulesInclusion.+\{background:.+;color:.+}/ + ); + expect(textContent).to.match( + /.+assets_scssModulesIndexInclusion.+\{background:.+;color:.+}/ + ); + } ); }); it('sass inclusion', async () => { const doc = await initDOM('sass-inclusion'); - - expect( - doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') - ).to.match(/#feature-sass-inclusion\{background:.+;color:.+}/); + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[2].href) }, + (_, textContent) => { + expect(textContent).to.match( + /#feature-sass-inclusion\{background:.+;color:.+}/ + ); + } + ); }); it('sass modules inclusion', async () => { const doc = await initDOM('sass-modules-inclusion'); - - expect( - doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') - ).to.match( - /.+sass-styles_sassModulesInclusion.+\{background:.+;color:.+}/ - ); - expect( - doc.getElementsByTagName('style')[1].textContent.replace(/\s/g, '') - ).to.match( - /.+assets_sassModulesIndexInclusion.+\{background:.+;color:.+}/ + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[2].href) }, + (_, textContent) => { + expect(textContent).to.match( + /.+sass-styles_sassModulesInclusion.+\{background:.+;color:.+}/ + ); + expect(textContent).to.match( + /.+assets_sassModulesIndexInclusion.+\{background:.+;color:.+}/ + ); + } ); }); @@ -124,9 +136,13 @@ describe('Integration', () => { it('svg inclusion', async () => { const doc = await initDOM('svg-inclusion'); - - expect(doc.getElementById('feature-svg-inclusion').src).to.match( - /\/static\/media\/logo\..+\.svg$/ + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[2].href) }, + (_, textContent) => { + expect(doc.getElementById('feature-svg-inclusion').src).to.match( + /\/static\/media\/logo\..+\.svg$/ + ); + } ); }); From 8074dbfa8cfa4e127223523546489984b6027c30 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 11:41:08 -0700 Subject: [PATCH 08/17] fix test run --- tasks/e2e-installs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-installs.sh b/tasks/e2e-installs.sh index 6caf114c572..b58cd5eafca 100755 --- a/tasks/e2e-installs.sh +++ b/tasks/e2e-installs.sh @@ -86,7 +86,7 @@ yarn # Start local registry tmp_registry_log=`mktemp` -nohup npx verdaccio@2.7.2 &>$tmp_registry_log & +nohup npx verdaccio@2.7.2 -c tasks/verdaccio.yaml &>$tmp_registry_log & # Wait for `verdaccio` to boot grep -q 'http address' <(tail -f $tmp_registry_log) From f583cdf411767fde933e27f53a9072c5732567a4 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 12:24:04 -0700 Subject: [PATCH 09/17] fix svg test --- .../kitchensink/integration/webpack.test.js | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 000f643334b..629b7e0160e 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -136,13 +136,8 @@ describe('Integration', () => { it('svg inclusion', async () => { const doc = await initDOM('svg-inclusion'); - resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[2].href) }, - (_, textContent) => { - expect(doc.getElementById('feature-svg-inclusion').src).to.match( - /\/static\/media\/logo\..+\.svg$/ - ); - } + expect(doc.getElementById('feature-svg-inclusion').src).to.match( + /\/static\/media\/logo\..+\.svg$/ ); }); @@ -156,10 +151,12 @@ describe('Integration', () => { it('svg in css', async () => { const doc = await initDOM('svg-in-css'); - - expect( - doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '') - ).to.match(/\/static\/media\/logo\..+\.svg/); + resourceLoader( + { url: url.parse(doc.getElementsByTagName('link')[2].href) }, + (_, textContent) => { + expect(textContent).to.match(/\/static\/media\/logo\..+\.svg/); + } + ); }); it('unknown ext inclusion', async () => { From 969297241dd70e9140f63d1fd3478064329ab00d Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 12:24:32 -0700 Subject: [PATCH 10/17] revert tmp dir --- tasks/e2e-kitchensink.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index cb671c9de40..b40a487ae4b 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -26,7 +26,7 @@ function cleanup { ps -ef | grep 'react-scripts' | grep -v grep | awk '{print $2}' | xargs kill -9 cd "$root_path" # TODO: fix "Device or resource busy" and remove ``|| $CI` - # rm -rf "$temp_app_path" "$temp_module_path" || $CI + rm -rf "$temp_app_path" "$temp_module_path" || $CI npm set registry "$original_npm_registry_url" yarn config set registry "$original_yarn_registry_url" } From 9c98866e20a249f5c4e91496ba83223d5f7e0540 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 17:15:35 -0700 Subject: [PATCH 11/17] fix import --- .../fixtures/kitchensink/integration/webpack.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index 629b7e0160e..a8ea5be214b 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -7,6 +7,7 @@ import { expect } from 'chai'; import initDOM, { resourceLoader } from './initDOM'; +import url from 'url'; describe('Integration', () => { describe('Webpack plugins', () => { From ad59f597bf24c33ddf22361016e0adc48acde39e Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 17:38:25 -0700 Subject: [PATCH 12/17] fix import --- tasks/e2e-kitchensink.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index b40a487ae4b..cb671c9de40 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -26,7 +26,7 @@ function cleanup { ps -ef | grep 'react-scripts' | grep -v grep | awk '{print $2}' | xargs kill -9 cd "$root_path" # TODO: fix "Device or resource busy" and remove ``|| $CI` - rm -rf "$temp_app_path" "$temp_module_path" || $CI + # rm -rf "$temp_app_path" "$temp_module_path" || $CI npm set registry "$original_npm_registry_url" yarn config set registry "$original_yarn_registry_url" } From 886d21f3fdbb660831f3e7ed7b845c5a8e9c5169 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 19:27:54 -0700 Subject: [PATCH 13/17] help debugging --- .../fixtures/kitchensink/integration/webpack.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index a8ea5be214b..d324ffbc5dc 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -13,6 +13,7 @@ describe('Integration', () => { describe('Webpack plugins', () => { it('css inclusion', async () => { const doc = await initDOM('css-inclusion'); + console.log(doc.documentElement.innerHTML); resourceLoader( { url: url.parse(doc.getElementsByTagName('link')[1].href) }, (_, textContent) => { @@ -26,6 +27,7 @@ describe('Integration', () => { it('css modules inclusion', async () => { const doc = await initDOM('css-modules-inclusion'); + console.log(doc.documentElement.innerHTML); resourceLoader( { url: url.parse(doc.getElementsByTagName('link')[2].href) }, (_, textContent) => { @@ -41,6 +43,7 @@ describe('Integration', () => { it('scss inclusion', async () => { const doc = await initDOM('scss-inclusion'); + console.log(doc.documentElement.innerHTML); resourceLoader( { url: url.parse(doc.getElementsByTagName('link')[2].href) }, (_, textContent) => { @@ -53,6 +56,7 @@ describe('Integration', () => { it('scss modules inclusion', async () => { const doc = await initDOM('scss-modules-inclusion'); + console.log(doc.documentElement.innerHTML); resourceLoader( { url: url.parse(doc.getElementsByTagName('link')[2].href) }, (_, textContent) => { From e231801501f0dc49c213d6f28ecfba0b39b1180c Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 20:03:21 -0700 Subject: [PATCH 14/17] fix tests --- .../kitchensink/integration/webpack.test.js | 104 ++++++------------ 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js index d324ffbc5dc..b79c1ec8785 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -9,92 +9,65 @@ import { expect } from 'chai'; import initDOM, { resourceLoader } from './initDOM'; import url from 'url'; -describe('Integration', () => { - describe('Webpack plugins', () => { - it('css inclusion', async () => { - const doc = await initDOM('css-inclusion'); - console.log(doc.documentElement.innerHTML); +const matchCSS = (doc, regexes) => { + if (process.env.E2E_FILE) { + const elements = doc.getElementsByTagName('link'); + let href = ""; + for (const elem of elements) { + if (elem.rel === 'stylesheet') { + href = elem.href; + } + } resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[1].href) }, + { url: url.parse(href) }, (_, textContent) => { - expect(textContent).to.match(/html\{/); - expect(textContent).to.match( - /#feature-css-inclusion\{background:.+;color:.+}/ - ); + for (const regex of regexes) { + expect(textContent).to.match(regex); + } } ); + + } else { + for (let i = 0; i < regexes.length; ++i) { + expect(doc.getElementsByTagName('style')[i].textContent.replace(/\s/g, '')).to.match(regexes[i]); + } + } +} + +describe('Integration', () => { + describe('Webpack plugins', () => { + it('css inclusion', async () => { + const doc = await initDOM('css-inclusion'); + matchCSS(doc, [/html\{/, /#feature-css-inclusion\{background:.+;color:.+}/]); }); it('css modules inclusion', async () => { const doc = await initDOM('css-modules-inclusion'); - console.log(doc.documentElement.innerHTML); - resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[2].href) }, - (_, textContent) => { - expect(textContent).to.match( - /.+style_cssModulesInclusion__.+\{background:.+;color:.+}/ - ); - expect(textContent).to.match( - /.+assets_cssModulesIndexInclusion__.+\{background:.+;color:.+}/ - ); - } - ); + matchCSS(doc, [/.+style_cssModulesInclusion__.+\{background:.+;color:.+}/, + /.+assets_cssModulesIndexInclusion__.+\{background:.+;color:.+}/]); }); it('scss inclusion', async () => { const doc = await initDOM('scss-inclusion'); - console.log(doc.documentElement.innerHTML); - resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[2].href) }, - (_, textContent) => { - expect(textContent).to.match( - /#feature-scss-inclusion\{background:.+;color:.+}/ - ); - } - ); + matchCSS(doc, [/#feature-scss-inclusion\{background:.+;color:.+}/]); }); it('scss modules inclusion', async () => { const doc = await initDOM('scss-modules-inclusion'); - console.log(doc.documentElement.innerHTML); - resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[2].href) }, - (_, textContent) => { - expect(textContent).to.match( - /.+scss-styles_scssModulesInclusion.+\{background:.+;color:.+}/ - ); - expect(textContent).to.match( - /.+assets_scssModulesIndexInclusion.+\{background:.+;color:.+}/ - ); - } - ); + matchCSS(doc, [/.+scss-styles_scssModulesInclusion.+\{background:.+;color:.+}/, + /.+assets_scssModulesIndexInclusion.+\{background:.+;color:.+}/]); + }); it('sass inclusion', async () => { const doc = await initDOM('sass-inclusion'); - resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[2].href) }, - (_, textContent) => { - expect(textContent).to.match( - /#feature-sass-inclusion\{background:.+;color:.+}/ - ); - } - ); + matchCSS(doc, [/#feature-sass-inclusion\{background:.+;color:.+}/]); }); it('sass modules inclusion', async () => { const doc = await initDOM('sass-modules-inclusion'); - resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[2].href) }, - (_, textContent) => { - expect(textContent).to.match( - /.+sass-styles_sassModulesInclusion.+\{background:.+;color:.+}/ - ); - expect(textContent).to.match( - /.+assets_sassModulesIndexInclusion.+\{background:.+;color:.+}/ - ); - } - ); + matchCSS([/.+sass-styles_sassModulesInclusion.+\{background:.+;color:.+}/, + /.+assets_sassModulesIndexInclusion.+\{background:.+;color:.+}/]); }); it('graphql files inclusion', async () => { @@ -156,12 +129,7 @@ describe('Integration', () => { it('svg in css', async () => { const doc = await initDOM('svg-in-css'); - resourceLoader( - { url: url.parse(doc.getElementsByTagName('link')[2].href) }, - (_, textContent) => { - expect(textContent).to.match(/\/static\/media\/logo\..+\.svg/); - } - ); + matchCSS(doc, [/\/static\/media\/logo\..+\.svg/]); }); it('unknown ext inclusion', async () => { From 6e83944025ee90718bcb5285906a49e0b808bc45 Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 20:16:44 -0700 Subject: [PATCH 15/17] fix sass test --- .../fixtures/kitchensink/integration/webpack.test.js | 2 +- 1 file changed, 1 insertion(+), 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 b79c1ec8785..ff3d383219d 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js @@ -66,7 +66,7 @@ describe('Integration', () => { it('sass modules inclusion', async () => { const doc = await initDOM('sass-modules-inclusion'); - matchCSS([/.+sass-styles_sassModulesInclusion.+\{background:.+;color:.+}/, + matchCSS(doc, [/.+sass-styles_sassModulesInclusion.+\{background:.+;color:.+}/, /.+assets_sassModulesIndexInclusion.+\{background:.+;color:.+}/]); }); From 2c5be477d75d2f54279159695e4a597ebcac3bcb Mon Sep 17 00:00:00 2001 From: Jack Zhao Date: Sat, 19 May 2018 20:31:26 -0700 Subject: [PATCH 16/17] restore cleanup --- tasks/e2e-kitchensink.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index cb671c9de40..b40a487ae4b 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -26,7 +26,7 @@ function cleanup { ps -ef | grep 'react-scripts' | grep -v grep | awk '{print $2}' | xargs kill -9 cd "$root_path" # TODO: fix "Device or resource busy" and remove ``|| $CI` - # rm -rf "$temp_app_path" "$temp_module_path" || $CI + rm -rf "$temp_app_path" "$temp_module_path" || $CI npm set registry "$original_npm_registry_url" yarn config set registry "$original_yarn_registry_url" } From d72678fb0c02145d24b7684802a3f5cfc94bd746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Cederstr=C3=B6m?= Date: Sun, 20 May 2018 19:22:24 +0200 Subject: [PATCH 17/17] - [x] Upgrade to webpack 4.8.X (#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 --- package.json | 14 +- packages/babel-preset-react-app/package.json | 2 +- .../confusing-browser-globals/package.json | 2 +- packages/eslint-config-react-app/package.json | 2 +- .../react-dev-utils/InterpolateHtmlPlugin.js | 9 +- packages/react-dev-utils/ModuleScopePlugin.js | 128 +++++------ packages/react-dev-utils/README.md | 14 +- .../WatchMissingNodeModulesPlugin.js | 10 +- .../react-dev-utils/WebpackDevServerUtils.js | 4 +- packages/react-dev-utils/package.json | 18 +- packages/react-error-overlay/package.json | 29 +-- .../webpack.config.iframe.js | 32 +-- .../react-error-overlay/webpack.config.js | 11 + .../config/webpack.config.dev.js | 65 +++--- .../config/webpack.config.prod.js | 200 ++++++++---------- .../config/webpackDevServer.config.js | 2 +- packages/react-scripts/package.json | 63 +++--- 17 files changed, 304 insertions(+), 301 deletions(-) diff --git a/package.json b/package.json index 1084992025b..e8309674b8b 100644 --- a/package.json +++ b/package.json @@ -19,16 +19,16 @@ "precommit": "lint-staged" }, "devDependencies": { - "eslint": "4.15.0", - "execa": "^0.9.0", - "husky": "^0.13.2", - "lerna": "2.6.0", - "lerna-changelog": "^0.6.0", + "eslint": "4.19.1", + "execa": "^0.10.0", + "husky": "^0.14.3", + "lerna": "2.9.1", + "lerna-changelog": "^0.7.0", "lint-staged": "^7.0.5", "meow": "^4.0.0", "multimatch": "^2.1.0", - "prettier": "1.6.1", - "svg-term-cli": "^2.0.3", + "prettier": "1.12.1", + "svg-term-cli": "^2.1.1", "tempy": "^0.2.1" }, "lint-staged": { diff --git a/packages/babel-preset-react-app/package.json b/packages/babel-preset-react-app/package.json index 9df5dcb7326..32054a98747 100644 --- a/packages/babel-preset-react-app/package.json +++ b/packages/babel-preset-react-app/package.json @@ -27,6 +27,6 @@ "@babel/preset-react": "7.0.0-beta.46", "babel-plugin-macros": "2.2.1", "babel-plugin-transform-dynamic-import": "2.0.0", - "babel-plugin-transform-react-remove-prop-types": "0.4.12" + "babel-plugin-transform-react-remove-prop-types": "0.4.13" } } diff --git a/packages/confusing-browser-globals/package.json b/packages/confusing-browser-globals/package.json index 874bec0a52b..88767c4d0f7 100644 --- a/packages/confusing-browser-globals/package.json +++ b/packages/confusing-browser-globals/package.json @@ -16,6 +16,6 @@ "index.js" ], "devDependencies": { - "jest": "22.4.1" + "jest": "22.4.3" } } diff --git a/packages/eslint-config-react-app/package.json b/packages/eslint-config-react-app/package.json index c4b51925e69..35c60230a74 100644 --- a/packages/eslint-config-react-app/package.json +++ b/packages/eslint-config-react-app/package.json @@ -16,7 +16,7 @@ "eslint-plugin-flowtype": "^2.34.1", "eslint-plugin-import": "^2.6.0", "eslint-plugin-jsx-a11y": "^6.0.2", - "eslint-plugin-react": "^7.7.0" + "eslint-plugin-react": "^7.8.2" }, "dependencies": { "confusing-browser-globals": "^1.0.0" diff --git a/packages/react-dev-utils/InterpolateHtmlPlugin.js b/packages/react-dev-utils/InterpolateHtmlPlugin.js index 9233bdefa3c..5100349f335 100644 --- a/packages/react-dev-utils/InterpolateHtmlPlugin.js +++ b/packages/react-dev-utils/InterpolateHtmlPlugin.js @@ -22,10 +22,10 @@ class InterpolateHtmlPlugin { } apply(compiler) { - compiler.plugin('compilation', compilation => { - compilation.plugin( - 'html-webpack-plugin-before-html-processing', - (data, callback) => { + compiler.hooks.compilation.tap('InterpolateHtmlPlugin', compilation => { + compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing.tap( + 'InterpolateHtmlPlugin', + data => { // Run HTML through a series of user-specified string replacements. Object.keys(this.replacements).forEach(key => { const value = this.replacements[key]; @@ -34,7 +34,6 @@ class InterpolateHtmlPlugin { value ); }); - callback(null, data); } ); }); diff --git a/packages/react-dev-utils/ModuleScopePlugin.js b/packages/react-dev-utils/ModuleScopePlugin.js index 695426331b9..a16954c91ed 100644 --- a/packages/react-dev-utils/ModuleScopePlugin.js +++ b/packages/react-dev-utils/ModuleScopePlugin.js @@ -18,70 +18,72 @@ class ModuleScopePlugin { apply(resolver) { const { appSrcs } = this; - resolver.plugin('file', (request, callback) => { - // Unknown issuer, probably webpack internals - if (!request.context.issuer) { - return callback(); - } - if ( - // If this resolves to a node_module, we don't care what happens next - request.descriptionFileRoot.indexOf('/node_modules/') !== -1 || - request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 || - // Make sure this request was manual - !request.__innerRequest_request - ) { - return callback(); - } - // Resolve the issuer from our appSrc and make sure it's one of our files - // Maybe an indexOf === 0 would be better? - if ( - appSrcs.every(appSrc => { - const relative = path.relative(appSrc, request.context.issuer); - // If it's not in one of our app src or a subdirectory, not our request! - return relative.startsWith('../') || relative.startsWith('..\\'); - }) - ) { - return callback(); - } - const requestFullPath = path.resolve( - path.dirname(request.context.issuer), - request.__innerRequest_request - ); - if (this.allowedFiles.has(requestFullPath)) { - return callback(); - } - // Find path from src to the requested file - // Error if in a parent directory of all given appSrcs - if ( - appSrcs.every(appSrc => { - const requestRelative = path.relative(appSrc, requestFullPath); - return ( - requestRelative.startsWith('../') || - requestRelative.startsWith('..\\') - ); - }) - ) { - callback( - new Error( - `You attempted to import ${chalk.cyan( - request.__innerRequest_request - )} which falls outside of the project ${chalk.cyan( - 'src/' - )} directory. ` + - `Relative imports outside of ${chalk.cyan( - 'src/' - )} are not supported. ` + - `You can either move it inside ${chalk.cyan( - 'src/' - )}, or add a symlink to it from project's ${chalk.cyan( - 'node_modules/' - )}.` - ), - request + resolver.hooks.file.tapAsync( + 'ModuleScopePlugin', + (request, contextResolver, callback) => { + // Unknown issuer, probably webpack internals + if (!request.context.issuer) { + return callback(); + } + if ( + // If this resolves to a node_module, we don't care what happens next + request.descriptionFileRoot.indexOf('/node_modules/') !== -1 || + request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 || + // Make sure this request was manual + !request.__innerRequest_request + ) { + return callback(); + } + // Resolve the issuer from our appSrc and make sure it's one of our files + // Maybe an indexOf === 0 would be better? + if ( + appSrcs.every(appSrc => { + const relative = path.relative(appSrc, request.context.issuer); + // If it's not in one of our app src or a subdirectory, not our request! + return relative.startsWith('../') || relative.startsWith('..\\'); + }) + ) { + return callback(); + } + const requestFullPath = path.resolve( + path.dirname(request.context.issuer), + request.__innerRequest_request ); - } else { - callback(); - } + if (this.allowedFiles.has(requestFullPath)) { + return callback(); + } + // Find path from src to the requested file + // Error if in a parent directory of all given appSrcs + if ( + appSrcs.every(appSrc => { + const requestRelative = path.relative(appSrc, requestFullPath); + return ( + requestRelative.startsWith('../') || + requestRelative.startsWith('..\\') + ); + }) + ) { + callback( + new Error( + `You attempted to import ${chalk.cyan( + request.__innerRequest_request + )} which falls outside of the project ${chalk.cyan( + 'src/' + )} directory. ` + + `Relative imports outside of ${chalk.cyan( + 'src/' + )} are not supported. ` + + `You can either move it inside ${chalk.cyan( + 'src/' + )}, or add a symlink to it from project's ${chalk.cyan( + 'node_modules/' + )}.` + ), + request + ); + } else { + callback(); + } }); } } diff --git a/packages/react-dev-utils/README.md b/packages/react-dev-utils/README.md index f63febe7c65..9d53e05db05 100644 --- a/packages/react-dev-utils/README.md +++ b/packages/react-dev-utils/README.md @@ -38,6 +38,11 @@ module.exports = { }, // ... plugins: [ + // Generates an `index.html` file with the