Skip to content

Commit 32372da

Browse files
feat(render): Separate pretty from render (#1906)
Co-authored-by: gabriel miranda <[email protected]>
1 parent 02f3177 commit 32372da

File tree

14 files changed

+43
-28
lines changed

14 files changed

+43
-28
lines changed

.changeset/strong-peas-kneel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-email/render": minor
3+
---
4+
5+
Deprecate the `pretty` option for `render` in favor of standalone `pretty` function

apps/docs/utilities/render.mdx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,13 @@ export default MyTemplate;
5050

5151
Import an existing React component and convert into a HTML string.
5252

53-
<Info>You can use the `pretty` option to beautify the output.</Info>
53+
<Info>You can use the `pretty` function to beautify the output.</Info>
5454

5555
```jsx
5656
import { MyTemplate } from './email';
57-
import { render } from '@react-email/render';
57+
import { render, pretty } from '@react-email/render';
5858

59-
const html = await render(<MyTemplate />, {
60-
pretty: true,
61-
});
59+
const html = await pretty(await render(<MyTemplate />));
6260

6361
console.log(html);
6462
```
@@ -117,7 +115,7 @@ Click me [https://example.com]
117115

118116
## Options
119117

120-
<ResponseField name="pretty" type="boolean">
118+
<ResponseField name="pretty" type="boolean" deprecated>
121119
Beautify HTML output
122120
</ResponseField>
123121
<ResponseField name="plainText" type="boolean">
@@ -126,4 +124,3 @@ Click me [https://example.com]
126124
<ResponseField name="htmlToTextOptions" type="HtmlToTextOptions">
127125
`html-to-text` [options](https://github.com/html-to-text/node-html-to-text/tree/master/packages/html-to-text#options) used for rendering
128126
</ResponseField>
129-

apps/web/components/ensure-matching-variants.spec.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { existsSync } from 'node:fs';
22
import path from 'node:path';
3-
import { render } from '@react-email/components';
3+
import { pretty, render } from '@react-email/components';
44
import { parse, stringify } from 'html-to-ast';
55
import type { Attr, IDoc as Doc } from 'html-to-ast/dist/types';
66
import postcss from 'postcss';
@@ -81,12 +81,13 @@ describe('copy-paste components', () => {
8181
inlineStylesVariantPath,
8282
);
8383
const tailwindHtml = getComparableHtml(
84-
await render(<Layout>{tailwindElement}</Layout>, { pretty: true }),
84+
await pretty(await render(<Layout>{tailwindElement}</Layout>)),
8585
);
8686
const inlineStylesHtml = getComparableHtml(
87-
await render(
88-
<Layout withTailwind={false}>{inlineStylesElement}</Layout>,
89-
{ pretty: true },
87+
await pretty(
88+
await render(
89+
<Layout withTailwind={false}>{inlineStylesElement}</Layout>,
90+
),
9091
),
9192
);
9293
expect(tailwindHtml).toBe(inlineStylesHtml);

apps/web/src/app/components/get-imported-components-for.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs';
22
import path from 'node:path';
33
import { parse } from '@babel/parser';
44
import traverse from '@babel/traverse';
5-
import { render } from '@react-email/components';
5+
import { pretty, render } from '@react-email/components';
66
import { z } from 'zod';
77
import { Layout } from '../../../components/_components/layout';
88
import type { Category, Component } from '../../../components/structure';
@@ -84,9 +84,7 @@ export const getImportedComponent = async (
8484
if (variantFilenames.length === 1 && variantFilenames[0] === 'index.tsx') {
8585
const filePath = path.join(dirpath, 'index.tsx');
8686
const element = <Layout>{await getComponentElement(filePath)}</Layout>;
87-
const html = await render(element, {
88-
pretty: true,
89-
});
87+
const html = await pretty(await render(element));
9088
const fileContent = await fs.readFile(filePath, 'utf8');
9189
const code = getComponentCodeFrom(fileContent);
9290
return {
@@ -121,9 +119,7 @@ export const getImportedComponent = async (
121119

122120
const element = <Layout>{elements[0]}</Layout>;
123121

124-
codePerVariant.html = await render(element, {
125-
pretty: true,
126-
});
122+
codePerVariant.html = await pretty(await render(element));
127123

128124
return {
129125
...component,

packages/react-email/src/actions/render-email-by-path.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@ export const renderEmailByPath = async (
5858
emailComponent: Email,
5959
createElement,
6060
render,
61+
pretty,
6162
sourceMapToOriginalFile,
6263
} = componentResult;
6364

6465
const previewProps = Email.PreviewProps || {};
6566
const EmailComponent = Email as React.FC;
6667
try {
67-
const markup = await render(createElement(EmailComponent, previewProps), {
68-
pretty: true,
69-
});
68+
const markup = await pretty(
69+
await render(createElement(EmailComponent, previewProps)),
70+
);
7071
const plainText = await render(
7172
createElement(EmailComponent, previewProps),
7273
{

packages/react-email/src/cli/commands/export.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const getEmailTemplatesFromDirectory = (emailDirectory: EmailsDirectory) => {
2929

3030
type ExportTemplatesOptions = Options & {
3131
silent?: boolean;
32+
pretty?: boolean;
3233
};
3334

3435
/*
@@ -117,12 +118,15 @@ export const exportTemplates = async (
117118
element: React.ReactElement,
118119
options: Record<string, unknown>,
119120
) => Promise<string>;
121+
pretty: (str: string, options?: Options) => Promise<string>;
120122
reactEmailCreateReactElement: typeof React.createElement;
121123
};
122-
const rendered = await emailModule.render(
124+
let rendered = await emailModule.render(
123125
emailModule.reactEmailCreateReactElement(emailModule.default, {}),
124126
options,
125127
);
128+
if (!options.plainText && options.pretty)
129+
rendered = await emailModule.pretty(rendered);
126130
const htmlPath = template.replace(
127131
'.cjs',
128132
options.plainText ? '.txt' : '.html',

packages/react-email/src/cli/commands/testing/export.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ test(
1111
);
1212
const pathToDumpMarkup = path.resolve(__dirname, './out');
1313
await exportTemplates(pathToDumpMarkup, pathToEmailsDirectory, {
14-
pretty: true,
1514
silent: true,
15+
pretty: true,
1616
});
1717

1818
expect(fs.existsSync(pathToDumpMarkup)).toBe(true);

packages/react-email/src/cli/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ program
4949
false,
5050
)
5151
.action(({ outDir, pretty, plainText, silent, dir: srcDir }) =>
52-
exportTemplates(outDir, srcDir, { pretty, silent, plainText }),
52+
exportTemplates(outDir, srcDir, { silent, plainText, pretty }),
5353
);
5454

5555
program.parse();

packages/react-email/src/utils/esbuild/renderring-utilities-exporter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export const renderingUtilitiesExporter = (emailTemplates: string[]) => ({
2828
async ({ path: pathToFile }) => {
2929
return {
3030
contents: `${await fs.readFile(pathToFile, 'utf8')};
31-
export { render } from 'react-email-module-that-will-export-render'
31+
export { render, pretty } from 'react-email-module-that-will-export-render'
3232
export { createElement as reactEmailCreateReactElement } from 'react';
3333
`,
3434
loader: path.extname(pathToFile).slice(1) as Loader,

packages/react-email/src/utils/get-email-component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import path from 'node:path';
2-
import type { render } from '@react-email/components';
2+
import type { pretty, render } from '@react-email/components';
33
import { type BuildFailure, type OutputFile, build } from 'esbuild';
44
import type React from 'react';
55
import type { RawSourceMap } from 'source-map-js';
@@ -14,6 +14,7 @@ import type { ErrorObject } from './types/error-object';
1414
const EmailComponentModule = z.object({
1515
default: z.any(),
1616
render: z.function(),
17+
pretty: z.function(),
1718
reactEmailCreateReactElement: z.function(),
1819
});
1920

@@ -27,6 +28,8 @@ export const getEmailComponent = async (
2728

2829
render: typeof render;
2930

31+
pretty: typeof pretty;
32+
3033
sourceMapToOriginalFile: RawSourceMap;
3134
}
3235
| { error: ErrorObject }
@@ -126,6 +129,7 @@ export const getEmailComponent = async (
126129
return {
127130
emailComponent: componentModule.default as EmailComponent,
128131
render: componentModule.render as typeof render,
132+
pretty: componentModule.pretty as typeof pretty,
129133
createElement:
130134
componentModule.reactEmailCreateReactElement as typeof React.createElement,
131135

0 commit comments

Comments
 (0)