Skip to content

Commit 813693c

Browse files
committed
add initial version with error
1 parent 735f038 commit 813693c

20 files changed

+762
-14
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import path from 'node:path';
2+
import child_process from 'node:child_process';
3+
import * as playwright from 'playwright';
4+
import shell from 'shelljs';
5+
6+
const $ = (command: string, cwd: string = path.resolve(__dirname, '..')) => {
7+
const executionResult = shell.exec(command, {
8+
cwd,
9+
fatal: true,
10+
silent: true,
11+
});
12+
if (executionResult.code !== 0) {
13+
process.stdout.write(executionResult.stderr);
14+
process.stderr.write(executionResult.stderr);
15+
}
16+
expect(
17+
executionResult.code,
18+
`Expected command "${command}" to work properly but it returned a non-zero exit code`,
19+
).toBe(0);
20+
};
21+
22+
describe('integrations', () => {
23+
let page!: playwright.Page;
24+
let browser!: playwright.Browser;
25+
26+
beforeAll(async () => {
27+
const packageLocation = path.resolve(import.meta.dirname, '../');
28+
$('yalc installations clean @react-email/render', packageLocation);
29+
$('yalc publish', packageLocation);
30+
31+
browser = await playwright.chromium.launch();
32+
page = await browser.newPage();
33+
});
34+
35+
afterAll(async () => {
36+
browser.close();
37+
});
38+
39+
describe('vite', () => {
40+
let devServer: child_process.ChildProcess;
41+
beforeAll(() => {
42+
const viteLocation = path.resolve(import.meta.dirname, './vite/');
43+
$('npm install', viteLocation);
44+
devServer = child_process.spawn('npm', ['run', 'dev'], {
45+
shell: true,
46+
cwd: viteLocation,
47+
stdio: 'pipe',
48+
});
49+
return new Promise<void>((resolve) => {
50+
devServer.on('spawn', async () => {
51+
await page.goto('http://127.0.0.1:5173');
52+
resolve();
53+
});
54+
});
55+
});
56+
57+
afterAll(() => {
58+
devServer.kill();
59+
});
60+
61+
it('should not error when rendering', async () => {
62+
await page.waitForSelector('[data-testid="rendered-html"]', {
63+
timeout: 500
64+
});
65+
});
66+
});
67+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"compilerOptions": {
4+
"types": ["@vitest/browser/providers/playwright"]
5+
},
6+
"include": ["integrations.spec.ts"]
7+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright 2024 Plus Five Five, Inc
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
{
2+
"name": "@react-email/render",
3+
"version": "1.1.0-canary.1",
4+
"description": "Transform React components into HTML email templates",
5+
"sideEffects": false,
6+
"main": "./dist/browser/index.js",
7+
"module": "./dist/browser/index.mjs",
8+
"types": "./dist/browser/index.d.ts",
9+
"files": [
10+
"dist/**"
11+
],
12+
"exports": {
13+
".": {
14+
"node": {
15+
"import": {
16+
"types": "./dist/node/index.d.mts",
17+
"default": "./dist/node/index.mjs"
18+
},
19+
"require": {
20+
"types": "./dist/node/index.d.ts",
21+
"default": "./dist/node/index.js"
22+
}
23+
},
24+
"deno": {
25+
"import": {
26+
"types": "./dist/browser/index.d.mts",
27+
"default": "./dist/browser/index.mjs"
28+
},
29+
"require": {
30+
"types": "./dist/browser/index.d.ts",
31+
"default": "./dist/browser/index.js"
32+
}
33+
},
34+
"worker": {
35+
"import": {
36+
"types": "./dist/browser/index.d.mts",
37+
"default": "./dist/browser/index.mjs"
38+
},
39+
"require": {
40+
"types": "./dist/browser/index.d.ts",
41+
"default": "./dist/browser/index.js"
42+
}
43+
},
44+
"browser": {
45+
"import": {
46+
"types": "./dist/browser/index.d.mts",
47+
"default": "./dist/browser/index.mjs"
48+
},
49+
"require": {
50+
"types": "./dist/browser/index.d.ts",
51+
"default": "./dist/browser/index.js"
52+
}
53+
},
54+
"default": {
55+
"import": {
56+
"types": "./dist/node/index.d.mts",
57+
"default": "./dist/node/index.mjs"
58+
},
59+
"require": {
60+
"types": "./dist/node/index.d.ts",
61+
"default": "./dist/node/index.js"
62+
}
63+
}
64+
}
65+
},
66+
"license": "MIT",
67+
"scripts": {
68+
"build": "tsup-node",
69+
"clean": "rm -rf dist",
70+
"dev": "tsup-node --watch",
71+
"test": "vitest run",
72+
"test:watch": "vitest"
73+
},
74+
"repository": {
75+
"type": "git",
76+
"url": "https://github.com/resend/react-email.git",
77+
"directory": "packages/render"
78+
},
79+
"keywords": [
80+
"react",
81+
"email"
82+
],
83+
"engines": {
84+
"node": ">=18.0.0"
85+
},
86+
"dependencies": {
87+
"html-to-text": "^9.0.5",
88+
"prettier": "^3.5.3",
89+
"react-promise-suspense": "^0.3.4"
90+
},
91+
"peerDependencies": {
92+
"react": "^18.0 || ^19.0 || ^19.0.0-rc",
93+
"react-dom": "^18.0 || ^19.0 || ^19.0.0-rc"
94+
},
95+
"publishConfig": {
96+
"access": "public"
97+
},
98+
"yalcSig": "6e502c45a0cc6d24195e55ec1ab3474c"
99+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
![React Email button cover](https://react.email/static/covers/render.png)
2+
3+
<div align="center"><strong>@react-email/render</strong></div>
4+
<div align="center">Transform React components into HTML email templates.</div>
5+
<br />
6+
<div align="center">
7+
<a href="https://react.email">Website</a>
8+
<span> · </span>
9+
<a href="https://github.com/resend/react-email">GitHub</a>
10+
<span> · </span>
11+
<a href="https://react.email/discord">Discord</a>
12+
</div>
13+
14+
## Install
15+
16+
Install component from your command line.
17+
18+
#### With yarn
19+
20+
```sh
21+
yarn add @react-email/render -E
22+
```
23+
24+
#### With npm
25+
26+
```sh
27+
npm install @react-email/render -E
28+
```
29+
30+
## Getting started
31+
32+
Convert React components into a HTML string.
33+
34+
```jsx
35+
import { MyTemplate } from "../components/MyTemplate";
36+
import { render } from "@react-email/render";
37+
38+
const html = await render(<MyTemplate firstName="Jim" />);
39+
```
40+
41+
## License
42+
43+
MIT License
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6e502c45a0cc6d24195e55ec1ab3474c
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# React + TypeScript + Vite
2+
3+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4+
5+
Currently, two official plugins are available:
6+
7+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9+
10+
## Expanding the ESLint configuration
11+
12+
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
13+
14+
```js
15+
export default tseslint.config({
16+
extends: [
17+
// Remove ...tseslint.configs.recommended and replace with this
18+
...tseslint.configs.recommendedTypeChecked,
19+
// Alternatively, use this for stricter rules
20+
...tseslint.configs.strictTypeChecked,
21+
// Optionally, add this for stylistic rules
22+
...tseslint.configs.stylisticTypeChecked,
23+
],
24+
languageOptions: {
25+
// other options...
26+
parserOptions: {
27+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
28+
tsconfigRootDir: import.meta.dirname,
29+
},
30+
},
31+
})
32+
```
33+
34+
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
35+
36+
```js
37+
// eslint.config.js
38+
import reactX from 'eslint-plugin-react-x'
39+
import reactDom from 'eslint-plugin-react-dom'
40+
41+
export default tseslint.config({
42+
plugins: {
43+
// Add the react-x and react-dom plugins
44+
'react-x': reactX,
45+
'react-dom': reactDom,
46+
},
47+
rules: {
48+
// other rules...
49+
// Enable its recommended typescript rules
50+
...reactX.configs['recommended-typescript'].rules,
51+
...reactDom.configs.recommended.rules,
52+
},
53+
})
54+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import js from '@eslint/js'
2+
import globals from 'globals'
3+
import reactHooks from 'eslint-plugin-react-hooks'
4+
import reactRefresh from 'eslint-plugin-react-refresh'
5+
import tseslint from 'typescript-eslint'
6+
7+
export default tseslint.config(
8+
{ ignores: ['dist'] },
9+
{
10+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
11+
files: ['**/*.{ts,tsx}'],
12+
languageOptions: {
13+
ecmaVersion: 2020,
14+
globals: globals.browser,
15+
},
16+
plugins: {
17+
'react-hooks': reactHooks,
18+
'react-refresh': reactRefresh,
19+
},
20+
rules: {
21+
...reactHooks.configs.recommended.rules,
22+
'react-refresh/only-export-components': [
23+
'warn',
24+
{ allowConstantExport: true },
25+
],
26+
},
27+
},
28+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React + TS</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)