Compare commits
3 Commits
pr33512
...
sebbie/rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
027534e673 | ||
|
|
f23fc95209 | ||
|
|
07b977b734 |
@@ -9,7 +9,7 @@
|
||||
|
||||
import type {Thenable} from 'shared/ReactTypes';
|
||||
|
||||
export * from 'react-html/src/ReactHTMLLegacyClientStreamConfig.js';
|
||||
export * from 'react-markup/src/ReactMarkupLegacyClientStreamConfig.js';
|
||||
export * from 'react-client/src/ReactClientConsoleConfigPlain';
|
||||
|
||||
export type ModuleLoading = null;
|
||||
|
||||
7
packages/react-html/npm/index.js
vendored
7
packages/react-html/npm/index.js
vendored
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-html.production.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-html.development.js');
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-html.react-server.production.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-html.react-server.development.js');
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
# `react-html`
|
||||
# `react-markup`
|
||||
|
||||
This package provides the ability to render standalone HTML from Server Components for use in embedded contexts such as e-mails and RSS/Atom feeds. It cannot use Client Components and does not hydrate. It is intended to be paired with the generic React package, which is shipped as `react` to npm.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install react react-html
|
||||
npm install react react-markup
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import { renderToMarkup } from 'react-html';
|
||||
import { experimental_renderToMarkup } from 'react-markup';
|
||||
import EmailTemplate from './my-email-template-component.js'
|
||||
|
||||
async function action(email, name) {
|
||||
"use server";
|
||||
// ... in your server, e.g. a Server Action...
|
||||
const htmlString = await renderToMarkup(<EmailTemplate name={name} />);
|
||||
const htmlString = await experimental_renderToMarkup(<EmailTemplate name={name} />);
|
||||
// ... send e-mail using some e-mail provider
|
||||
await sendEmail({ to: email, contentType: 'text/html', body: htmlString });
|
||||
}
|
||||
@@ -27,6 +27,6 @@ Note that this is an async function that needs to be awaited - unlike the legacy
|
||||
|
||||
## API
|
||||
|
||||
### `react-html`
|
||||
### `react-markup`
|
||||
|
||||
See https://react.dev/reference/react-html
|
||||
See https://react.dev/reference/react-markup
|
||||
10
packages/react-markup/index.experimental.js
Normal file
10
packages/react-markup/index.experimental.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and 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 {renderToMarkup as experimental_renderToMarkup} from './src/ReactMarkupClient';
|
||||
@@ -7,4 +7,4 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export * from './src/ReactHTMLClient';
|
||||
export {};
|
||||
7
packages/react-markup/npm/index.js
vendored
Normal file
7
packages/react-markup/npm/index.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-markup.production.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-markup.development.js');
|
||||
}
|
||||
7
packages/react-markup/npm/react-html.react-server.js
Normal file
7
packages/react-markup/npm/react-html.react-server.js
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-markup.react-server.production.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-markup.react-server.development.js');
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
{
|
||||
"name": "react-html",
|
||||
"name": "react-markup",
|
||||
"version": "19.0.0",
|
||||
"private": true,
|
||||
"description": "React package generating embedded HTML markup such as e-mails using Server Components.",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/facebook/react.git",
|
||||
"directory": "packages/react-html"
|
||||
"directory": "packages/react-markup"
|
||||
},
|
||||
"keywords": [
|
||||
"react"
|
||||
@@ -24,12 +23,12 @@
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
"index.js",
|
||||
"react-html.react-server.js",
|
||||
"react-markup.react-server.js",
|
||||
"cjs/"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"react-server": "./react-html.react-server.js",
|
||||
"react-server": "./react-markup.react-server.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./src/*": "./src/*",
|
||||
@@ -7,4 +7,4 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export * from './src/ReactHTMLServer';
|
||||
export * from './src/ReactMarkupServer';
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
createResumableState,
|
||||
createRenderState,
|
||||
createRootFormatContext,
|
||||
} from './ReactFizzConfigHTML';
|
||||
} from './ReactFizzConfigMarkup';
|
||||
|
||||
type MarkupOptions = {
|
||||
identifierPrefix?: string,
|
||||
@@ -8,4 +8,4 @@
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line react-internal/prod-error-codes
|
||||
throw new Error('react-html should not get built in stable');
|
||||
throw new Error('react-markup should not get built in stable');
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
createResumableState,
|
||||
createRenderState,
|
||||
createRootFormatContext,
|
||||
} from './ReactFizzConfigHTML';
|
||||
} from './ReactFizzConfigMarkup';
|
||||
|
||||
type ReactMarkupNodeList =
|
||||
// This is the intersection of ReactNodeList and ReactClientValue minus
|
||||
@@ -8,4 +8,4 @@
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line react-internal/prod-error-codes
|
||||
throw new Error('react-html should not get built in stable');
|
||||
throw new Error('react-markup should not get built in stable');
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
let React;
|
||||
let ReactHTML;
|
||||
let ReactMarkup;
|
||||
|
||||
function normalizeCodeLocInfo(str) {
|
||||
return (
|
||||
@@ -24,18 +24,18 @@ function normalizeCodeLocInfo(str) {
|
||||
if (!__EXPERIMENTAL__) {
|
||||
it('should not be built in stable', () => {
|
||||
try {
|
||||
require('react-html');
|
||||
require('react-markup');
|
||||
} catch (x) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Expected react-html not to exist in stable.');
|
||||
throw new Error('Expected react-markup not to exist in stable.');
|
||||
});
|
||||
} else {
|
||||
describe('ReactHTML', () => {
|
||||
describe('ReactMarkup', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
React = require('react');
|
||||
ReactHTML = require('react-html');
|
||||
ReactMarkup = require('react-markup');
|
||||
});
|
||||
|
||||
it('should be able to render a simple component', async () => {
|
||||
@@ -43,7 +43,7 @@ if (!__EXPERIMENTAL__) {
|
||||
return <div>hello world</div>;
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(<Component />);
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(<Component />);
|
||||
expect(html).toBe('<div>hello world</div>');
|
||||
});
|
||||
|
||||
@@ -52,14 +52,14 @@ if (!__EXPERIMENTAL__) {
|
||||
return <div>{'hello '.repeat(200)}world</div>;
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
expect(html).toBe('<div>' + ('hello '.repeat(200) + 'world') + '</div>');
|
||||
});
|
||||
|
||||
it('should prefix html tags with a doctype', async () => {
|
||||
const html = await ReactHTML.renderToMarkup(
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(
|
||||
<html>
|
||||
<body>hello</body>
|
||||
</html>,
|
||||
@@ -76,7 +76,7 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(<Component />);
|
||||
await ReactMarkup.experimental_renderToMarkup(<Component />);
|
||||
}).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -87,7 +87,7 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(<Component />);
|
||||
await ReactMarkup.experimental_renderToMarkup(<Component />);
|
||||
}).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -100,7 +100,7 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(<Component />);
|
||||
await ReactMarkup.experimental_renderToMarkup(<Component />);
|
||||
}).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -142,7 +142,7 @@ if (!__EXPERIMENTAL__) {
|
||||
);
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(<Component />);
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(<Component />);
|
||||
const container = document.createElement('div');
|
||||
container.innerHTML = html;
|
||||
|
||||
@@ -176,7 +176,7 @@ if (!__EXPERIMENTAL__) {
|
||||
);
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(<Component />);
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(<Component />);
|
||||
expect(html).toBe('<div>01</div>');
|
||||
});
|
||||
|
||||
@@ -199,7 +199,7 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(
|
||||
await ReactMarkup.experimental_renderToMarkup(
|
||||
<div>
|
||||
<Foo />
|
||||
</div>,
|
||||
@@ -13,7 +13,7 @@ global.TextDecoder = require('util').TextDecoder;
|
||||
global.TextEncoder = require('util').TextEncoder;
|
||||
|
||||
let React;
|
||||
let ReactHTML;
|
||||
let ReactMarkup;
|
||||
|
||||
function normalizeCodeLocInfo(str) {
|
||||
return (
|
||||
@@ -27,34 +27,34 @@ function normalizeCodeLocInfo(str) {
|
||||
if (!__EXPERIMENTAL__) {
|
||||
it('should not be built in stable', () => {
|
||||
try {
|
||||
require('react-html');
|
||||
require('react-markup');
|
||||
} catch (x) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Expected react-html not to exist in stable.');
|
||||
throw new Error('Expected react-markup not to exist in stable.');
|
||||
});
|
||||
} else {
|
||||
describe('ReactHTML', () => {
|
||||
describe('ReactMarkup', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
// We run in the react-server condition.
|
||||
jest.mock('react', () => require('react/react.react-server'));
|
||||
if (__EXPERIMENTAL__) {
|
||||
jest.mock('react-html', () =>
|
||||
require('react-html/react-html.react-server'),
|
||||
jest.mock('react-markup', () =>
|
||||
require('react-markup/react-markup.react-server'),
|
||||
);
|
||||
}
|
||||
|
||||
React = require('react');
|
||||
if (__EXPERIMENTAL__) {
|
||||
ReactHTML = require('react-html');
|
||||
ReactMarkup = require('react-markup');
|
||||
} else {
|
||||
try {
|
||||
require('react-html/react-html.react-server');
|
||||
require('react-markup/react-markup.react-server');
|
||||
} catch (x) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Expected react-html not to exist in stable.');
|
||||
throw new Error('Expected react-markup not to exist in stable.');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -64,7 +64,7 @@ if (!__EXPERIMENTAL__) {
|
||||
return React.createElement('div', null, 'hello world');
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
expect(html).toBe('<div>hello world</div>');
|
||||
@@ -76,14 +76,14 @@ if (!__EXPERIMENTAL__) {
|
||||
return React.createElement('div', null, 'hello '.repeat(200) + 'world');
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
expect(html).toBe('<div>' + ('hello '.repeat(200) + 'world') + '</div>');
|
||||
});
|
||||
|
||||
it('should prefix html tags with a doctype', async () => {
|
||||
const html = await ReactHTML.renderToMarkup(
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(
|
||||
// We can't use JSX because that's client-JSX in our tests.
|
||||
React.createElement(
|
||||
'html',
|
||||
@@ -104,7 +104,9 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(React.createElement(Component));
|
||||
await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
}).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -116,7 +118,9 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(React.createElement(Component));
|
||||
await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
}).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -130,7 +134,9 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(React.createElement(Component));
|
||||
await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
}).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -173,7 +179,7 @@ if (!__EXPERIMENTAL__) {
|
||||
);
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
const container = document.createElement('div');
|
||||
@@ -204,7 +210,7 @@ if (!__EXPERIMENTAL__) {
|
||||
return React.createElement('div', null, a, b);
|
||||
}
|
||||
|
||||
const html = await ReactHTML.renderToMarkup(
|
||||
const html = await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement(Component),
|
||||
);
|
||||
expect(html).toBe('<div>00</div>');
|
||||
@@ -225,7 +231,7 @@ if (!__EXPERIMENTAL__) {
|
||||
}
|
||||
|
||||
await expect(async () => {
|
||||
await ReactHTML.renderToMarkup(
|
||||
await ReactMarkup.experimental_renderToMarkup(
|
||||
React.createElement('div', null, React.createElement(Foo)),
|
||||
{
|
||||
onError(error, errorInfo) {
|
||||
@@ -13,4 +13,4 @@ export * from 'react-dom-bindings/src/client/ReactFiberConfigDOM';
|
||||
export * from 'react-client/src/ReactClientConsoleConfigBrowser';
|
||||
|
||||
// eslint-disable-next-line react-internal/prod-error-codes
|
||||
throw new Error('Fiber is not used in react-html');
|
||||
throw new Error('Fiber is not used in react-markup');
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
import type {Request} from 'react-server/src/ReactFizzServer';
|
||||
|
||||
export * from 'react-html/src/ReactFizzConfigHTML.js';
|
||||
export * from 'react-markup/src/ReactFizzConfigMarkup.js';
|
||||
|
||||
export * from 'react-client/src/ReactClientConsoleConfigPlain';
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@
|
||||
"528": "Expected <link> not to update to be updated to a stylesheet with precedence. Check the `rel`, `href`, and `precedence` props of this component. Alternatively, check whether two different <link> components render in the same slot or share the same key.%s",
|
||||
"529": "Expected stylesheet with precedence to not be updated to a different kind of <link>. Check the `rel`, `href`, and `precedence` props of this component. Alternatively, check whether two different <link> components render in the same slot or share the same key.%s",
|
||||
"530": "The render was aborted by the server with a promise.",
|
||||
"531": "react-html is not supported outside a React Server Components environment.",
|
||||
"531": "react-markup is not supported outside a React Server Components environment.",
|
||||
"532": "Attempted to render a Client Component from renderToMarkup. This is not supported since it will never hydrate. Only render Server Components with renderToMarkup.",
|
||||
"533": "Attempted to render a Server Action from renderToMarkup. This is not supported since it varies by version of the app. Use a fixed URL for any forms instead.",
|
||||
"534": "renderToMarkup should not have emitted Client References. This is a bug in React.",
|
||||
@@ -527,4 +527,4 @@
|
||||
"539": "Binary RSC chunks cannot be encoded as strings. This is a bug in the wiring of the React streams.",
|
||||
"540": "String chunks need to be passed in their original shape. Not split into smaller string chunks. This is a bug in the wiring of the React streams.",
|
||||
"541": "Compared context values must be arrays"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,10 +367,10 @@ const bundles = [
|
||||
{
|
||||
bundleTypes: __EXPERIMENTAL__ ? [NODE_DEV, NODE_PROD] : [],
|
||||
moduleType: RENDERER,
|
||||
entry: 'react-html/src/ReactHTMLServer.js',
|
||||
name: 'react-html.react-server',
|
||||
entry: 'react-markup/src/ReactMarkupServer.js',
|
||||
name: 'react-markup.react-server',
|
||||
condition: 'react-server',
|
||||
global: 'ReactHTML',
|
||||
global: 'ReactMarkup',
|
||||
minifyWithProdErrorCodes: false,
|
||||
wrapWithModuleBoundaries: false,
|
||||
externals: ['react'],
|
||||
@@ -380,9 +380,9 @@ const bundles = [
|
||||
{
|
||||
bundleTypes: __EXPERIMENTAL__ ? [NODE_DEV, NODE_PROD] : [],
|
||||
moduleType: RENDERER,
|
||||
entry: 'react-html/src/ReactHTMLClient.js',
|
||||
name: 'react-html',
|
||||
global: 'ReactHTML',
|
||||
entry: 'react-markup/src/ReactMarkupClient.js',
|
||||
name: 'react-markup',
|
||||
global: 'ReactMarkup',
|
||||
minifyWithProdErrorCodes: false,
|
||||
wrapWithModuleBoundaries: false,
|
||||
externals: ['react'],
|
||||
|
||||
@@ -65,8 +65,8 @@ const forks = Object.freeze({
|
||||
if (entry === 'react/src/ReactServer.js') {
|
||||
return './packages/react/src/ReactSharedInternalsServer.js';
|
||||
}
|
||||
if (entry === 'react-html/src/ReactHTMLServer.js') {
|
||||
// Inside the ReactHTMLServer render we don't refer to any shared internals
|
||||
if (entry === 'react-markup/src/ReactMarkupServer.js') {
|
||||
// Inside the ReactMarkupServer render we don't refer to any shared internals
|
||||
// but instead use our own internal copy of the state because you cannot use
|
||||
// any of this state from a component anyway. E.g. you can't use a client hook.
|
||||
return './packages/react/src/ReactSharedInternalsClient.js';
|
||||
@@ -100,8 +100,8 @@ const forks = Object.freeze({
|
||||
entry === 'react-dom/src/ReactDOMFB.js' ||
|
||||
entry === 'react-dom/src/ReactDOMTestingFB.js' ||
|
||||
entry === 'react-dom/src/ReactDOMServer.js' ||
|
||||
entry === 'react-html/src/ReactHTMLClient.js' ||
|
||||
entry === 'react-html/src/ReactHTMLServer.js'
|
||||
entry === 'react-markup/src/ReactMarkupClient.js' ||
|
||||
entry === 'react-markup/src/ReactMarkupServer.js'
|
||||
) {
|
||||
if (
|
||||
bundleType === FB_WWW_DEV ||
|
||||
|
||||
@@ -444,14 +444,14 @@ module.exports = [
|
||||
{
|
||||
shortName: 'markup',
|
||||
entryPoints: [
|
||||
'react-html/src/ReactHTMLClient.js', // react-html
|
||||
'react-html/src/ReactHTMLServer.js', // react-html/react-html.react-server
|
||||
'react-markup/src/ReactMarkupClient.js', // react-markup
|
||||
'react-markup/src/ReactMarkupServer.js', // react-markup/react-markup.react-server
|
||||
],
|
||||
paths: [
|
||||
'react-dom',
|
||||
'react-dom/src/ReactDOMReactServer.js',
|
||||
'react-dom-bindings',
|
||||
'react-html',
|
||||
'react-markup',
|
||||
'shared/ReactDOMSharedInternals',
|
||||
],
|
||||
isFlowTyped: true,
|
||||
|
||||
Reference in New Issue
Block a user