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.
Sebastian Markbåge committed
Nov 12, 2020 at 11:11 UTC
e41fd1fc0605dde41cff53e01039633c8e852b6d
13 files changed
+108
-7
fixtures/flight/config/package.json
new
+3
@@ -0,0 +1,3 @@
1
+{
2
+ "type": "commonjs"
3
+}
fixtures/flight/package.json
+3
-1
@@ -1,9 +1,11 @@
1
{
2
"name": "flight",
3
+ "type": "module",
4
"version": "0.1.0",
5
"private": true,
6
"dependencies": {
7
"@babel/core": "7.6.0",
8
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
9
"@babel/register": "^7.7.0",
10
"@svgr/webpack": "4.3.2",
11
"@typescript-eslint/eslint-plugin": "^2.2.0",
@@ -65,7 +67,7 @@
67
"prebuild": "cp -r ../../build/node_modules/* ./node_modules/",
68
"start": "concurrently \"npm run start:server\" \"npm run start:client\"",
69
"start:client": "node scripts/start.js",
68
- "start:server": "NODE_ENV=development node server",
70
+ "start:server": "NODE_ENV=development node --experimental-loader ./server/loader.mjs server",
71
"start:prod": "node scripts/build.js && NODE_ENV=production node server",
72
"build": "node scripts/build.js",
73
"test": "node scripts/test.js --env=jsdom"
fixtures/flight/scripts/package.json
new
+3
@@ -0,0 +1,3 @@
1
+{
2
+ "type": "commonjs"
3
+}
fixtures/flight/server/handler.server.mjs
new
+27
@@ -0,0 +1,27 @@
1
+import {pipeToNodeWritable} from 'react-transport-dom-webpack/server.js';
2
+import * as React from 'react';
3
+import App from '../src/App.server.js';
4
+
5
+import {URL} from 'url';
6
+
7
+const rootPath = import.meta.url;
8
+function resolve(relative) {
9
+ return new URL(relative, rootPath).href;
10
+}
11
+
12
+export default function(req, res) {
13
+ res.setHeader('Access-Control-Allow-Origin', '*');
14
+ pipeToNodeWritable(<App />, res, {
15
+ // TODO: Read from a map on the disk.
16
+ [resolve('../src/Counter.client.js')]: {
17
+ id: './src/Counter.client.js',
18
+ chunks: ['1'],
19
+ name: 'default',
20
+ },
21
+ [resolve('../src/ShowMore.client.js')]: {
22
+ id: './src/ShowMore.client.js',
23
+ chunks: ['2'],
24
+ name: 'default',
25
+ },
26
+ });
27
+};
fixtures/flight/server/index.js
+2
-1
@@ -25,7 +25,8 @@ app.get('/', function(req, res) {
25
delete require.cache[key];
26
}
27
}
28
- require('./handler.server')(req, res);
28
+ import('./handler.server.mjs').then(m => m.default(req, res));
29
+ // require('./handler.server.js')(req, res);
30
});
31
32
app.listen(3001, () => {
fixtures/flight/server/loader.mjs
new
+42
@@ -0,0 +1,42 @@
1
+import babel from '@babel/core';
2
+
3
+const options = {
4
+ babelrc: false,
5
+ ignore: [/\/(build|node_modules)\//],
6
+ plugins: [
7
+ '@babel/plugin-syntax-import-meta',
8
+ '@babel/plugin-transform-react-jsx',
9
+ ],
10
+};
11
+
12
+const optionsCommonJS = {
13
+ ignore: [/\/(build|node_modules)\//],
14
+ presets: ['react-app'],
15
+ plugins: ['@babel/transform-modules-commonjs'],
16
+};
17
+
18
+export async function transformSource(source, context, defaultTransformSource) {
19
+ const {format} = context;
20
+ if (format === 'module' || format === 'commonjs') {
21
+ const opt = Object.assign(
22
+ {filename: context.url},
23
+ format === 'commonjs' ? optionsCommonJS : options
24
+ );
25
+ const {code} = await babel.transformAsync(source, opt);
26
+ return {source: code};
27
+ }
28
+ return defaultTransformSource(source, context);
29
+}
30
+
31
+export async function getSource(url, context, defaultGetSource) {
32
+ if (url.endsWith('.client.js')) {
33
+ const name = url;
34
+ return {
35
+ source:
36
+ "export default { $$typeof: Symbol.for('react.module.reference'), name: " +
37
+ JSON.stringify(name) +
38
+ '}',
39
+ };
40
+ }
41
+ return defaultGetSource(url, context, defaultGetSource);
42
+}
fixtures/flight/server/package.json
new
+3
@@ -0,0 +1,3 @@
1
+{
2
+ "type": "commonjs"
3
+}
fixtures/flight/src/App.server.js
+3
-3
@@ -1,10 +1,10 @@
1
import * as React from 'react';
2
3
-import Container from './Container';
3
+import Container from './Container.js';
4
5
-import Counter from './Counter.client';
5
+import Counter from './Counter.client.js';
6
7
-import ShowMore from './ShowMore.client';
7
+import ShowMore from './ShowMore.client.js';
8
9
export default function App() {
10
return (
fixtures/flight/src/Counter.client.js
+1
-1
@@ -1,6 +1,6 @@
1
import * as React from 'react';
2
3
-import Container from './Container';
3
+import Container from './Container.js';
4
5
export default function Counter() {
6
const [count, setCount] = React.useState(0);
fixtures/flight/src/ShowMore.client.js
+1
-1
@@ -1,6 +1,6 @@
1
import * as React from 'react';
2
3
-import Container from './Container';
3
+import Container from './Container.js';
4
5
export default function ShowMore({children}) {
6
const [show, setShow] = React.useState(false);
fixtures/flight/yarn.lock
+12
@@ -252,6 +252,11 @@
252
version "7.0.0"
253
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250"
254
255
+"@babel/helper-plugin-utils@^7.10.4":
256
+ version "7.10.4"
257
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375"
258
+ integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==
259
+
260
"@babel/helper-regex@^7.0.0":
261
version "7.0.0"
262
resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27"
@@ -445,6 +450,13 @@
450
dependencies:
451
"@babel/helper-plugin-utils" "^7.0.0"
452
453
+"@babel/plugin-syntax-import-meta@^7.10.4":
454
+ version "7.10.4"
455
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
456
+ integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
457
+ dependencies:
458
+ "@babel/helper-plugin-utils" "^7.10.4"
459
+
460
"@babel/plugin-syntax-json-strings@^7.2.0":
461
version "7.2.0"
462
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470"
package.json
+1
@@ -14,6 +14,7 @@
14
"@babel/plugin-proposal-class-properties": "^7.10.4",
15
"@babel/plugin-proposal-object-rest-spread": "^7.11.0",
16
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
17
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
18
"@babel/plugin-syntax-jsx": "^7.10.4",
19
"@babel/plugin-transform-arrow-functions": "^7.10.4",
20
"@babel/plugin-transform-async-to-generator": "^7.10.4",
yarn.lock
+7
@@ -739,6 +739,13 @@
739
dependencies:
740
"@babel/helper-plugin-utils" "^7.10.4"
741
742
+"@babel/plugin-syntax-import-meta@^7.10.4":
743
+ version "7.10.4"
744
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
745
+ integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
746
+ dependencies:
747
+ "@babel/helper-plugin-utils" "^7.10.4"
748
+
749
"@babel/plugin-syntax-json-strings@^7.8.0":
750
version "7.8.3"
751
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"