Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.

Commit 7a4adab

Browse files
Merge pull request #441 from platformsh/improvement/react-package-build-time
Improve react build performance
2 parents 730f4fa + 575822e commit 7a4adab

File tree

14 files changed

+256
-107
lines changed

14 files changed

+256
-107
lines changed

.github/workflows/test.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ jobs:
3636
uses: actions/setup-python@v4
3737
with:
3838
python-version: ${{ matrix.python-version }}
39-
cache: 'pip' # harmless even though we'll use uv
4039
- name: "Install uv"
4140
uses: astral-sh/setup-uv@v6
4241
with:

frontend/bun.lock

Lines changed: 79 additions & 58 deletions
Large diffs are not rendered by default.

frontend/package.json

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
{
22
"name": "frontend",
33
"version": "0.1.0",
4+
"type": "module",
45
"private": true,
56
"proxy": "http://0.0.0.0:8000",
67
"dependencies": {
7-
"@radix-ui/react-tooltip": "^1.0.7",
8+
"@radix-ui/react-tooltip": "^1.2.8",
89
"@testing-library/jest-dom": "^5.17.0",
910
"@testing-library/react": "^13.4.0",
1011
"@testing-library/user-event": "^13.5.0",
1112
"@types/jest": "^27.5.2",
12-
"@types/node": "^20.12.5",
13-
"@types/react": "^18.2.18",
14-
"@types/react-dom": "^18.2.18",
15-
"ajv": "^7",
16-
"postcss": "^8.4.38",
17-
"react": "^18.2.0",
18-
"react-code-blocks": "^0.1.5",
19-
"react-dom": "^18.2.0",
13+
"@types/node": "^20.19.19",
14+
"@types/react": "^18.3.25",
15+
"@types/react-dom": "^18.3.7",
16+
"ajv": "^7.2.4",
17+
"postcss": "^8.5.6",
18+
"react": "^18.3.1",
19+
"react-dom": "^18.3.1",
2020
"react-inject-env": "^2.1.0",
21-
"react-router-dom": "^6.21.2",
21+
"react-refractor": "^4.0.0",
22+
"react-router-dom": "^6.30.1",
2223
"react-scripts": "^5.0.1",
23-
"react-syntax-highlighter": "^15.5.0",
24+
"react-syntax-highlighter": "^15.6.6",
25+
"refractor": "^5.0.0",
2426
"typescript": "^4.9.5",
2527
"web-vitals": "^2.1.4"
2628
},
@@ -53,17 +55,21 @@
5355
},
5456
"jest": {
5557
"transform": {
56-
"^.+\\.svg$": "./src/tests/transformers/svg.js"
58+
"^.+\\.svg$": "<rootDir>/src/tests/transformers/svg.js"
59+
},
60+
"moduleNameMapper": {
61+
"^react-refractor$": "<rootDir>/__mocks__/react-refractor.js",
62+
"^refractor/yaml$": "<rootDir>/__mocks__/refractor/yaml.js"
5763
}
5864
},
5965
"devDependencies": {
6066
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
6167
"@svgr/webpack": "^8.1.0",
62-
"eslint-config-prettier": "^9.0.0",
63-
"eslint-plugin-prettier": "^5.0.0",
64-
"eslint-plugin-testing-library": "^6.0.1",
65-
"prettier": "^3.0.3",
66-
"tailwindcss": "^3.3.3"
68+
"eslint-config-prettier": "^9.1.2",
69+
"eslint-plugin-prettier": "^5.5.4",
70+
"eslint-plugin-testing-library": "^6.5.0",
71+
"prettier": "^3.6.2",
72+
"tailwindcss": "^3.4.17"
6773
},
6874
"overrides": {
6975
"@svgr/webpack": "$@svgr/webpack"

frontend/src/__mocks__/react-code-blocks.js

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from "react";
2+
3+
export const Refractor = () => {
4+
return <div data-testid="mocked-code-block">RefractorMock</div>;
5+
};
6+
7+
export const registerLanguage = () => {};
8+
9+
export default Refractor;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const yaml = {};
2+
export default yaml;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, { useMemo } from "react";
2+
import { Refractor, registerLanguage } from "react-refractor";
3+
import yaml from "refractor/yaml";
4+
5+
registerLanguage(yaml);
6+
7+
interface CodeBlockProps {
8+
text: string;
9+
language?: "yaml" | "javascript";
10+
showLineNumbers?: boolean;
11+
startingLineNumber?: number;
12+
className?: string;
13+
}
14+
15+
export default function CodeBlock({
16+
text,
17+
language = "yaml",
18+
showLineNumbers = true,
19+
startingLineNumber = 1,
20+
className,
21+
}: CodeBlockProps) {
22+
const lines = useMemo(() => text.split("\n"), [text]);
23+
24+
const numbers = lines
25+
.map((_, i) => String(startingLineNumber + i))
26+
.join("\n");
27+
28+
return (
29+
<pre
30+
className={`flex ${className || ""} overflow-x-auto`}
31+
data-starting-line-number={startingLineNumber}
32+
data-testid="code-block"
33+
>
34+
{showLineNumbers && (
35+
<div
36+
className="text-right text-gray-400 select-none"
37+
data-starting-line-number={startingLineNumber}
38+
>
39+
<Refractor
40+
language="text"
41+
value={numbers}
42+
inline={false}
43+
className="!rounded-r-none !pr-0"
44+
/>
45+
</div>
46+
)}
47+
<div className="flex-1" data-starting-line-number={startingLineNumber}>
48+
<Refractor
49+
language={language}
50+
value={text}
51+
inline={false}
52+
className="!rounded-l-none"
53+
/>
54+
</div>
55+
</pre>
56+
);
57+
}

frontend/src/index.css

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,46 @@
8484
/*@apply border-b-[40px] border-l-[50px] border-b-upsun-violet-600 border-l-transparent;*/
8585
}
8686
}
87+
88+
@layer components {
89+
code[class*="language-"] {
90+
@apply block;
91+
}
92+
93+
:not(.gutter) > code[class*="language-"] {
94+
@apply text-gray-400;
95+
}
96+
97+
pre[class*="language-"] {
98+
@apply text-white bg-black p-4 m-0 overflow-auto rounded-md;
99+
}
100+
101+
code[class*="language-"] .token.comment {
102+
@apply text-white italic;
103+
}
104+
105+
code[class*="language-"] .token.key {
106+
@apply text-upsun-yellow-400;
107+
}
108+
109+
code[class*="language-"] .token.string,
110+
code[class*="language-"] .token.char {
111+
@apply text-[#34E2E2];
112+
}
113+
114+
code[class*="language-"] .token.punctuation {
115+
@apply text-[#ccc];
116+
}
117+
118+
code[class*="language-"] .token.function {
119+
@apply text-[#FFD700];
120+
}
121+
122+
code[class*="language-"] .token.variable {
123+
@apply text-[#F0E68C];
124+
}
125+
126+
code[class*="language-"] .token.number {
127+
@apply text-[#FFA500];
128+
}
129+
}

frontend/src/steps/StepRedis.test.tsx

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
1+
import fs from "fs";
2+
import path from "path";
13
import { render, screen } from "@testing-library/react";
24
import StepRedis from "./StepRedis";
35

6+
function getSnippetStartLine(filePath: string, marker: string) {
7+
const contents = fs.readFileSync(filePath, "utf-8").split("\n");
8+
const idx = contents.findIndex((line) => line.includes(marker));
9+
if (idx === -1) throw new Error(`Marker "${marker}" not found`);
10+
return idx + 1;
11+
}
12+
413
describe("<StepRedis />", () => {
514
it("renders with correct title", async () => {
615
render(
@@ -10,7 +19,6 @@ describe("<StepRedis />", () => {
1019
environment="staging"
1120
/>,
1221
);
13-
1422
expect(
1523
await screen.findByText("3. Add Redis to staging"),
1624
).toBeInTheDocument();
@@ -20,11 +28,30 @@ describe("<StepRedis />", () => {
2028
render(
2129
<StepRedis isDisabled={true} hideContent={false} environment="staging" />,
2230
);
23-
2431
expect(await screen.findByTestId("step-redis")).toHaveClass("is-disabled");
2532
});
2633

27-
it("renders the mocked code block instead of the real one", async () => {
34+
it("renders one mocked code block for gutter and one for code", async () => {
35+
render(
36+
<StepRedis
37+
isDisabled={false}
38+
hideContent={false}
39+
environment="staging"
40+
/>,
41+
);
42+
43+
const block = screen.getByTestId("code-block");
44+
45+
expect(block).toBeInTheDocument();
46+
});
47+
48+
it("uses the correct startingLineNumber based on config.yaml", () => {
49+
const filePath = path.resolve(process.cwd(), "../.upsun/config.yaml");
50+
const expectedLineNumber = getSnippetStartLine(
51+
filePath,
52+
"#add_service_start",
53+
);
54+
2855
render(
2956
<StepRedis
3057
isDisabled={false}
@@ -33,6 +60,11 @@ describe("<StepRedis />", () => {
3360
/>,
3461
);
3562

36-
expect(await screen.findByTestId("mocked-code-block")).toBeInTheDocument();
63+
const block = screen.getByTestId("code-block");
64+
65+
expect(block).toHaveAttribute(
66+
"data-starting-line-number",
67+
String(expectedLineNumber),
68+
);
3769
});
3870
});

frontend/src/steps/StepRedis.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React from "react";
22
import FeatureStep from "../components/FeatureStep";
33
import { ReactComponent as RedisIcon } from "../assets/utility/service_redis.svg";
4-
import { CodeBlock } from "react-code-blocks";
5-
import UpsunCodeTheme from "../theme/code";
4+
import CodeBlock from "../components/CodeBlock";
65
import CopyButton from "../components/CopyButton";
76
import commands from "../commands.json";
87
import CodeExample from "../components/CodeExample";
@@ -70,8 +69,7 @@ services:
7069
text={servicesText}
7170
language="yaml"
7271
showLineNumbers
73-
theme={UpsunCodeTheme}
74-
startingLineNumber={67}
72+
startingLineNumber={79}
7573
/>
7674
</div>
7775
</li>

0 commit comments

Comments
 (0)