From c3f621dc646e6c21eec6231751f1ca3c0c8535c1 Mon Sep 17 00:00:00 2001 From: Sam Cooke Date: Mon, 28 Dec 2020 15:47:10 +1000 Subject: [PATCH 1/6] Flight-webpack: Include ts\tsx\jsx modules as well --- .../react-server-dom-webpack/src/ReactFlightWebpackPlugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js index ecdd66ed82c66..ffd3dbe47dc59 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js +++ b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js @@ -175,7 +175,7 @@ export default class ReactFlightWebpackPlugin { // TODO: Hook into deps instead of the target module. // That way we know by the type of dep whether to include. // It also resolves conflicts when the same module is in multiple chunks. - if (!/\.client\.js$/.test(mod.resource)) { + if (!/\.client\.(js|jsx|ts|tsx)$/.test(mod.resource)) { return; } const moduleExports = {}; From 2a6c13676ed9eebc56d1c0881e9429bb14f76295 Mon Sep 17 00:00:00 2001 From: Sam Cooke Date: Mon, 28 Dec 2020 16:38:02 +1000 Subject: [PATCH 2/6] Add tests - This commit adds tests running in both webpack v4 and webpack v5. - Interestingly, both pass - I expected webpack v5 too fail. Will investigate --- package.json | 3 + .../ReactFlightWebpackPlugin-test.js | 136 ++++++ .../src/__tests__/fixture/Form.client.js | 4 + .../__tests__/fixture/FormServer.server.js | 4 + .../src/__tests__/fixture/entry.js | 8 + .../src/__tests__/fixture/package.json | 3 + yarn.lock | 420 +++++++++++++++++- 7 files changed, 572 insertions(+), 6 deletions(-) create mode 100644 packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js create mode 100644 packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js create mode 100644 packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js create mode 100644 packages/react-server-dom-webpack/src/__tests__/fixture/entry.js create mode 100644 packages/react-server-dom-webpack/src/__tests__/fixture/package.json diff --git a/package.json b/package.json index bf225d9cdc81c..8ea886f7ccbea 100644 --- a/package.json +++ b/package.json @@ -139,5 +139,8 @@ "version-check": "node ./scripts/tasks/version-check.js", "merge-fork": "node ./scripts/merge-fork/merge-fork.js", "replace-fork": "node ./scripts/merge-fork/replace-fork.js" + }, + "dependencies": { + "webpack5": "npm:webpack@5" } } diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js new file mode 100644 index 0000000000000..65a72e82200a4 --- /dev/null +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js @@ -0,0 +1,136 @@ +const webpack5 = require('webpack5'); +const webpack4 = require('webpack'); +const path = require('path'); +const os = require('os'); +const FlightPlugin = require('../ReactFlightWebpackPlugin').default; + +describe('ReactFlightWebpackPlugin', () => { + // Probably too big a timeout. + jest.setTimeout(5000 * 5); + + test('produces manifest - webpack v4', done => { + const entry = path.resolve(path.join(__dirname, 'fixture', 'entry.js')); + + const plugin = new FlightPlugin({isServer: false}); + + const output = webpack4({ + entry, + plugins: [plugin], + output: { + // Output + path: path.resolve(path.join(os.tmpdir(), 'output')), + }, + mode: 'development', + }); + + output.run((err, stats) => { + expect(err).toBeNull(); + const fileName = plugin.manifestFilename; //'react-client-manifest.json' + + const pluginOutput = stats.compilation.assets[fileName]; + console.log(pluginOutput); + + const producedManifest = pluginOutput.source(); + + const manifest = JSON.parse(producedManifest); + // The key uses the absolute filename, which means we can't snapshot it. + const key = + 'file://' + + path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')); + + expect(manifest[key]).toMatchInlineSnapshot(` + Object { + "": Object { + "chunks": Array [ + "main", + ], + "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", + "name": "", + }, + "*": Object { + "chunks": Array [ + "main", + ], + "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", + "name": "*", + }, + "true": Object { + "chunks": Array [ + "main", + ], + "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", + "name": true, + }, + } + `); + + done(); + }); + }); + + test('produces manifest - webpack v5', done => { + const entry = path.resolve(path.join(__dirname, 'fixture', 'entry.js')); + + const plugin = new FlightPlugin({isServer: false}); + const fileName = plugin.manifestFilename; + + const output = webpack5({ + entry: { + main: entry, + client: path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')), + }, + plugins: [plugin], + cache: undefined, + output: { + // Output + path: path.resolve(path.join(os.tmpdir(), 'output')), + }, + mode: 'development', + }); + + const originalFileSystem = output.outputFileSystem; + + output.outputFileSystem = { + ...originalFileSystem, + writeFile: (dest, contents, err) => { + if (dest.includes(fileName)) { + assert(contents.toString()); + done(); + } + }, + }; + + output.run((err, stats, foo) => { + expect(err).toBeNull(); + }); + }); +}); + +function assert(manifestContents) { + const key = + 'file://' + path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')); + expect(JSON.parse(manifestContents)[key]).toMatchInlineSnapshot(` + Object { + "": Object { + "chunks": Array [ + "client", + ], + "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", + "name": "", + }, + "*": Object { + "chunks": Array [ + "client", + ], + "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", + "name": "*", + }, + "undefined": Object { + "chunks": Array [ + "client", + ], + "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", + }, + } + `); +} diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js new file mode 100644 index 0000000000000..5abee0fe5021c --- /dev/null +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js @@ -0,0 +1,4 @@ + +module.exports = function Form() { + console.log('Form Rendered!') +} \ No newline at end of file diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js b/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js new file mode 100644 index 0000000000000..82e19d59f024f --- /dev/null +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js @@ -0,0 +1,4 @@ + +module.exports = function Form() { + console.log('Form Rendered! On the server') +} \ No newline at end of file diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js b/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js new file mode 100644 index 0000000000000..1ccbfa1ce8eba --- /dev/null +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js @@ -0,0 +1,8 @@ + +const ClientComponent = require('./Form.client'); +const ServerComponent = require('./FormServer.server.js'); + +console.log( + ClientComponent, + ServerComponent +); diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/package.json b/packages/react-server-dom-webpack/src/__tests__/fixture/package.json new file mode 100644 index 0000000000000..d102758c0c35e --- /dev/null +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/package.json @@ -0,0 +1,3 @@ +{ + "name": "fixture" +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 7b6cb08909628..dff9a64f27684 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2100,16 +2100,37 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/eslint-scope@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" + integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== +"@types/eslint@*": + version "7.2.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.6.tgz#5e9aff555a975596c03a98b59ecd103decc70c3c" + integrity sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + "@types/estree@*": version "0.0.42" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.42.tgz#8d0c1f480339efedb3e46070e22dd63e0430dd11" integrity sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ== +"@types/estree@^0.0.45": + version "0.0.45" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" + integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" @@ -2149,6 +2170,11 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/json-schema@*", "@types/json-schema@^7.0.6": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== + "@types/json-schema@^7.0.3": version "7.0.3" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" @@ -2420,21 +2446,45 @@ "@webassemblyjs/helper-wasm-bytecode" "1.9.0" "@webassemblyjs/wast-parser" "1.9.0" +"@webassemblyjs/ast@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.1.tgz#76c6937716d68bf1484c15139f5ed30b9abc8bb4" + integrity sha512-uMu1nCWn2Wxyy126LlGqRVlhdTOsO/bsBRI4dNq3+6SiSuRKRQX6ejjKgh82LoGAPSq72lDUiQ4FWVaf0PecYw== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/wast-parser" "1.9.1" + "@webassemblyjs/floating-point-hex-parser@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== +"@webassemblyjs/floating-point-hex-parser@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.1.tgz#9eb0ff90a1cdeef51f36ba533ed9f06b5cdadd09" + integrity sha512-5VEKu024RySmLKTTBl9q1eO/2K5jk9ZS+2HXDBLA9s9p5IjkaXxWiDb/+b7wSQp6FRdLaH1IVGIfOex58Na2pg== + "@webassemblyjs/helper-api-error@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== +"@webassemblyjs/helper-api-error@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.1.tgz#ad89015c4246cd7f5ed0556700237f8b9c2c752f" + integrity sha512-y1lGmfm38djrScwpeL37rRR9f1D6sM8RhMpvM7CYLzOlHVboouZokXK/G88BpzW0NQBSvCCOnW5BFhten4FPfA== + "@webassemblyjs/helper-buffer@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== +"@webassemblyjs/helper-buffer@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.1.tgz#186e67ac25f9546ea7939759413987f157524133" + integrity sha512-uS6VSgieHbk/m4GSkMU5cqe/5TekdCzQso4revCIEQ3vpGZgqSSExi4jWpTWwDpAHOIAb1Jfrs0gUB9AA4n71w== + "@webassemblyjs/helper-code-frame@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" @@ -2442,11 +2492,23 @@ dependencies: "@webassemblyjs/wast-printer" "1.9.0" +"@webassemblyjs/helper-code-frame@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.1.tgz#aab177b7cc87a318a8f8664ad68e2c3828ebc42b" + integrity sha512-ZQ2ZT6Evk4DPIfD+92AraGYaFIqGm4U20e7FpXwl7WUo2Pn1mZ1v8VGH8i+Y++IQpxPbQo/UyG0Khs7eInskzA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.1" + "@webassemblyjs/helper-fsm@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== +"@webassemblyjs/helper-fsm@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.1.tgz#527e91628e84d13d3573884b3dc4c53a81dcb911" + integrity sha512-J32HGpveEqqcKFS0YbgicB0zAlpfIxJa5MjxDxhu3i5ltPcVfY5EPvKQ1suRguFPehxiUs+/hfkwPEXom/l0lw== + "@webassemblyjs/helper-module-context@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" @@ -2454,11 +2516,23 @@ dependencies: "@webassemblyjs/ast" "1.9.0" +"@webassemblyjs/helper-module-context@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.1.tgz#778670b3d471f7cf093d1e7c0dde431b54310e16" + integrity sha512-IEH2cMmEQKt7fqelLWB5e/cMdZXf2rST1JIrzWmf4XBt3QTxGdnnLvV4DYoN8pJjOx0VYXsWg+yF16MmJtolZg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== +"@webassemblyjs/helper-wasm-bytecode@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.1.tgz#563f59bcf409ccf469edde168b9426961ffbf6df" + integrity sha512-i2rGTBqFUcSXxyjt2K4vm/3kkHwyzG6o427iCjcIKjOqpWH8SEem+xe82jUk1iydJO250/CvE5o7hzNAMZf0dQ== + "@webassemblyjs/helper-wasm-section@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" @@ -2469,6 +2543,16 @@ "@webassemblyjs/helper-wasm-bytecode" "1.9.0" "@webassemblyjs/wasm-gen" "1.9.0" +"@webassemblyjs/helper-wasm-section@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.1.tgz#f7988f94c12b01b99a16120cb01dc099b00e4798" + integrity sha512-FetqzjtXZr2d57IECK+aId3D0IcGweeM0CbAnJHkYJkcRTHP+YcMb7Wmc0j21h5UWBpwYGb9dSkK/93SRCTrGg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-buffer" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/wasm-gen" "1.9.1" + "@webassemblyjs/ieee754@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" @@ -2476,6 +2560,13 @@ dependencies: "@xtuc/ieee754" "^1.2.0" +"@webassemblyjs/ieee754@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.1.tgz#3b715871ca7d75784717cf9ceca9d7b81374b8af" + integrity sha512-EvTG9M78zP1MmkBpUjGQHZc26DzPGZSLIPxYHCjQsBMo60Qy2W34qf8z0exRDtxBbRIoiKa5dFyWer/7r1aaSQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + "@webassemblyjs/leb128@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" @@ -2483,11 +2574,23 @@ dependencies: "@xtuc/long" "4.2.2" +"@webassemblyjs/leb128@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.1.tgz#b2ecaa39f9e8277cc9c707c1ca8b2aa7b27d0b72" + integrity sha512-Oc04ub0vFfLnF+2/+ki3AE+anmW4sv9uNBqb+79fgTaPv6xJsOT0dhphNfL3FrME84CbX/D1T9XT8tjFo0IIiw== + dependencies: + "@xtuc/long" "4.2.2" + "@webassemblyjs/utf8@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== +"@webassemblyjs/utf8@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.1.tgz#d02d9daab85cda3211e43caf31dca74c260a73b0" + integrity sha512-llkYtppagjCodFjo0alWOUhAkfOiQPQDIc5oA6C9sFAXz7vC9QhZf/f8ijQIX+A9ToM3c9Pq85X0EX7nx9gVhg== + "@webassemblyjs/wasm-edit@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" @@ -2502,6 +2605,20 @@ "@webassemblyjs/wasm-parser" "1.9.0" "@webassemblyjs/wast-printer" "1.9.0" +"@webassemblyjs/wasm-edit@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.1.tgz#e27a6bdbf78e5c72fa812a2fc3cbaad7c3e37578" + integrity sha512-S2IaD6+x9B2Xi8BCT0eGsrXXd8UxAh2LVJpg1ZMtHXnrDcsTtIX2bDjHi40Hio6Lc62dWHmKdvksI+MClCYbbw== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-buffer" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/helper-wasm-section" "1.9.1" + "@webassemblyjs/wasm-gen" "1.9.1" + "@webassemblyjs/wasm-opt" "1.9.1" + "@webassemblyjs/wasm-parser" "1.9.1" + "@webassemblyjs/wast-printer" "1.9.1" + "@webassemblyjs/wasm-gen@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" @@ -2513,6 +2630,17 @@ "@webassemblyjs/leb128" "1.9.0" "@webassemblyjs/utf8" "1.9.0" +"@webassemblyjs/wasm-gen@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.1.tgz#56a0787d1fa7994fdc7bea59004e5bec7189c5fc" + integrity sha512-bqWI0S4lBQsEN5FTZ35vYzfKUJvtjNnBobB1agCALH30xNk1LToZ7Z8eiaR/Z5iVECTlBndoRQV3F6mbEqE/fg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/ieee754" "1.9.1" + "@webassemblyjs/leb128" "1.9.1" + "@webassemblyjs/utf8" "1.9.1" + "@webassemblyjs/wasm-opt@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" @@ -2523,6 +2651,16 @@ "@webassemblyjs/wasm-gen" "1.9.0" "@webassemblyjs/wasm-parser" "1.9.0" +"@webassemblyjs/wasm-opt@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.1.tgz#fbdf8943a825e6dcc4cd69c3e092289fa4aec96c" + integrity sha512-gSf7I7YWVXZ5c6XqTEqkZjVs8K1kc1k57vsB6KBQscSagDNbAdxt6MwuJoMjsE1yWY1tsuL+pga268A6u+Fdkg== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-buffer" "1.9.1" + "@webassemblyjs/wasm-gen" "1.9.1" + "@webassemblyjs/wasm-parser" "1.9.1" + "@webassemblyjs/wasm-parser@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" @@ -2535,6 +2673,18 @@ "@webassemblyjs/leb128" "1.9.0" "@webassemblyjs/utf8" "1.9.0" +"@webassemblyjs/wasm-parser@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.1.tgz#5e8352a246d3f605312c8e414f7990de55aaedfa" + integrity sha512-ImM4N2T1MEIond0MyE3rXvStVxEmivQrDKf/ggfh5pP6EHu3lL/YTAoSrR7shrbKNPpeKpGesW1LIK/L4kqduw== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-api-error" "1.9.1" + "@webassemblyjs/helper-wasm-bytecode" "1.9.1" + "@webassemblyjs/ieee754" "1.9.1" + "@webassemblyjs/leb128" "1.9.1" + "@webassemblyjs/utf8" "1.9.1" + "@webassemblyjs/wast-parser@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" @@ -2547,6 +2697,18 @@ "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" +"@webassemblyjs/wast-parser@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.1.tgz#e25ef13585c060073c1db0d6bd94340fdeee7596" + integrity sha512-2xVxejXSvj3ls/o2TR/zI6p28qsGupjHhnHL6URULQRcXmryn3w7G83jQMcT7PHqUfyle65fZtWLukfdLdE7qw== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/floating-point-hex-parser" "1.9.1" + "@webassemblyjs/helper-api-error" "1.9.1" + "@webassemblyjs/helper-code-frame" "1.9.1" + "@webassemblyjs/helper-fsm" "1.9.1" + "@xtuc/long" "4.2.2" + "@webassemblyjs/wast-printer@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" @@ -2556,6 +2718,15 @@ "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" +"@webassemblyjs/wast-printer@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.1.tgz#b9f38e93652037d4f3f9c91584635af4191ed7c1" + integrity sha512-tDV8V15wm7mmbAH6XvQRU1X+oPGmeOzYsd6h7hlRLz6QpV4Ec/KKxM8OpLtFmQPLCreGxTp+HuxtH4pRIZyL9w== + dependencies: + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/wast-parser" "1.9.1" + "@xtuc/long" "4.2.2" + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -2642,6 +2813,11 @@ acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.0.4.tgz#7a3ae4191466a6984eee0fe3407a4f3aa9db8354" + integrity sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ== + adbkit-logcat@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/adbkit-logcat/-/adbkit-logcat-1.1.0.tgz#01d7f9b0cef9093a30bcb3b007efff301508962f" @@ -2760,6 +2936,11 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + ajv-merge-patch@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ajv-merge-patch/-/ajv-merge-patch-4.1.0.tgz#cd580e5860ac53431d6aa901fa3d5e2eb2b74a6c" @@ -2788,6 +2969,16 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^6.5.5, ajv@^6.9.1: version "6.10.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" @@ -3738,6 +3929,17 @@ browserslist@^4.12.0: escalade "^3.0.2" node-releases "^1.1.60" +browserslist@^4.14.5: + version "4.16.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.0.tgz#410277627500be3cb28a1bfe037586fbedf9488b" + integrity sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ== + dependencies: + caniuse-lite "^1.0.30001165" + colorette "^1.2.1" + electron-to-chromium "^1.3.621" + escalade "^3.1.1" + node-releases "^1.1.67" + browserslist@^4.8.3: version "4.8.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.5.tgz#691af4e327ac877b25e7a3f7ee869c4ef36cdea3" @@ -3974,6 +4176,11 @@ caniuse-lite@^1.0.30001111: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001114.tgz#2e88119afb332ead5eaa330e332e951b1c4bfea9" integrity sha512-ml/zTsfNBM+T1+mjglWRPgVsu2L76GAaADKX5f4t0pbhttEp0WMawJsHDYlFkVZkoA+89uvBRrVrEE4oqenzXQ== +caniuse-lite@^1.0.30001165: + version "1.0.30001170" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" + integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -4328,6 +4535,11 @@ color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +colorette@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" + integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== + colors@0.5.x: version "0.5.1" resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" @@ -5413,6 +5625,11 @@ electron-to-chromium@^1.3.523: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.538.tgz#15226638ee9db5d8e74f4c860cef6078d8e1e871" integrity sha512-rlyYXLlOoZkJuvY4AJXUpP7CHRVtwZz311HPVoEO1UHo/kqDCsP1pNas0A9paZuPEiYGdLwrjllF2hs69NEaTw== +electron-to-chromium@^1.3.621: + version "1.3.633" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz#16dd5aec9de03894e8d14a1db4cda8a369b9b7fe" + integrity sha512-bsVCsONiVX1abkWdH7KtpuDAhsQ3N3bjPYhROSAXE78roJKet0Y5wznA14JE9pzbwSZmSMAW6KiKYf1RvbTJkA== + electron@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/electron/-/electron-9.1.0.tgz#ca77600c9e4cd591298c340e013384114d3d8d05" @@ -5520,6 +5737,14 @@ enhanced-resolve@^4.1.1, enhanced-resolve@^4.3.0: memory-fs "^0.5.0" tapable "^1.0.0" +enhanced-resolve@^5.3.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.4.1.tgz#c89b0c34f17f931902ef2913a125d4b825b49b6f" + integrity sha512-4GbyIMzYktTFoRSmkbgZ1LU+RXwf4AQ8Z+rSuuh1dC8plp0PPeaWvx6+G4hh4KnUJ48VoxKbNyA1QQQIUpXjYA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + enquirer@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -5687,6 +5912,11 @@ escalade@^3.0.2: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + escape-goat@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" @@ -5840,6 +6070,14 @@ eslint-scope@^4.0.0, eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + eslint-utils@^1.3.1: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" @@ -6011,6 +6249,13 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + estraverse@^4.0.0, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -6021,7 +6266,7 @@ estraverse@^4.1.0, estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0: +estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== @@ -6071,6 +6316,11 @@ events@^3.0.0: resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== +events@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" + integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== + eventsource@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" @@ -6581,6 +6831,14 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + findup-sync@3.0.0, findup-sync@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" @@ -6961,6 +7219,11 @@ glob-stream@^6.1.0: to-absolute-glob "^2.0.0" unique-stream "^2.0.2" +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + glob@7.1.6, glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -8736,6 +8999,15 @@ jest-worker@^25.2.6: merge-stream "^2.0.0" supports-color "^7.0.0" +jest-worker@^26.6.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + jest@^25.2.7: version "25.2.7" resolved "https://registry.yarnpkg.com/jest/-/jest-25.2.7.tgz#3929a5f35cdd496f7756876a206b99a94e1e09ae" @@ -9185,6 +9457,11 @@ loader-runner@^2.4.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== +loader-runner@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.1.0.tgz#f70bc0c29edbabdf2043e7ee73ccc3fe1c96b42d" + integrity sha512-oR4lB4WvwFoC70ocraKhn5nkKSs23t57h9udUgw8o0iH8hMXeEoRuUgfcvgUwAJ1ZpRqBvcou4N2SMvM1DwMrA== + loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0: version "1.2.3" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" @@ -9234,6 +9511,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -9703,7 +9987,7 @@ mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.40.0" -mime-types@^2.1.26: +mime-types@^2.1.26, mime-types@^2.1.27: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== @@ -10006,6 +10290,11 @@ neo-async@^2.5.0, neo-async@^2.6.1: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + next-tick@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" @@ -10143,6 +10432,11 @@ node-releases@^1.1.60: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA== +node-releases@^1.1.67: + version "1.1.67" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" + integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== + node-rsa@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/node-rsa/-/node-rsa-1.0.5.tgz#854dc1b275729d69bc25883f83ca80705db9262e" @@ -10582,6 +10876,13 @@ p-limit@^2.1.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -10596,6 +10897,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -10999,6 +11307,13 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + plugin-error@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" @@ -11432,7 +11747,7 @@ randomatic@^1.1.3: is-number "^3.0.0" kind-of "^4.0.0" -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -12361,6 +12676,15 @@ schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: ajv "^6.12.2" ajv-keywords "^3.4.1" +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -12453,6 +12777,13 @@ serialize-javascript@^2.1.2: resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== +serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -12710,7 +13041,7 @@ sonic-boom@^1.0.0: atomic-sleep "^1.0.0" flatstr "^1.0.12" -source-list-map@^2.0.0: +source-list-map@^2.0.0, source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== @@ -12734,7 +13065,7 @@ source-map-support@0.5.16: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@0.5.19, source-map-support@^0.5.17, source-map-support@~0.5.12: +source-map-support@0.5.19, source-map-support@^0.5.17, source-map-support@~0.5.12, source-map-support@~0.5.19: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -12765,7 +13096,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: +source-map@^0.7.3, source-map@~0.7.2: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== @@ -13228,6 +13559,11 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== + tar-fs@^1.8.1: version "1.16.0" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.0.tgz#e877a25acbcc51d8c790da1c57c9cf439817b896" @@ -13316,6 +13652,18 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" +terser-webpack-plugin@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.0.3.tgz#ec60542db2421f45735c719d2e17dabfbb2e3e42" + integrity sha512-zFdGk8Lh9ZJGPxxPE6jwysOlATWB8GMW8HcfGULWA/nPal+3VdATflQvSBSLQJRCmYZnfFJl6vkRTiwJGNgPiQ== + dependencies: + jest-worker "^26.6.1" + p-limit "^3.0.2" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + source-map "^0.6.1" + terser "^5.3.8" + terser@^4.1.2: version "4.6.13" resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.13.tgz#e879a7364a5e0db52ba4891ecde007422c56a916" @@ -13334,6 +13682,15 @@ terser@^4.6.3: source-map "~0.6.1" source-map-support "~0.5.12" +terser@^5.3.8: + version "5.5.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289" + integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.19" + test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -14174,6 +14531,14 @@ watchpack@^1.7.4: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.0" +watchpack@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.0.tgz#e63194736bf3aa22026f7b191cd57907b0f9f696" + integrity sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" @@ -14382,6 +14747,44 @@ webpack-sources@^1.4.0, webpack-sources@^1.4.1: source-list-map "^2.0.0" source-map "~0.6.1" +webpack-sources@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac" + integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + +"webpack5@npm:webpack@5": + version "5.11.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.11.0.tgz#1647abc060441d86d01d8835b8f0fc1dae2fe76f" + integrity sha512-ubWv7iP54RqAC/VjixgpnLLogCFbAfSOREcSWnnOlZEU8GICC5eKmJSu6YEnph2N2amKqY9rvxSwgyHxVqpaRw== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.45" + "@webassemblyjs/ast" "1.9.1" + "@webassemblyjs/helper-module-context" "1.9.1" + "@webassemblyjs/wasm-edit" "1.9.1" + "@webassemblyjs/wasm-parser" "1.9.1" + acorn "^8.0.4" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.3.1" + eslint-scope "^5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.1.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + pkg-dir "^5.0.0" + schema-utils "^3.0.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.0.3" + watchpack "^2.0.0" + webpack-sources "^2.1.1" + webpack@^4.41.2, webpack@^4.43.0: version "4.43.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.43.0.tgz#c48547b11d563224c561dad1172c8aa0b8a678e6" @@ -14838,6 +15241,11 @@ yn@3.1.1: resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zip-dir@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/zip-dir/-/zip-dir-1.0.2.tgz#253f907aead62a21acd8721d8b88032b2411c051" From 71b978f3aec14266467e0bcba173c7415c3e97d4 Mon Sep 17 00:00:00 2001 From: Sam Cooke Date: Mon, 28 Dec 2020 17:15:22 +1000 Subject: [PATCH 3/6] Extend the test to include named imports --- .../ReactFlightWebpackPlugin-test.js | 119 +++++++++--------- .../src/__tests__/fixture/Form.client.js | 2 +- .../src/__tests__/fixture/entry.js | 2 +- 3 files changed, 61 insertions(+), 62 deletions(-) diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js index 65a72e82200a4..219068930b3e3 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js @@ -1,23 +1,51 @@ -const webpack5 = require('webpack5'); -const webpack4 = require('webpack'); const path = require('path'); const os = require('os'); -const FlightPlugin = require('../ReactFlightWebpackPlugin').default; + +function getDependencies(mode: 'wp5' | 'wp4') { + jest.resetModuleRegistry(); + let webpack; + if (mode === 'wp5') { + webpack = jest.requireActual('webpack5'); + // The code we are testing (ReactFlightWebpackPlugin) directly imports `webpack`. It cannot depend upon `webpack5` as + // consumers of `ReactFlightWebpackPlugin` are more likely to have installed wp5 just as `webpack`. So we fix this by mocking the + // `webpack` module, and return the webpack 5 instance that we required. + jest.mock('webpack', () => { + return webpack; + }); + // Sanity-check. If the webpack in package.json changes, this should catch that + expect(webpack.version).toMatch(/5\.[0-9]*\.[0-9]*/); + } else { + webpack = jest.requireActual('webpack'); + // Sanity-check. If the webpack in package.json changes, this should catch that + expect(webpack.version).toMatch(/4\.[0-9]*\.[0-9]*/); + } + + const FlightPlugin = require('../ReactFlightWebpackPlugin').default; + return { + FlightPlugin, + webpack, + }; +} describe('ReactFlightWebpackPlugin', () => { - // Probably too big a timeout. + // Running webpack can be slow, so we increase Jest's default timeout. These values are + // "magic", and not backed by any kind of logic or reasoning. jest.setTimeout(5000 * 5); test('produces manifest - webpack v4', done => { + const {webpack, FlightPlugin} = getDependencies('wp4'); + const entry = path.resolve(path.join(__dirname, 'fixture', 'entry.js')); const plugin = new FlightPlugin({isServer: false}); - const output = webpack4({ - entry, + const output = webpack({ + entry: { + main: entry, + client: path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')), + }, plugins: [plugin], output: { - // Output path: path.resolve(path.join(os.tmpdir(), 'output')), }, mode: 'development', @@ -32,37 +60,7 @@ describe('ReactFlightWebpackPlugin', () => { const producedManifest = pluginOutput.source(); - const manifest = JSON.parse(producedManifest); - // The key uses the absolute filename, which means we can't snapshot it. - const key = - 'file://' + - path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')); - - expect(manifest[key]).toMatchInlineSnapshot(` - Object { - "": Object { - "chunks": Array [ - "main", - ], - "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", - "name": "", - }, - "*": Object { - "chunks": Array [ - "main", - ], - "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", - "name": "*", - }, - "true": Object { - "chunks": Array [ - "main", - ], - "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", - "name": true, - }, - } - `); + assert(producedManifest); done(); }); @@ -70,11 +68,12 @@ describe('ReactFlightWebpackPlugin', () => { test('produces manifest - webpack v5', done => { const entry = path.resolve(path.join(__dirname, 'fixture', 'entry.js')); + const {webpack, FlightPlugin} = getDependencies('wp5'); const plugin = new FlightPlugin({isServer: false}); const fileName = plugin.manifestFilename; - const output = webpack5({ + const output = webpack({ entry: { main: entry, client: path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')), @@ -109,28 +108,28 @@ describe('ReactFlightWebpackPlugin', () => { function assert(manifestContents) { const key = 'file://' + path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')); - expect(JSON.parse(manifestContents)[key]).toMatchInlineSnapshot(` - Object { - "": Object { - "chunks": Array [ - "client", - ], - "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", - "name": "", + const manifestObj = JSON.parse(manifestContents); + + expect(manifestObj[key]).toBe( + expect.objectContaining({ + '': { + chunks: ['client'], + id: + './packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js', + name: '', }, - "*": Object { - "chunks": Array [ - "client", - ], - "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", - "name": "*", + '*': { + chunks: ['client'], + id: + './packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js', + name: '', }, - "undefined": Object { - "chunks": Array [ - "client", - ], - "id": "./packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js", + Form: { + chunks: ['client'], + id: + './packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js', + name: 'Form', }, - } - `); + }), + ); } diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js index 5abee0fe5021c..bdef1f9196135 100644 --- a/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js @@ -1,4 +1,4 @@ -module.exports = function Form() { +module.exports.Form = function Form() { console.log('Form Rendered!') } \ No newline at end of file diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js b/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js index 1ccbfa1ce8eba..0ca87b5e40542 100644 --- a/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js @@ -1,5 +1,5 @@ -const ClientComponent = require('./Form.client'); +const ClientComponent = require('./Form.client').Form; const ServerComponent = require('./FormServer.server.js'); console.log( From dbe62f80333e22d779a240603fbb367b05ff0e3d Mon Sep 17 00:00:00 2001 From: Sam Cooke Date: Mon, 28 Dec 2020 17:08:08 +1000 Subject: [PATCH 4/6] Add webpack v5 specific API's --- .../src/ReactFlightWebpackPlugin.js | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js index ffd3dbe47dc59..47abfb7189361 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js +++ b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js @@ -119,6 +119,10 @@ export default class ReactFlightWebpackPlugin { ); }; + const manifestFilename = this.manifestFilename; + // To target both webpack v4 & webpack v5, we have to listen to certain hooks. + let hooksInstalled = false; + compiler.hooks.run.tapAsync(PLUGIN_NAME, run); compiler.hooks.watchRun.tapAsync(PLUGIN_NAME, run); compiler.hooks.compilation.tap( @@ -163,9 +167,86 @@ export default class ReactFlightWebpackPlugin { } } }); + + if (!compilation.hooks.processAssets) { + return; + } + hooksInstalled = true; + + compilation.hooks.processAssets.tap( + { + name: PLUGIN_NAME, + // We derive the manifest from the existing assets. + stage: require('webpack').Compilation.PROCESS_ASSETS_STAGE_DERIVED, + }, + () => { + const json = {}; + /** @type {ChunkGraph} */ + const chunkGraph = compilation.chunkGraph; + /** @type {ModuleGraph} */ + const moduleGraph = compilation.moduleGraph; + + compilation.chunkGroups.forEach(function(chunkGroup) { + const chunkIds = chunkGroup.chunks.map(function(c) { + return c.id; + }); + + function recordModule(id, mod) { + // TODO: Hook into deps instead of the target module. + // That way we know by the type of dep whether to include. + // It also resolves conflicts when the same module is in multiple chunks. + if (!/\.client\.tsx$/.test(mod.resource)) { + // TODO: The above is using JS, instead of TSX + return; + } + + const moduleExports = {}; + // const providedExports = mod.buildMeta ? mod.buildMeta.providedExports : []; + const providedExports = moduleGraph.getProvidedExports(mod); + ['', '*'].concat(providedExports).forEach(function(name) { + moduleExports[name] = { + id: id, + chunks: chunkIds, + name: name, + }; + }); + const href = URL.pathToFileURL(mod.resource).href; + + if (href !== undefined) { + json[href] = moduleExports; + } + } + + chunkGroup.chunks.forEach(function(chunk) { + chunk.getModules().forEach(function(mod) { + const id = chunkGraph.getModuleId(mod); + recordModule(id, mod); + // If this is a concatenation, register each child to the parent ID. + if (mod.modules) { + mod.modules.forEach(function(concatenatedMod) { + recordModule(id, concatenatedMod); + }); + } + }); + }); + }); + const output = JSON.stringify(json, null, 2); + compilation.assets[manifestFilename] = { + source: function() { + return output; + }, + size: function() { + return output.length; + }, + }; + }, + ); }, ); + if (hooksInstalled) { + return; + } compiler.hooks.emit.tap(PLUGIN_NAME, compilation => { const json = {}; compilation.chunkGroups.forEach(chunkGroup => { @@ -205,7 +286,7 @@ export default class ReactFlightWebpackPlugin { }); }); const output = JSON.stringify(json, null, 2); - compilation.assets[this.manifestFilename] = { + compilation.assets[manifestFilename] = { source() { return output; }, From 313538611ac1ee5e1e72f0e122870885dbd029da Mon Sep 17 00:00:00 2001 From: Sam Cooke Date: Thu, 31 Dec 2020 09:00:36 +1000 Subject: [PATCH 5/6] Refactor to reduce code duplication --- .../src/ReactFlightWebpackPlugin.js | 159 +++++++++--------- .../ReactFlightWebpackPlugin-test.js | 48 ++++-- .../src/__tests__/fixture/Form.client.js | 2 +- .../__tests__/fixture/FormServer.server.js | 5 +- 4 files changed, 115 insertions(+), 99 deletions(-) diff --git a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js index 47abfb7189361..9323530c20beb 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js +++ b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js @@ -16,6 +16,7 @@ import ModuleDependency from 'webpack/lib/dependencies/ModuleDependency'; import NullDependency from 'webpack/lib/dependencies/NullDependency'; import AsyncDependenciesBlock from 'webpack/lib/AsyncDependenciesBlock'; import Template from 'webpack/lib/Template'; +import { RawSource } from 'webpack-sources' class ClientReferenceDependency extends ModuleDependency { constructor(request) { @@ -94,6 +95,48 @@ export default class ReactFlightWebpackPlugin { options.manifestFilename || 'react-client-manifest.json'; } + get webpackVersion(): 'wp5' | 'wp4' { + return require('webpack').version.match(/4\.[0-9]*\.[0-9]*/) + ? 'wp4' + : 'wp5'; + } + + pluginOutput = {}; + + recordModule = (id: string, { + getExports, + resource, + chunkIds, + }: { getExports: () => string[], resource: string, chunkIds: string[] }) => { + // TODO: Hook into deps instead of the target module. + // That way we know by the type of dep whether to include. + // It also resolves conflicts when the same module is in multiple chunks. + if (!/\.client\.(tsx|jsx|js|ts)$/.test(resource)) { + return; + } + + const moduleExports = {}; + const providedExports = getExports(); + ['', '*'].concat(providedExports).forEach(function(name) { + moduleExports[name] = { + id: id, + chunks: chunkIds, + name: name, + }; + }); + const href = pathToFileURL(resource).href; + + if (href !== undefined) { + this.pluginOutput[href] = moduleExports; + } + } + + // + output(compilation) { + const output = JSON.stringify(this.pluginOutput, null, 2); + compilation.emitAsset(this.manifestFilename, new RawSource(output)); + } + apply(compiler: any) { let resolvedClientReferences; const run = (params, callback) => { @@ -168,10 +211,10 @@ export default class ReactFlightWebpackPlugin { } }); - if (!compilation.hooks.processAssets) { + // ProcessAssests hook is only supported by webpack v5. + if(this.webpackVersion !== 'wp5') { return; } - hooksInstalled = true; compilation.hooks.processAssets.tap( { @@ -180,120 +223,74 @@ export default class ReactFlightWebpackPlugin { stage: require('webpack').Compilation.PROCESS_ASSETS_STAGE_DERIVED, }, () => { - const json = {}; - /** @type {ChunkGraph} */ const chunkGraph = compilation.chunkGraph; - /** @type {ModuleGraph} */ const moduleGraph = compilation.moduleGraph; - compilation.chunkGroups.forEach(function(chunkGroup) { + compilation.chunkGroups.forEach((chunkGroup) => { const chunkIds = chunkGroup.chunks.map(function(c) { return c.id; }); - - function recordModule(id, mod) { - // TODO: Hook into deps instead of the target module. - // That way we know by the type of dep whether to include. - // It also resolves conflicts when the same module is in multiple chunks. - if (!/\.client\.tsx$/.test(mod.resource)) { - // TODO: The above is using JS, instead of TSX - return; - } - - const moduleExports = {}; - // const providedExports = mod.buildMeta ? mod.buildMeta.providedExports : []; - const providedExports = moduleGraph.getProvidedExports(mod); - ['', '*'].concat(providedExports).forEach(function(name) { - moduleExports[name] = { - id: id, - chunks: chunkIds, - name: name, - }; - }); - const href = URL.pathToFileURL(mod.resource).href; - - if (href !== undefined) { - json[href] = moduleExports; - } - } - - chunkGroup.chunks.forEach(function(chunk) { - chunk.getModules().forEach(function(mod) { + chunkGroup.chunks.forEach((chunk) => { + chunk.getModules().forEach((mod) => { const id = chunkGraph.getModuleId(mod); - recordModule(id, mod); + this.recordModule(id, { + getExports: () => moduleGraph.getProvidedExports(mod), + chunkIds, + resource: mod.resource, + }); // If this is a concatenation, register each child to the parent ID. if (mod.modules) { - mod.modules.forEach(function(concatenatedMod) { - recordModule(id, concatenatedMod); + mod.modules.forEach((concatenatedMod) => { + this.recordModule(id, { + getExports: () => moduleGraph.getProvidedExports(concatenatedMod), + resource: concatenatedMod.resource, + chunkIds, + }); }); } }); }); }); - const output = JSON.stringify(json, null, 2); - compilation.assets[manifestFilename] = { - source: function() { - return output; - }, - size: function() { - return output.length; - }, - }; + + this.output(compilation) }, ); }, ); - if (hooksInstalled) { + if (this.webpackVersion === 'wp5') { return; } compiler.hooks.emit.tap(PLUGIN_NAME, compilation => { - const json = {}; compilation.chunkGroups.forEach(chunkGroup => { const chunkIds = chunkGroup.chunks.map(c => c.id); - function recordModule(id, mod) { - // TODO: Hook into deps instead of the target module. - // That way we know by the type of dep whether to include. - // It also resolves conflicts when the same module is in multiple chunks. - if (!/\.client\.(js|jsx|ts|tsx)$/.test(mod.resource)) { - return; - } - const moduleExports = {}; - ['', '*'].concat(mod.buildMeta.providedExports).forEach(name => { - moduleExports[name] = { - id: id, - chunks: chunkIds, - name: name, - }; - }); - const href = pathToFileURL(mod.resource).href; - if (href !== undefined) { - json[href] = moduleExports; - } - } - chunkGroup.chunks.forEach(chunk => { chunk.getModules().forEach(mod => { - recordModule(mod.id, mod); + this.recordModule(mod.id, { + chunkIds, + // TODO: This can return `true` in some cases, which is likely not expected + // It seems to return true in the case of cjs exports `module.exports.foo` + getExports: () => mod.buildMeta.providedExports, + resource: mod.resource, + }); // If this is a concatenation, register each child to the parent ID. if (mod.modules) { mod.modules.forEach(concatenatedMod => { - recordModule(mod.id, concatenatedMod); + this.recordModule(mod.id, { + chunkIds, + // TODO: This can return `true` in some cases, which is likely not expected + getExports: () => concatenatedMod.buildMeta.providedExports, + resource: concatenatedMod.resource, + }); }); } }); }); + + this.output(compilation); }); - const output = JSON.stringify(json, null, 2); - compilation.assets[manifestFilename] = { - source() { - return output; - }, - size() { - return output.length; - }, - }; + }); } diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js index 219068930b3e3..cccd96d145b3d 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js @@ -53,13 +53,11 @@ describe('ReactFlightWebpackPlugin', () => { output.run((err, stats) => { expect(err).toBeNull(); - const fileName = plugin.manifestFilename; //'react-client-manifest.json' - + // in webpack 4, we can read the assets of the compilation object. This doesn't work in webpack 5 + // as webpack 5 removes the source from the assets object, to prevent memory leaks. + const fileName = plugin.manifestFilename; const pluginOutput = stats.compilation.assets[fileName]; - console.log(pluginOutput); - const producedManifest = pluginOutput.source(); - assert(producedManifest); done(); @@ -82,25 +80,45 @@ describe('ReactFlightWebpackPlugin', () => { cache: undefined, output: { // Output - path: path.resolve(path.join(os.tmpdir(), 'output')), + path: path.resolve(path.join(os.tmpdir(), 'output+2')), + // Make webpack always want to emit files, regardless if they exist or not + // This aids in development of the tests, as webpack 5 will not emit fi the file is already existing. + compareBeforeEmit: false, }, mode: 'development', }); + + const originalFileSystem = output.outputFileSystem; output.outputFileSystem = { ...originalFileSystem, - writeFile: (dest, contents, err) => { - if (dest.includes(fileName)) { - assert(contents.toString()); - done(); - } - }, + writeFile: jest.fn((dest, contents, cb) => { + // Call the callback, but don't actually write anything. + cb(null); + }) }; - output.run((err, stats, foo) => { + output.run((err, stats) => { expect(err).toBeNull(); + + expect(output.outputFileSystem.writeFile).toHaveBeenCalledWith( + expect.stringContaining(fileName), + expect.anything(), + expect.anything() + ); + const calls = output.outputFileSystem.writeFile.mock.calls; + // Get the idx that was called with the fileName, + const idx = calls.findIndex(val => { + return val[0].includes(fileName); + }) + + const contents = output.outputFileSystem.writeFile.mock.calls[idx][1].toString(); + + // Check that the contents match with what we expect + assert(contents) + done(); }); }); }); @@ -110,7 +128,7 @@ function assert(manifestContents) { 'file://' + path.resolve(path.join(__dirname, 'fixture', 'Form.client.js')); const manifestObj = JSON.parse(manifestContents); - expect(manifestObj[key]).toBe( + expect(manifestObj[key]).toStrictEqual( expect.objectContaining({ '': { chunks: ['client'], @@ -122,7 +140,7 @@ function assert(manifestContents) { chunks: ['client'], id: './packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js', - name: '', + name: '*', }, Form: { chunks: ['client'], diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js index bdef1f9196135..ae1c9bf643da5 100644 --- a/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js @@ -1,4 +1,4 @@ -module.exports.Form = function Form() { +export function Form() { console.log('Form Rendered!') } \ No newline at end of file diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js b/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js index 82e19d59f024f..6b02213632774 100644 --- a/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js @@ -1,4 +1,5 @@ -module.exports = function Form() { - console.log('Form Rendered! On the server') + +export default function Foo() { + console.log('Form!') } \ No newline at end of file From 61d3dc8fdbda38aa4069b8de8d543c9dde632b92 Mon Sep 17 00:00:00 2001 From: Sam Cooke Date: Thu, 31 Dec 2020 09:05:27 +1000 Subject: [PATCH 6/6] Prettier & Linting --- .../src/ReactFlightWebpackPlugin.js | 39 +++++++++---------- .../ReactFlightWebpackPlugin-test.js | 14 +++---- .../src/__tests__/fixture/Form.client.js | 5 +-- .../__tests__/fixture/FormServer.server.js | 6 +-- .../src/__tests__/fixture/entry.js | 6 +-- 5 files changed, 31 insertions(+), 39 deletions(-) diff --git a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js index 9323530c20beb..933967f107943 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js +++ b/packages/react-server-dom-webpack/src/ReactFlightWebpackPlugin.js @@ -16,7 +16,7 @@ import ModuleDependency from 'webpack/lib/dependencies/ModuleDependency'; import NullDependency from 'webpack/lib/dependencies/NullDependency'; import AsyncDependenciesBlock from 'webpack/lib/AsyncDependenciesBlock'; import Template from 'webpack/lib/Template'; -import { RawSource } from 'webpack-sources' +import {RawSource} from 'webpack-sources'; class ClientReferenceDependency extends ModuleDependency { constructor(request) { @@ -103,11 +103,14 @@ export default class ReactFlightWebpackPlugin { pluginOutput = {}; - recordModule = (id: string, { - getExports, - resource, - chunkIds, - }: { getExports: () => string[], resource: string, chunkIds: string[] }) => { + recordModule = ( + id: string, + { + getExports, + resource, + chunkIds, + }: {getExports: () => string[], resource: string, chunkIds: string[]}, + ) => { // TODO: Hook into deps instead of the target module. // That way we know by the type of dep whether to include. // It also resolves conflicts when the same module is in multiple chunks. @@ -129,10 +132,10 @@ export default class ReactFlightWebpackPlugin { if (href !== undefined) { this.pluginOutput[href] = moduleExports; } - } + }; // - output(compilation) { + output(compilation) { const output = JSON.stringify(this.pluginOutput, null, 2); compilation.emitAsset(this.manifestFilename, new RawSource(output)); } @@ -162,10 +165,6 @@ export default class ReactFlightWebpackPlugin { ); }; - const manifestFilename = this.manifestFilename; - // To target both webpack v4 & webpack v5, we have to listen to certain hooks. - let hooksInstalled = false; - compiler.hooks.run.tapAsync(PLUGIN_NAME, run); compiler.hooks.watchRun.tapAsync(PLUGIN_NAME, run); compiler.hooks.compilation.tap( @@ -212,7 +211,7 @@ export default class ReactFlightWebpackPlugin { }); // ProcessAssests hook is only supported by webpack v5. - if(this.webpackVersion !== 'wp5') { + if (this.webpackVersion !== 'wp5') { return; } @@ -226,12 +225,12 @@ export default class ReactFlightWebpackPlugin { const chunkGraph = compilation.chunkGraph; const moduleGraph = compilation.moduleGraph; - compilation.chunkGroups.forEach((chunkGroup) => { + compilation.chunkGroups.forEach(chunkGroup => { const chunkIds = chunkGroup.chunks.map(function(c) { return c.id; }); - chunkGroup.chunks.forEach((chunk) => { - chunk.getModules().forEach((mod) => { + chunkGroup.chunks.forEach(chunk => { + chunk.getModules().forEach(mod => { const id = chunkGraph.getModuleId(mod); this.recordModule(id, { getExports: () => moduleGraph.getProvidedExports(mod), @@ -240,9 +239,10 @@ export default class ReactFlightWebpackPlugin { }); // If this is a concatenation, register each child to the parent ID. if (mod.modules) { - mod.modules.forEach((concatenatedMod) => { + mod.modules.forEach(concatenatedMod => { this.recordModule(id, { - getExports: () => moduleGraph.getProvidedExports(concatenatedMod), + getExports: () => + moduleGraph.getProvidedExports(concatenatedMod), resource: concatenatedMod.resource, chunkIds, }); @@ -252,7 +252,7 @@ export default class ReactFlightWebpackPlugin { }); }); - this.output(compilation) + this.output(compilation); }, ); }, @@ -290,7 +290,6 @@ export default class ReactFlightWebpackPlugin { this.output(compilation); }); - }); } diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js index cccd96d145b3d..d3652e04f4690 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightWebpackPlugin-test.js @@ -88,8 +88,6 @@ describe('ReactFlightWebpackPlugin', () => { mode: 'development', }); - - const originalFileSystem = output.outputFileSystem; output.outputFileSystem = { @@ -97,7 +95,7 @@ describe('ReactFlightWebpackPlugin', () => { writeFile: jest.fn((dest, contents, cb) => { // Call the callback, but don't actually write anything. cb(null); - }) + }), }; output.run((err, stats) => { @@ -106,18 +104,20 @@ describe('ReactFlightWebpackPlugin', () => { expect(output.outputFileSystem.writeFile).toHaveBeenCalledWith( expect.stringContaining(fileName), expect.anything(), - expect.anything() + expect.anything(), ); const calls = output.outputFileSystem.writeFile.mock.calls; // Get the idx that was called with the fileName, const idx = calls.findIndex(val => { return val[0].includes(fileName); - }) + }); - const contents = output.outputFileSystem.writeFile.mock.calls[idx][1].toString(); + const contents = output.outputFileSystem.writeFile.mock.calls[ + idx + ][1].toString(); // Check that the contents match with what we expect - assert(contents) + assert(contents); done(); }); }); diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js index ae1c9bf643da5..ba70f7aae3991 100644 --- a/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/Form.client.js @@ -1,4 +1,3 @@ - export function Form() { - console.log('Form Rendered!') -} \ No newline at end of file + console.log('Form Rendered!'); +} diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js b/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js index 6b02213632774..e87eac9e11163 100644 --- a/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/FormServer.server.js @@ -1,5 +1,3 @@ - - export default function Foo() { - console.log('Form!') -} \ No newline at end of file + console.log('Form!'); +} diff --git a/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js b/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js index 0ca87b5e40542..1a101c50ff7b8 100644 --- a/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js +++ b/packages/react-server-dom-webpack/src/__tests__/fixture/entry.js @@ -1,8 +1,4 @@ - const ClientComponent = require('./Form.client').Form; const ServerComponent = require('./FormServer.server.js'); -console.log( - ClientComponent, - ServerComponent -); +console.log(ClientComponent, ServerComponent);