Skip to content

Commit

Permalink
use the preview-utils to render in the VS Code extension
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielmfern committed Dec 19, 2024
1 parent 4f15bef commit b458a0b
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 101 deletions.
3 changes: 2 additions & 1 deletion packages/visual-studio-code-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"publish": "vsce publish",
"package": "node ./prebuild.mjs && vsce package",
"vscode:prepublish": "pnpm build --minify",
"dev": "pnpm build --watch",
"build": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --tsconfig=./tsconfig.json --external:vscode --external:esbuild --format=cjs --platform=node",
"pretest": "pnpm build && pnpm lint",
"lint": "eslint ."
Expand Down Expand Up @@ -72,7 +73,7 @@
"esbuild": "^0.19.12"
},
"devDependencies": {
"@react-email/render": "workspace:*",
"preview-utils": "workspace:*",
"@types/mocha": "^10.0.2",
"@types/node": "18.x",
"@types/vscode": "^1.83.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/visual-studio-code-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export function activate(context: vscode.ExtensionContext) {
}

previewPanel = vscode.window.createWebviewPanel(
"react-email preview - try opening an email",
"react-email preview - try opening an email",
"React Email — try opening an email",
"React Email — try opening an email",
vscode.ViewColumn.Two,
{ enableScripts: true },
);
Expand Down
94 changes: 24 additions & 70 deletions packages/visual-studio-code-extension/src/render-open-email-file.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import * as vscode from "vscode";

import * as path from "path";
import * as vm from "vm";
import * as esbuild from "esbuild";

import { render } from "@react-email/render";
import { isFileAnEmail, renderEmailByPath } from "preview-utils";

export type BuiltEmail =
| {
filename: string;
html: string;
text: string;
valid: true;
}
filename: string;
html: string;
text: string;
valid: true;
}
| { valid: false };

export async function renderOpenEmailFile(
Expand All @@ -28,75 +26,31 @@ export async function renderOpenEmailFile(
}

const currentlyOpenTabFilePath = activeEditor.document.fileName; // actually a path not the name of the file
if (!isFileAnEmail(currentlyOpenTabFilePath)) {
return { valid: false };
}

const currentlyOpenTabFilename = path.basename(
currentlyOpenTabFilePath,
".tsx",
);

try {
const buildResult = await esbuild.build({
bundle: true,
entryPoints: [currentlyOpenTabFilePath],
platform: "node",
write: false,
jsx: "automatic",
loader: {
// eslint-disable-next-line @typescript-eslint/naming-convention
".js": "jsx",
},
format: "cjs",
});

console.log(global);

const fakeContext = {
...global,
process: {
env: {},
},
module: { exports: { default: undefined as unknown } },
__filanem: currentlyOpenTabFilePath,
__dirname: path.dirname(currentlyOpenTabFilePath),
};
const result = await renderEmailByPath(currentlyOpenTabFilePath);

try {
vm.runInNewContext(buildResult.outputFiles[0].text, fakeContext, {
filename: currentlyOpenTabFilePath,
});
} catch (exception) {
throw exception;
}

if (typeof fakeContext.module.exports.default !== "function") {
return {
valid: false,
};
}

const email = fakeContext.module.exports.default;

const comp = email("PreviewProps" in email ? email.PreviewProps : {}); // this may come without a defualt which might cause problems
const emailAsText = render(comp, {
plainText: true,
pretty: false,
});

const emailAsHTML = render(comp, { pretty: false });

return {
filename: currentlyOpenTabFilename,
html: emailAsHTML,
text: emailAsText,
valid: true,
};
} catch (exception) {
console.warn(
"Exception happenned on rendering or building of an email, but maybe its because it just was invalid anyways",
exception,
);

throw exception;
if ("error" in result) {
const err = new Error(result.error.message);
err.stack = result.error.stack;
err.name = result.error.name;
err.cause = result.error.cause;
throw err;
}

return {
valid: true,
filename: currentlyOpenTabFilename,
html: result.markup,
text: result.plainText,
};
}

return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export async function updatePreiewPanel(
builtEmail.html &&
builtEmail.html.trim().length > 0
) {
previewPanel.title = `react-email preview - ${builtEmail.filename}`;
previewPanel.title = `React Email — ${builtEmail.filename}`;
console.log(
builtEmail.html
);
previewPanel.webview.html =
convertAllEmailAssetSourcesIntoWebviewURIs(
builtEmail.html,
Expand All @@ -37,7 +40,7 @@ export async function updatePreiewPanel(
// this invalidness can happen if the focused content is a image,
// does not a export a default and for some other similar situations
} catch (exception) {
previewPanel.title = `react-email preview - error on the email ${basename(
previewPanel.title = `React Email — error on the email ${basename(
vscode.window.activeTextEditor.document.fileName,
)}`;
let errorMessage: string;
Expand All @@ -52,7 +55,7 @@ export async function updatePreiewPanel(
);
}
} else if (previewPanel.webview.html.trim().length === 0) {
previewPanel.title = `react-email preview - try opening an email!`;
previewPanel.title = `React Email — try opening an email!`;
previewPanel.webview.html = noEmailOpenHTML;
}
}
Expand Down
28 changes: 3 additions & 25 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b458a0b

Please sign in to comment.