Skip to content

Commit

Permalink
Add Node ESM loader build
Browse files Browse the repository at this point in the history
This adds a loader build as a first-class export. This will grow in
complexity so it deserves its own module.
  • Loading branch information
sebmarkbage committed Nov 17, 2020
1 parent bf7b7ae commit 50e1b77
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 28 deletions.
6 changes: 4 additions & 2 deletions fixtures/flight/server/handler.server.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {pipeToNodeWritable} from 'react-transport-dom-webpack/server.js';
import {pipeToNodeWritable} from 'react-transport-dom-webpack/server';
import * as React from 'react';
import App from '../src/App.server.js';

Expand All @@ -10,8 +10,10 @@ function resolve(relative) {
}

export default function(req, res) {
// In case this was a transpiled CommonJS import.
const AppOrDefault = App.default || App;
res.setHeader('Access-Control-Allow-Origin', '*');
pipeToNodeWritable(<App />, res, {
pipeToNodeWritable(<AppOrDefault />, res, {
// TODO: Read from a map on the disk.
[resolve('../src/Counter.client.js')]: {
id: './src/Counter.client.js',
Expand Down
6 changes: 4 additions & 2 deletions fixtures/flight/server/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
'use strict';

const url = require('url');

require.extensions['.client.js'] = function(module, path) {
module.exports = {
$$typeof: Symbol.for('react.module.reference'),
name: path,
name: url.pathToFileURL(path).href,
};
};

Expand All @@ -26,7 +28,7 @@ app.get('/', function(req, res) {
}
}
import('./handler.server.mjs').then(m => m.default(req, res));
// require('./handler.server.js')(req, res);
// require('./handler.server.js')(req, res);
});

app.listen(3001, () => {
Expand Down
34 changes: 11 additions & 23 deletions fixtures/flight/server/loader.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import {
resolve,
getSource,
} from 'react-transport-dom-webpack/node-loader';

export {resolve, getSource};

import babel from '@babel/core';

const options = {
const babelOptions = {
babelrc: false,
ignore: [/\/(build|node_modules)\//],
plugins: [
Expand All @@ -9,34 +16,15 @@ const options = {
],
};

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') {
if (format === 'module') {
const opt = Object.assign(
{filename: context.url},
format === 'commonjs' ? optionsCommonJS : options
babelOptions
);
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);
return defaultTransformSource(source, context, defaultTransformSource);
}
3 changes: 3 additions & 0 deletions packages/react-transport-dom-webpack/esm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export * from '../src/ReactFlightWebpackNodeLoader.js';
3 changes: 3 additions & 0 deletions packages/react-transport-dom-webpack/npm/esm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
12 changes: 11 additions & 1 deletion packages/react-transport-dom-webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,18 @@
"server.browser.js",
"server.node.js",
"cjs/",
"umd/"
"umd/",
"esm/"
],
"exports": {
".": "./index.js",
"./plugin": "./plugin.js",
"./server": "./server.js",
"./server.browser": "./server.browser.js",
"./server.node": "./server.node.js",
"./node-loader": "./esm/react-transport-dom-webpack-node-loader.js",
"./package.json": "./package.json"
},
"browser": {
"./server.js": "./server.browser.js"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

type ResolveContext = {
conditions: Array<string>,
parentURL: string | void,
};

type ResolveFunction = (
string,
ResolveContext,
ResolveFunction,
) => Promise<string>;

type GetSourceContext = {
format: string,
url: string,
};

type GetSourceFunction = (
string,
GetSourceContext,
GetSourceFunction,
) => Promise<{source: Source}>;

type Source = string | ArrayBuffer | Uint8Array;

export async function resolve(
specifier: string,
context: ResolveContext,
defaultResolve: ResolveFunction,
): Promise<string> {
// TODO: Resolve server-only files.
return defaultResolve(specifier, context, defaultResolve);
}

export async function getSource(
url: string,
context: GetSourceContext,
defaultGetSource: GetSourceFunction,
): Promise<{source: Source}> {
if (url.endsWith('.client.js')) {
// TODO: Named exports.
const src =
"export default { $$typeof: Symbol.for('react.module.reference'), name: " +
JSON.stringify(url) +
'}';
return {source: src};
}
return defaultGetSource(url, context, defaultGetSource);
}
9 changes: 9 additions & 0 deletions scripts/rollup/bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ const bundles = [
externals: [],
},

/******* React Transport DOM Webpack Node.js Loader *******/
{
bundleTypes: [NODE_ESM],
moduleType: RENDERER_UTILS,
entry: 'react-transport-dom-webpack/node-loader',
global: 'ReactFlightWebpackNodeLoader',
externals: [],
},

/******* React Transport DOM Server Relay *******/
{
bundleTypes: [FB_WWW_DEV, FB_WWW_PROD],
Expand Down
1 change: 1 addition & 0 deletions scripts/shared/pathsByLanguageVersion.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
const esNextPaths = [
// Internal forwarding modules
'packages/*/*.js',
'packages/*/esm/*.js',
// Source files
'packages/*/src/**/*.js',
'packages/dom-event-testing-library/**/*.js',
Expand Down

0 comments on commit 50e1b77

Please sign in to comment.