From e41fd1fc0605dde41cff53e01039633c8e852b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Thu, 12 Nov 2020 11:11:05 -0500 Subject: [PATCH] Support ESM module loaders in Flight fixture (#20229) This lets the Flight fixture run as "type": "module" or "commonjs". Experimental loaders can be used similar to require.extensions to do the transpilation and replacement of .client.js references. --- fixtures/flight/config/package.json | 3 ++ fixtures/flight/package.json | 4 ++- fixtures/flight/scripts/package.json | 3 ++ fixtures/flight/server/handler.server.mjs | 27 +++++++++++++++ fixtures/flight/server/index.js | 3 +- fixtures/flight/server/loader.mjs | 42 +++++++++++++++++++++++ fixtures/flight/server/package.json | 3 ++ fixtures/flight/src/App.server.js | 6 ++-- fixtures/flight/src/Counter.client.js | 2 +- fixtures/flight/src/ShowMore.client.js | 2 +- fixtures/flight/yarn.lock | 12 +++++++ package.json | 1 + yarn.lock | 7 ++++ 13 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 fixtures/flight/config/package.json create mode 100644 fixtures/flight/scripts/package.json create mode 100644 fixtures/flight/server/handler.server.mjs create mode 100644 fixtures/flight/server/loader.mjs create mode 100644 fixtures/flight/server/package.json diff --git a/fixtures/flight/config/package.json b/fixtures/flight/config/package.json new file mode 100644 index 000000000000..5bbefffbabee --- /dev/null +++ b/fixtures/flight/config/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/fixtures/flight/package.json b/fixtures/flight/package.json index 65d2556d635a..92c41ebfe47a 100644 --- a/fixtures/flight/package.json +++ b/fixtures/flight/package.json @@ -1,9 +1,11 @@ { "name": "flight", + "type": "module", "version": "0.1.0", "private": true, "dependencies": { "@babel/core": "7.6.0", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/register": "^7.7.0", "@svgr/webpack": "4.3.2", "@typescript-eslint/eslint-plugin": "^2.2.0", @@ -65,7 +67,7 @@ "prebuild": "cp -r ../../build/node_modules/* ./node_modules/", "start": "concurrently \"npm run start:server\" \"npm run start:client\"", "start:client": "node scripts/start.js", - "start:server": "NODE_ENV=development node server", + "start:server": "NODE_ENV=development node --experimental-loader ./server/loader.mjs server", "start:prod": "node scripts/build.js && NODE_ENV=production node server", "build": "node scripts/build.js", "test": "node scripts/test.js --env=jsdom" diff --git a/fixtures/flight/scripts/package.json b/fixtures/flight/scripts/package.json new file mode 100644 index 000000000000..5bbefffbabee --- /dev/null +++ b/fixtures/flight/scripts/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/fixtures/flight/server/handler.server.mjs b/fixtures/flight/server/handler.server.mjs new file mode 100644 index 000000000000..0d21c80eebfd --- /dev/null +++ b/fixtures/flight/server/handler.server.mjs @@ -0,0 +1,27 @@ +import {pipeToNodeWritable} from 'react-transport-dom-webpack/server.js'; +import * as React from 'react'; +import App from '../src/App.server.js'; + +import {URL} from 'url'; + +const rootPath = import.meta.url; +function resolve(relative) { + return new URL(relative, rootPath).href; +} + +export default function(req, res) { + res.setHeader('Access-Control-Allow-Origin', '*'); + pipeToNodeWritable(, res, { + // TODO: Read from a map on the disk. + [resolve('../src/Counter.client.js')]: { + id: './src/Counter.client.js', + chunks: ['1'], + name: 'default', + }, + [resolve('../src/ShowMore.client.js')]: { + id: './src/ShowMore.client.js', + chunks: ['2'], + name: 'default', + }, + }); +}; diff --git a/fixtures/flight/server/index.js b/fixtures/flight/server/index.js index 06c245b4120a..ffa1a8628b8e 100644 --- a/fixtures/flight/server/index.js +++ b/fixtures/flight/server/index.js @@ -25,7 +25,8 @@ app.get('/', function(req, res) { delete require.cache[key]; } } - require('./handler.server')(req, res); + import('./handler.server.mjs').then(m => m.default(req, res)); + // require('./handler.server.js')(req, res); }); app.listen(3001, () => { diff --git a/fixtures/flight/server/loader.mjs b/fixtures/flight/server/loader.mjs new file mode 100644 index 000000000000..f2d109ce8179 --- /dev/null +++ b/fixtures/flight/server/loader.mjs @@ -0,0 +1,42 @@ +import babel from '@babel/core'; + +const options = { + babelrc: false, + ignore: [/\/(build|node_modules)\//], + plugins: [ + '@babel/plugin-syntax-import-meta', + '@babel/plugin-transform-react-jsx', + ], +}; + +const optionsCommonJS = { + ignore: [/\/(build|node_modules)\//], + presets: ['react-app'], + plugins: ['@babel/transform-modules-commonjs'], +}; + +export async function transformSource(source, context, defaultTransformSource) { + const {format} = context; + if (format === 'module' || format === 'commonjs') { + const opt = Object.assign( + {filename: context.url}, + format === 'commonjs' ? optionsCommonJS : options + ); + const {code} = await babel.transformAsync(source, opt); + return {source: code}; + } + return defaultTransformSource(source, context); +} + +export async function getSource(url, context, defaultGetSource) { + if (url.endsWith('.client.js')) { + const name = url; + return { + source: + "export default { $$typeof: Symbol.for('react.module.reference'), name: " + + JSON.stringify(name) + + '}', + }; + } + return defaultGetSource(url, context, defaultGetSource); +} diff --git a/fixtures/flight/server/package.json b/fixtures/flight/server/package.json new file mode 100644 index 000000000000..5bbefffbabee --- /dev/null +++ b/fixtures/flight/server/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/fixtures/flight/src/App.server.js b/fixtures/flight/src/App.server.js index bf3b20fa32a7..54a644dc48d4 100644 --- a/fixtures/flight/src/App.server.js +++ b/fixtures/flight/src/App.server.js @@ -1,10 +1,10 @@ import * as React from 'react'; -import Container from './Container'; +import Container from './Container.js'; -import Counter from './Counter.client'; +import Counter from './Counter.client.js'; -import ShowMore from './ShowMore.client'; +import ShowMore from './ShowMore.client.js'; export default function App() { return ( diff --git a/fixtures/flight/src/Counter.client.js b/fixtures/flight/src/Counter.client.js index 892af50df69a..00a1f2cbe440 100644 --- a/fixtures/flight/src/Counter.client.js +++ b/fixtures/flight/src/Counter.client.js @@ -1,6 +1,6 @@ import * as React from 'react'; -import Container from './Container'; +import Container from './Container.js'; export default function Counter() { const [count, setCount] = React.useState(0); diff --git a/fixtures/flight/src/ShowMore.client.js b/fixtures/flight/src/ShowMore.client.js index d8ff151725e8..86d01baa7984 100644 --- a/fixtures/flight/src/ShowMore.client.js +++ b/fixtures/flight/src/ShowMore.client.js @@ -1,6 +1,6 @@ import * as React from 'react'; -import Container from './Container'; +import Container from './Container.js'; export default function ShowMore({children}) { const [show, setShow] = React.useState(false); diff --git a/fixtures/flight/yarn.lock b/fixtures/flight/yarn.lock index faf12e3ff847..ad74759fddff 100644 --- a/fixtures/flight/yarn.lock +++ b/fixtures/flight/yarn.lock @@ -252,6 +252,11 @@ version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" +"@babel/helper-plugin-utils@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + "@babel/helper-regex@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" @@ -445,6 +450,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" diff --git a/package.json b/package.json index a9feab2a2c98..788479a9df8f 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/plugin-proposal-object-rest-spread": "^7.11.0", "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-jsx": "^7.10.4", "@babel/plugin-transform-arrow-functions": "^7.10.4", "@babel/plugin-transform-async-to-generator": "^7.10.4", diff --git a/yarn.lock b/yarn.lock index fb413bf61246..d44e85f4e47d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -739,6 +739,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"