@samitouri / QOS-React-2 / commits / e41fd1fc06

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"