Skip to content

Commit 5eb431e

Browse files
committed
chore(build): add Vercel preview builds for framework test apps
1 parent 308aef5 commit 5eb431e

File tree

4 files changed

+307
-1
lines changed

4 files changed

+307
-1
lines changed

core/vercel.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema": "https://openapi.vercel.sh/vercel.json",
3+
"framework": null,
4+
"installCommand": "npm install",
5+
"buildCommand": "bash ../scripts/vercel-build.sh",
6+
"outputDirectory": "../_vercel_output",
7+
"rewrites": [
8+
{ "source": "/angular/:path*", "destination": "/angular/index.html" },
9+
{ "source": "/react/:path*", "destination": "/react/index.html" },
10+
{ "source": "/vue/:path*", "destination": "/vue/index.html" },
11+
{ "source": "/react-router/:path*", "destination": "/react-router/index.html" }
12+
]
13+
}

packages/react/test/base/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ setupIonicReact();
4444

4545
const App: React.FC = () => (
4646
<IonApp>
47-
<IonReactRouter>
47+
<IonReactRouter basename={import.meta.env?.BASE_URL?.replace(/\/$/, '')}>
4848
<IonRouterOutlet>
4949
<Route exact path="/" component={Main} />
5050
<Route path="/overlay-hooks" component={OverlayHooks} />
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
11
/// <reference types="react-scripts" />
2+
3+
interface ImportMetaEnv {
4+
readonly BASE_URL?: string;
5+
}
6+
7+
interface ImportMeta {
8+
readonly env?: ImportMetaEnv;
9+
}

scripts/vercel-build.sh

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
#!/bin/bash
2+
#
3+
# Vercel preview build script
4+
#
5+
# Builds core component tests (same as before) plus framework test apps
6+
# (Angular, React, Vue) so they're all accessible from a single preview URL.
7+
#
8+
# Core tests: /src/components/{name}/test/{scenario}
9+
# Angular test app: /angular/
10+
# React test app: /react/
11+
# Vue test app: /vue/
12+
# React Router app: /react-router/ (only Vite-based apps, i.e. RR6+)
13+
#
14+
set -e
15+
16+
# Vercel sets CWD to the project root directory (core/), so go up one level
17+
REPO_ROOT=$(cd "$(dirname "$0")/.." && pwd)
18+
OUTPUT_DIR="${REPO_ROOT}/_vercel_output"
19+
20+
echo "=== Ionic Framework Preview Build ==="
21+
echo "Root: ${REPO_ROOT}"
22+
23+
rm -rf "${OUTPUT_DIR}"
24+
mkdir -p "${OUTPUT_DIR}"
25+
26+
# ---------------------------------------------------------------------------
27+
# Step 1 - Build Core (dependencies already installed by Vercel installCommand)
28+
# ---------------------------------------------------------------------------
29+
echo ""
30+
echo "--- Step 1: Building Core ---"
31+
cd "${REPO_ROOT}/core"
32+
npm run build
33+
34+
# Copy core files to output. The test HTML files use relative paths like
35+
# ../../../../../dist/ionic/ionic.esm.js so the directory structure must
36+
# be preserved exactly.
37+
echo "Copying core output..."
38+
cp -r "${REPO_ROOT}/core/src" "${OUTPUT_DIR}/src"
39+
cp -r "${REPO_ROOT}/core/dist" "${OUTPUT_DIR}/dist"
40+
cp -r "${REPO_ROOT}/core/css" "${OUTPUT_DIR}/css"
41+
mkdir -p "${OUTPUT_DIR}/scripts"
42+
cp -r "${REPO_ROOT}/core/scripts/testing" "${OUTPUT_DIR}/scripts/testing"
43+
44+
# ---------------------------------------------------------------------------
45+
# Step 2 - Build Framework Packages (parallel)
46+
# ---------------------------------------------------------------------------
47+
echo ""
48+
echo "--- Step 2: Building Framework Packages ---"
49+
50+
build_angular_pkgs() {
51+
cd "${REPO_ROOT}/packages/angular" && npm install && npm run build
52+
cd "${REPO_ROOT}/packages/angular-server" && npm install && npm run build
53+
}
54+
55+
build_react_pkgs() {
56+
cd "${REPO_ROOT}/packages/react" && npm install && npm run build
57+
cd "${REPO_ROOT}/packages/react-router" && npm install && npm run build
58+
}
59+
60+
build_vue_pkgs() {
61+
cd "${REPO_ROOT}/packages/vue" && npm install && npm run build
62+
cd "${REPO_ROOT}/packages/vue-router" && npm install && npm run build
63+
}
64+
65+
build_angular_pkgs > /tmp/vercel-angular-pkg.log 2>&1 &
66+
PID_ANG=$!
67+
build_react_pkgs > /tmp/vercel-react-pkg.log 2>&1 &
68+
PID_REACT=$!
69+
build_vue_pkgs > /tmp/vercel-vue-pkg.log 2>&1 &
70+
PID_VUE=$!
71+
72+
FAILED=""
73+
wait $PID_ANG || { echo "Angular packages failed:"; tail -30 /tmp/vercel-angular-pkg.log; FAILED="${FAILED} angular-pkg"; }
74+
wait $PID_REACT || { echo "React packages failed:"; tail -30 /tmp/vercel-react-pkg.log; FAILED="${FAILED} react-pkg"; }
75+
wait $PID_VUE || { echo "Vue packages failed:"; tail -30 /tmp/vercel-vue-pkg.log; FAILED="${FAILED} vue-pkg"; }
76+
77+
if [ -n "${FAILED}" ]; then
78+
echo "ERROR: Framework package builds failed:${FAILED}"
79+
echo "Core tests will still be deployed."
80+
# Generate landing page and exit early -- core tests are still useful
81+
generate_landing_page
82+
exit 0
83+
fi
84+
85+
echo "All framework packages built."
86+
87+
# ---------------------------------------------------------------------------
88+
# Step 3 - Build Framework Test Apps (parallel)
89+
# ---------------------------------------------------------------------------
90+
echo ""
91+
echo "--- Step 3: Building Framework Test Apps ---"
92+
93+
# Find the best available app version for a given package
94+
pick_app() {
95+
local test_dir="$1"
96+
shift
97+
for v in "$@"; do
98+
if [ -d "${test_dir}/apps/${v}" ]; then
99+
echo "${v}"
100+
return 0
101+
fi
102+
done
103+
return 1
104+
}
105+
106+
build_angular_test() {
107+
local APP
108+
APP=$(pick_app "${REPO_ROOT}/packages/angular/test" ng20 ng19 ng18) || {
109+
echo "[angular] No test app found, skipping."
110+
return 0
111+
}
112+
echo "[angular] Building ${APP}..."
113+
114+
cd "${REPO_ROOT}/packages/angular/test"
115+
./build.sh "${APP}"
116+
cd "build/${APP}"
117+
npm install
118+
npm run sync
119+
# --base-href sets <base href="/angular/"> so Angular Router works under the sub-path
120+
npm run build -- --base-href /angular/
121+
122+
mkdir -p "${OUTPUT_DIR}/angular"
123+
cp -r dist/test-app/browser/* "${OUTPUT_DIR}/angular/"
124+
echo "[angular] Done."
125+
}
126+
127+
build_react_test() {
128+
local APP
129+
APP=$(pick_app "${REPO_ROOT}/packages/react/test" react19 react18) || {
130+
echo "[react] No test app found, skipping."
131+
return 0
132+
}
133+
echo "[react] Building ${APP}..."
134+
135+
cd "${REPO_ROOT}/packages/react/test"
136+
./build.sh "${APP}"
137+
cd "build/${APP}"
138+
npm install
139+
npm run sync
140+
# --base sets Vite's base URL; import.meta.env.BASE_URL is read by IonReactRouter basename
141+
npx vite build --base /react/
142+
143+
mkdir -p "${OUTPUT_DIR}/react"
144+
cp -r dist/* "${OUTPUT_DIR}/react/"
145+
echo "[react] Done."
146+
}
147+
148+
build_vue_test() {
149+
echo "[vue] Building vue3..."
150+
151+
cd "${REPO_ROOT}/packages/vue/test"
152+
./build.sh vue3
153+
cd build/vue3
154+
npm install
155+
npm run sync
156+
# Vue Router already reads import.meta.env.BASE_URL which Vite sets from --base
157+
npx vite build --base /vue/
158+
159+
mkdir -p "${OUTPUT_DIR}/vue"
160+
cp -r dist/* "${OUTPUT_DIR}/vue/"
161+
echo "[vue] Done."
162+
}
163+
164+
build_react_router_test() {
165+
# Only build Vite-based (RR6+) apps. CRA-based reactrouter5 can't handle
166+
# sub-path routing without code changes, and it's being replaced by RR6.
167+
local APP
168+
APP=$(pick_app "${REPO_ROOT}/packages/react-router/test" reactrouter6-react19 reactrouter6-react18 reactrouter6) || {
169+
echo "[react-router] No Vite-based test app found, skipping."
170+
return 0
171+
}
172+
echo "[react-router] Building ${APP}..."
173+
174+
cd "${REPO_ROOT}/packages/react-router/test"
175+
./build.sh "${APP}"
176+
cd "build/${APP}"
177+
npm install --legacy-peer-deps
178+
npm run sync
179+
npx vite build --base /react-router/
180+
181+
mkdir -p "${OUTPUT_DIR}/react-router"
182+
cp -r dist/* "${OUTPUT_DIR}/react-router/"
183+
echo "[react-router] Done."
184+
}
185+
186+
build_angular_test > /tmp/vercel-angular-test.log 2>&1 &
187+
PID_ANG_TEST=$!
188+
build_react_test > /tmp/vercel-react-test.log 2>&1 &
189+
PID_REACT_TEST=$!
190+
build_vue_test > /tmp/vercel-vue-test.log 2>&1 &
191+
PID_VUE_TEST=$!
192+
build_react_router_test > /tmp/vercel-rr-test.log 2>&1 &
193+
PID_RR_TEST=$!
194+
195+
TEST_FAILED=""
196+
wait $PID_ANG_TEST || { echo "Angular test app failed:"; tail -30 /tmp/vercel-angular-test.log; TEST_FAILED="${TEST_FAILED} angular"; }
197+
wait $PID_REACT_TEST || { echo "React test app failed:"; tail -30 /tmp/vercel-react-test.log; TEST_FAILED="${TEST_FAILED} react"; }
198+
wait $PID_VUE_TEST || { echo "Vue test app failed:"; tail -30 /tmp/vercel-vue-test.log; TEST_FAILED="${TEST_FAILED} vue"; }
199+
wait $PID_RR_TEST || { echo "React Router test app failed:"; tail -30 /tmp/vercel-rr-test.log; TEST_FAILED="${TEST_FAILED} react-router"; }
200+
201+
if [ -n "${TEST_FAILED}" ]; then
202+
echo ""
203+
echo "WARNING: Some test app builds failed:${TEST_FAILED}"
204+
echo "Core tests and successful framework apps will still be deployed."
205+
fi
206+
207+
# ---------------------------------------------------------------------------
208+
# Step 4 - Landing Page
209+
# ---------------------------------------------------------------------------
210+
echo ""
211+
echo "--- Step 4: Generating landing page ---"
212+
213+
cat > "${OUTPUT_DIR}/index.html" << 'LANDING_EOF'
214+
<!DOCTYPE html>
215+
<html lang="en">
216+
<head>
217+
<meta charset="UTF-8">
218+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
219+
<title>Ionic Framework - Preview</title>
220+
<style>
221+
* { margin: 0; padding: 0; box-sizing: border-box; }
222+
body {
223+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
224+
background: #f5f5f5; padding: 2rem; color: #333;
225+
}
226+
.container { max-width: 680px; margin: 0 auto; }
227+
h1 { font-size: 1.4rem; margin-bottom: 0.25rem; }
228+
.subtitle { color: #666; margin-bottom: 1.5rem; font-size: 0.875rem; }
229+
.cards { display: grid; gap: 0.75rem; }
230+
a.card {
231+
background: #fff; border-radius: 8px; padding: 1rem 1.25rem;
232+
text-decoration: none; color: inherit;
233+
border: 1px solid #e0e0e0; transition: border-color 0.15s;
234+
}
235+
a.card:hover { border-color: #4f8ef7; }
236+
.card h2 { font-size: 1rem; margin-bottom: 0.2rem; display: flex; align-items: center; gap: 0.5rem; }
237+
.card p { color: #666; font-size: 0.8rem; }
238+
.badge {
239+
display: inline-block; font-size: 0.65rem; padding: 1px 6px;
240+
border-radius: 3px; font-weight: 600;
241+
}
242+
.badge-green { background: #e8f5e9; color: #2e7d32; }
243+
.badge-blue { background: #e3f2fd; color: #1565c0; }
244+
.badge-red { background: #fce4ec; color: #c62828; }
245+
.badge-purple{ background: #f3e5f5; color: #6a1b9a; }
246+
hr { border: none; border-top: 1px solid #e0e0e0; margin: 1rem 0; }
247+
.tip { font-size: 0.75rem; color: #999; margin-top: 1rem; }
248+
</style>
249+
</head>
250+
<body>
251+
<div class="container">
252+
<h1>Ionic Framework Preview</h1>
253+
<p class="subtitle">Component test apps for manual validation</p>
254+
<div class="cards">
255+
<a class="card" href="/src/components/">
256+
<h2>Core Components <span class="badge badge-blue">Stencil</span></h2>
257+
<p>Browse to /src/components/{name}/test/{scenario}/</p>
258+
</a>
259+
<hr>
260+
<a class="card" href="/angular/">
261+
<h2>Angular <span class="badge badge-red">ng20</span></h2>
262+
<p>@ionic/angular standalone + lazy-loaded component tests</p>
263+
</a>
264+
<a class="card" href="/react/">
265+
<h2>React <span class="badge badge-blue">react19</span></h2>
266+
<p>@ionic/react overlays, hooks, tabs, form controls</p>
267+
</a>
268+
<a class="card" href="/vue/">
269+
<h2>Vue <span class="badge badge-green">vue3</span></h2>
270+
<p>@ionic/vue overlays, router, tabs, lifecycle</p>
271+
</a>
272+
<a class="card" href="/react-router/">
273+
<h2>React Router <span class="badge badge-purple">rr6</span></h2>
274+
<p>@ionic/react-router navigation, tabs, transitions</p>
275+
</a>
276+
</div>
277+
<p class="tip">Links to framework apps that were not built will 404.</p>
278+
</div>
279+
</body>
280+
</html>
281+
LANDING_EOF
282+
283+
echo ""
284+
echo "=== Preview build complete ==="
285+
ls -la "${OUTPUT_DIR}"

0 commit comments

Comments
 (0)