Skip to content

Commit

Permalink
perf: move overlay template to server side (#4276)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Dec 26, 2024
1 parent b457159 commit 2e5750b
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 134 deletions.
16 changes: 12 additions & 4 deletions packages/core/src/client/hmr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ function clearOutdatedErrors() {
}
}

let createOverlay: undefined | ((err: string[]) => void);
let createOverlay: undefined | ((overlay: string, errors: string[]) => void);
let clearOverlay: undefined | (() => void);

export const registerOverlay = (
createFn: (err: string[]) => void,
createFn: (overlay: string, errors: string[]) => void,
clearFn: () => void,
): void => {
createOverlay = createFn;
Expand Down Expand Up @@ -91,7 +91,15 @@ function handleWarnings({ text }: { text: string[] }) {
}

// Compilation with errors (e.g. syntax error or missing modules).
function handleErrors({ text, html }: { text: string[]; html: string[] }) {
function handleErrors({
text,
html,
overlay,
}: {
text: string[];
html: string[];
overlay: string;
}) {
clearOutdatedErrors();

isFirstCompilation = false;
Expand All @@ -103,7 +111,7 @@ function handleErrors({ text, html }: { text: string[]; html: string[] }) {
}

if (createOverlay) {
createOverlay(html);
createOverlay(overlay, html);
}
}

Expand Down
135 changes: 5 additions & 130 deletions packages/core/src/client/overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,134 +28,13 @@ function linkedText(root: ShadowRoot, selector: string, text: string): void {
el.insertAdjacentHTML('beforeend', frag);
}

const overlayTemplate = `
<style>
.root {
position: fixed;
z-index: 9999;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow-y: scroll;
margin: 0;
background: rgba(0, 0, 0, 0.66);
cursor: pointer;
}
.container {
font-family: Menlo, Consolas, monospace;
line-height: 1.6;
width: 960px;
max-width: 85%;
color: #d8d8d8;
margin: 32px auto;
padding: 32px 40px;
position: relative;
background: #181818;
border-radius: 24px;
box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
overflow: hidden;
direction: ltr;
text-align: left;
box-sizing: border-box;
cursor: default;
}
.title {
margin: 0 0 20px;
padding-bottom: 12px;
font-size: 17px;
font-weight: 600;
color: #fb6a6a;
border-bottom: 2px solid rgba(252,94,94,.66);
}
.content {
margin: 0;
font-size: 14px;
font-family: inherit;
overflow-x: scroll;
scrollbar-width: none;
}
.content::-webkit-scrollbar {
display: none;
}
.file-link {
cursor: pointer;
color: #6eecf7;
text-decoration: underline;
text-underline-offset: 3px;
&:hover {
opacity: 0.8;
}
&:active {
opacity: 0.6;
}
}
.close {
position: absolute;
top: 27px;
right: 32px;
width: 32px;
height: 32px;
cursor: pointer;
}
.close:hover {
opacity: 0.8;
}
.close:active {
opacity: 0.6;
}
.close:before,
.close:after {
position: absolute;
left: 16px;
top: 8px;
content: ' ';
height: 18px;
width: 2px;
border-radius: 4px;
background-color: #b8b8b8;
}
.close:before {
transform: rotate(45deg);
}
.close:after {
transform: rotate(-45deg);
}
.footer {
font-size: 12px;
color: #7e6a92;
margin-top: 20px;
padding-top: 12px;
border-top: 2px solid rgba(126,106,146,.6);
}
.footer p {
margin: 4px 0 0;
}
.footer span {
color: #a88dc3;
}
</style>
<div class="root">
<div class="container">
<div class="close"></div>
<p class="title">Build failed</p>
<pre class="content"></pre>
<footer class="footer">
<p><span>Fix error</span>, click outside, or press Esc to close the overlay.</p>
<p>Disable overlay by setting Rsbuild's <span>dev.client.overlay</span> config to false.<p>
</footer>
</div>
</div>
`;

const {
HTMLElement = class {} as typeof globalThis.HTMLElement,
customElements,
} = typeof window !== 'undefined' ? window : globalThis;

class ErrorOverlay extends HTMLElement {
constructor(message: string[]) {
constructor(overlay: string, errors: string[]) {
super();

if (!this.attachShadow) {
Expand All @@ -166,15 +45,12 @@ class ErrorOverlay extends HTMLElement {
}

const root = this.attachShadow({ mode: 'open' });
root.innerHTML = overlayTemplate;

linkedText(root, '.content', message.join('\n\n').trim());
root.innerHTML = overlay;

linkedText(root, '.content', errors.join('\n\n').trim());
root.querySelector('.close')?.addEventListener('click', this.close);

// close overlay when click outside
this.addEventListener('click', this.close);

root.querySelector('.container')!.addEventListener('click', (e) => {
e.stopPropagation();
});
Expand All @@ -185,7 +61,6 @@ class ErrorOverlay extends HTMLElement {
}
document.removeEventListener('keydown', onEscKeydown);
};

document.addEventListener('keydown', onEscKeydown);
}

Expand All @@ -209,9 +84,9 @@ if (customElements && !customElements.get(overlayId)) {
customElements.define(overlayId, ErrorOverlay);
}

function createOverlay(err: string[]) {
function createOverlay(overlay: string, errors: string[]) {
clearOverlay();
document.body.appendChild(new ErrorOverlay(err));
document.body.appendChild(new ErrorOverlay(overlay, errors));
}

function clearOverlay() {
Expand Down
123 changes: 123 additions & 0 deletions packages/core/src/server/socketServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,128 @@ interface ExtWebSocket extends Ws {
isAlive: boolean;
}

// HTML template for error overlay
const overlayTemplate = `
<style>
.root {
position: fixed;
z-index: 9999;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow-y: scroll;
margin: 0;
background: rgba(0, 0, 0, 0.66);
cursor: pointer;
}
.container {
font-family: Menlo, Consolas, monospace;
line-height: 1.6;
width: 960px;
max-width: 85%;
color: #d8d8d8;
margin: 32px auto;
padding: 32px 40px;
position: relative;
background: #181818;
border-radius: 24px;
box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
overflow: hidden;
direction: ltr;
text-align: left;
box-sizing: border-box;
cursor: default;
}
.title {
margin: 0 0 20px;
padding-bottom: 12px;
font-size: 17px;
font-weight: 600;
color: #fb6a6a;
border-bottom: 2px solid rgba(252,94,94,.66);
}
.content {
margin: 0;
font-size: 14px;
font-family: inherit;
overflow-x: scroll;
scrollbar-width: none;
}
.content::-webkit-scrollbar {
display: none;
}
.file-link {
cursor: pointer;
color: #6eecf7;
text-decoration: underline;
text-underline-offset: 3px;
&:hover {
opacity: 0.8;
}
&:active {
opacity: 0.6;
}
}
.close {
position: absolute;
top: 27px;
right: 32px;
width: 32px;
height: 32px;
cursor: pointer;
}
.close:hover {
opacity: 0.8;
}
.close:active {
opacity: 0.6;
}
.close:before,
.close:after {
position: absolute;
left: 16px;
top: 8px;
content: ' ';
height: 18px;
width: 2px;
border-radius: 4px;
background-color: #b8b8b8;
}
.close:before {
transform: rotate(45deg);
}
.close:after {
transform: rotate(-45deg);
}
.footer {
font-size: 12px;
color: #7e6a92;
margin-top: 20px;
padding-top: 12px;
border-top: 2px solid rgba(126,106,146,.6);
}
.footer p {
margin: 4px 0 0;
}
.footer span {
color: #a88dc3;
}
</style>
<div class="root">
<div class="container">
<div class="close"></div>
<p class="title">Build failed</p>
<pre class="content"></pre>
<footer class="footer">
<p><span>Fix error</span>, click outside, or press Esc to close the overlay.</p>
<p>Disable overlay by setting Rsbuild's <span>dev.client.overlay</span> config to false.<p>
</footer>
</div>
</div>
`;

function isEqualSet(a: Set<string>, b: Set<string>): boolean {
if (a.size !== b.size) {
return false;
Expand Down Expand Up @@ -297,6 +419,7 @@ export class SocketServer {
data: {
text: formattedErrors,
html: formattedErrors.map((item) => ansiHTML(escapeHtml(item))),
overlay: overlayTemplate,
},
});
}
Expand Down

0 comments on commit 2e5750b

Please sign in to comment.