create-pika-minigame 2.6.0 → 2.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +62 -27
- package/package.json +1 -1
- package/templates/package.json.template +9 -13
- package/templates/rspack.config.mjs +2 -0
- package/templates/scripts/deploy-vercel.sh +102 -18
- package/templates/scripts/pika-build.sh +112 -0
package/bin/cli.js
CHANGED
|
@@ -222,10 +222,12 @@ ${colors.reset}
|
|
|
222
222
|
// Copy scripts folder
|
|
223
223
|
if (fs.existsSync(scriptsTemplateDir)) {
|
|
224
224
|
copyDir(scriptsTemplateDir, path.join(targetDir, 'scripts'), replacements);
|
|
225
|
-
// Make
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
225
|
+
// Make shell scripts executable
|
|
226
|
+
const scriptsDir = path.join(targetDir, 'scripts');
|
|
227
|
+
for (const file of fs.readdirSync(scriptsDir)) {
|
|
228
|
+
if (file.endsWith('.sh')) {
|
|
229
|
+
fs.chmodSync(path.join(scriptsDir, file), '755');
|
|
230
|
+
}
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
233
|
|
|
@@ -253,63 +255,96 @@ ${colors.reset}
|
|
|
253
255
|
const pkgPath = path.join(targetDir, 'package.json');
|
|
254
256
|
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
255
257
|
|
|
258
|
+
// Only keep peer dependencies - actual deps come from pika-build workspace
|
|
256
259
|
pkg.dependencies = {
|
|
257
|
-
|
|
258
|
-
'react-native
|
|
260
|
+
react: pkg.dependencies.react,
|
|
261
|
+
'react-native': pkg.dependencies['react-native'],
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// These are peerDependencies for the game
|
|
265
|
+
pkg.peerDependencies = {
|
|
266
|
+
'react': '18.3.1',
|
|
267
|
+
'react-native': '0.77.0',
|
|
259
268
|
'react-native-reanimated': '~3.16.0',
|
|
260
|
-
'react-native-safe-area-context': '4.12.0',
|
|
261
269
|
};
|
|
262
270
|
|
|
263
271
|
pkg.devDependencies = {
|
|
264
272
|
...pkg.devDependencies,
|
|
265
|
-
'@
|
|
266
|
-
'
|
|
267
|
-
'@module-federation/enhanced': '^2.7.0',
|
|
268
|
-
'@rspack/core': '^1.7.12',
|
|
269
|
-
'@swc/helpers': '^0.5.19',
|
|
270
|
-
'ajv': '^8.17.0',
|
|
273
|
+
'@types/react': '~18.3.0',
|
|
274
|
+
'typescript': '~5.3.0',
|
|
271
275
|
'serve': '^14.2.0',
|
|
276
|
+
'eslint': '^8.0.0',
|
|
272
277
|
};
|
|
273
278
|
|
|
274
|
-
// Add build and deploy scripts
|
|
279
|
+
// Add build and deploy scripts (use pika-build.sh for MF compatibility)
|
|
275
280
|
pkg.scripts = {
|
|
276
281
|
...pkg.scripts,
|
|
277
|
-
'build:ios':
|
|
278
|
-
'build:android':
|
|
282
|
+
'build:ios': './scripts/pika-build.sh ios',
|
|
283
|
+
'build:android': './scripts/pika-build.sh android',
|
|
279
284
|
'build:all': 'npm run build:ios && npm run build:android',
|
|
280
285
|
'serve:ios': 'npx serve build/outputs/ios/remotes -l 9000 --cors',
|
|
281
286
|
'serve:android': 'npx serve build/outputs/android/remotes -l 9000 --cors',
|
|
287
|
+
'dev': 'npm run build:ios && npm run serve:ios',
|
|
282
288
|
'deploy': './scripts/deploy-vercel.sh',
|
|
283
289
|
'deploy:prod': './scripts/deploy-vercel.sh --prod',
|
|
284
290
|
};
|
|
285
291
|
|
|
286
292
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
287
293
|
|
|
288
|
-
|
|
294
|
+
// Step 5: Update .gitignore for Vercel
|
|
295
|
+
log.step(5, 'Updating .gitignore...');
|
|
296
|
+
const gitignorePath = path.join(targetDir, '.gitignore');
|
|
297
|
+
if (fs.existsSync(gitignorePath)) {
|
|
298
|
+
let gitignore = fs.readFileSync(gitignorePath, 'utf8');
|
|
299
|
+
if (!gitignore.includes('.vercel-prod-url')) {
|
|
300
|
+
gitignore += `
|
|
301
|
+
# Vercel
|
|
302
|
+
.vercel
|
|
303
|
+
.vercel-prod-url
|
|
304
|
+
|
|
305
|
+
# Build outputs
|
|
306
|
+
build/
|
|
307
|
+
`;
|
|
308
|
+
fs.writeFileSync(gitignorePath, gitignore);
|
|
309
|
+
log.success('Updated .gitignore');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
log.step(6, 'Project created successfully!');
|
|
289
314
|
|
|
290
315
|
console.log(`
|
|
291
316
|
${colors.green}Success!${colors.reset} Created ${colors.bright}${pascalName}${colors.reset} at ${targetDir}
|
|
292
317
|
|
|
318
|
+
${colors.bright}Prerequisites:${colors.reset}
|
|
319
|
+
|
|
320
|
+
Make sure you have the Pika host repo cloned at ~/robotapp (or set PIKA_HOST_DIR)
|
|
321
|
+
The build script uses the host's node_modules for Module Federation compatibility.
|
|
322
|
+
|
|
293
323
|
${colors.bright}Next steps:${colors.reset}
|
|
294
324
|
|
|
295
325
|
${colors.cyan}cd ${projectName}${colors.reset}
|
|
296
|
-
${colors.cyan}npm install
|
|
297
|
-
${colors.cyan}
|
|
298
|
-
${colors.cyan}npm run ios${colors.reset}
|
|
326
|
+
${colors.cyan}npm install${colors.reset}
|
|
327
|
+
${colors.cyan}npm run build:ios${colors.reset} # Build the game
|
|
328
|
+
${colors.cyan}npm run serve:ios${colors.reset} # Serve on port 9000
|
|
299
329
|
|
|
300
330
|
${colors.bright}Available commands:${colors.reset}
|
|
301
331
|
|
|
302
|
-
${colors.cyan}npm run ios${colors.reset}
|
|
303
|
-
${colors.cyan}npm run android${colors.reset}
|
|
304
|
-
${colors.cyan}npm
|
|
305
|
-
${colors.cyan}npm run
|
|
306
|
-
${colors.cyan}npm run deploy
|
|
332
|
+
${colors.cyan}npm run build:ios${colors.reset} Build for iOS (uses pika-build.sh)
|
|
333
|
+
${colors.cyan}npm run build:android${colors.reset} Build for Android
|
|
334
|
+
${colors.cyan}npm run serve:ios${colors.reset} Serve build on localhost:9000
|
|
335
|
+
${colors.cyan}npm run dev${colors.reset} Build + serve (one command)
|
|
336
|
+
${colors.cyan}npm run deploy${colors.reset} Deploy to Vercel (preview)
|
|
337
|
+
${colors.cyan}npm run deploy:prod${colors.reset} Deploy to Vercel (production)
|
|
307
338
|
|
|
308
339
|
${colors.bright}Project structure:${colors.reset}
|
|
309
340
|
|
|
310
341
|
src/ Game source code (edit this!)
|
|
311
|
-
|
|
312
|
-
|
|
342
|
+
scripts/ Build and deploy scripts
|
|
343
|
+
|
|
344
|
+
${colors.bright}Environment:${colors.reset}
|
|
345
|
+
|
|
346
|
+
PIKA_HOST_DIR Path to robotapp (default: ~/robotapp)
|
|
347
|
+
MF_PUBLIC_PATH Public URL for production builds
|
|
313
348
|
|
|
314
349
|
Happy coding! ${colors.yellow}🎮${colors.reset}
|
|
315
350
|
`);
|
package/package.json
CHANGED
|
@@ -5,32 +5,28 @@
|
|
|
5
5
|
"description": "Pika mini-game: {{PROJECT_NAME_PASCAL}}",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"build:
|
|
12
|
-
"build:android": "npx react-native webpack-bundle --platform android --entry-file index.js --dev false --bundle-output build/outputs/android/remotes/{{PROJECT_NAME_SNAKE}}.container.js.bundle",
|
|
8
|
+
"build:ios": "./scripts/pika-build.sh ios",
|
|
9
|
+
"build:android": "./scripts/pika-build.sh android",
|
|
10
|
+
"build:ios:prod": "./scripts/pika-build.sh ios --prod",
|
|
11
|
+
"build:android:prod": "./scripts/pika-build.sh android --prod",
|
|
13
12
|
"build:all": "npm run build:ios && npm run build:android",
|
|
14
13
|
"serve:ios": "npx serve build/outputs/ios/remotes -l 9000 --cors",
|
|
15
14
|
"serve:android": "npx serve build/outputs/android/remotes -l 9000 --cors",
|
|
16
15
|
"deploy": "./scripts/deploy-vercel.sh",
|
|
17
16
|
"deploy:prod": "./scripts/deploy-vercel.sh --prod",
|
|
17
|
+
"dev": "npm run build:ios && npm run serve:ios",
|
|
18
18
|
"lint": "eslint src/",
|
|
19
19
|
"typecheck": "tsc --noEmit"
|
|
20
20
|
},
|
|
21
|
-
"
|
|
21
|
+
"peerDependencies": {
|
|
22
22
|
"react": "18.3.1",
|
|
23
23
|
"react-native": "0.77.0",
|
|
24
|
-
"react-native-
|
|
25
|
-
"react-native-reanimated": "~3.16.0",
|
|
26
|
-
"react-native-safe-area-context": "4.12.0",
|
|
27
|
-
"react-native-screens": "~4.0.0"
|
|
24
|
+
"react-native-reanimated": "~3.16.0"
|
|
28
25
|
},
|
|
29
26
|
"devDependencies": {
|
|
30
|
-
"@babel/core": "^7.25.0",
|
|
31
|
-
"@callstack/repack": "^5.0.0",
|
|
32
27
|
"@types/react": "~18.3.0",
|
|
33
28
|
"typescript": "~5.3.0",
|
|
34
|
-
"serve": "^14.2.0"
|
|
29
|
+
"serve": "^14.2.0",
|
|
30
|
+
"eslint": "^8.0.0"
|
|
35
31
|
}
|
|
36
32
|
}
|
|
@@ -62,6 +62,8 @@ export default Repack.defineRspackConfig((env) => {
|
|
|
62
62
|
'./App': './src/App.tsx',
|
|
63
63
|
},
|
|
64
64
|
shared: {
|
|
65
|
+
// eager: false = load from host's share scope (smaller bundle)
|
|
66
|
+
// Requires building with pika-build.sh to ensure correct paths
|
|
65
67
|
react: { singleton: true, eager: false, requiredVersion: '18.3.1' },
|
|
66
68
|
'react-native': { singleton: true, eager: false, requiredVersion: '0.77.0' },
|
|
67
69
|
'react-native-reanimated': { singleton: true, eager: false },
|
|
@@ -8,6 +8,12 @@ set -e
|
|
|
8
8
|
# Usage:
|
|
9
9
|
# ./scripts/deploy-vercel.sh [--prod]
|
|
10
10
|
#
|
|
11
|
+
# First deploy creates a new Vercel project and saves the production URL.
|
|
12
|
+
# Subsequent deploys use the saved URL automatically.
|
|
13
|
+
#
|
|
14
|
+
# To reset and create a new Vercel project:
|
|
15
|
+
# rm -rf .vercel .vercel-prod-url && ./scripts/deploy-vercel.sh --prod
|
|
16
|
+
#
|
|
11
17
|
# Prerequisites:
|
|
12
18
|
# - Vercel CLI: npm i -g vercel
|
|
13
19
|
# - Logged in: vercel login
|
|
@@ -34,9 +40,24 @@ fi
|
|
|
34
40
|
|
|
35
41
|
# Parse arguments
|
|
36
42
|
PROD_FLAG=""
|
|
43
|
+
PROD_URL_FILE=".vercel-prod-url"
|
|
44
|
+
|
|
37
45
|
if [[ "$1" == "--prod" ]]; then
|
|
38
46
|
PROD_FLAG="--prod"
|
|
39
47
|
log_info "Deploying to PRODUCTION"
|
|
48
|
+
|
|
49
|
+
# Check for saved production URL (project-local)
|
|
50
|
+
if [[ -f "$PROD_URL_FILE" ]]; then
|
|
51
|
+
SAVED_PROD_URL=$(cat "$PROD_URL_FILE" | tr -d '[:space:]')
|
|
52
|
+
if [[ -n "$SAVED_PROD_URL" ]]; then
|
|
53
|
+
log_info "Using saved production URL: $SAVED_PROD_URL"
|
|
54
|
+
VERCEL_PROD_URL="$SAVED_PROD_URL"
|
|
55
|
+
fi
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
if [[ -z "$VERCEL_PROD_URL" ]]; then
|
|
59
|
+
log_info "No saved production URL found. Will detect after first deploy."
|
|
60
|
+
fi
|
|
40
61
|
else
|
|
41
62
|
log_info "Deploying to PREVIEW (add --prod for production)"
|
|
42
63
|
fi
|
|
@@ -48,7 +69,7 @@ PROJECT_VERSION=$(node -p "require('./package.json').version")
|
|
|
48
69
|
log_info "Project: $PROJECT_NAME v$PROJECT_VERSION"
|
|
49
70
|
|
|
50
71
|
# =============================================================================
|
|
51
|
-
# Step 1: Build for all platforms
|
|
72
|
+
# Step 1: Build for all platforms using pika-build.sh
|
|
52
73
|
# =============================================================================
|
|
53
74
|
log_info "Building mini-game bundles..."
|
|
54
75
|
|
|
@@ -57,24 +78,14 @@ BUILD_DIR="build/deploy"
|
|
|
57
78
|
rm -rf "$BUILD_DIR"
|
|
58
79
|
mkdir -p "$BUILD_DIR/ios" "$BUILD_DIR/android"
|
|
59
80
|
|
|
60
|
-
#
|
|
61
|
-
|
|
81
|
+
# Use pika-build.sh which builds in host's workspace for MF compatibility
|
|
82
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
62
83
|
|
|
63
84
|
log_info "Building iOS bundle..."
|
|
64
|
-
|
|
65
|
-
--platform ios \
|
|
66
|
-
--entry-file index.js \
|
|
67
|
-
--dev false \
|
|
68
|
-
--bundle-output build/outputs/ios/remotes/${PROJECT_NAME//-/_}.container.js.bundle \
|
|
69
|
-
2>&1 | tail -5
|
|
85
|
+
"$SCRIPT_DIR/pika-build.sh" ios 2>&1 | tail -10
|
|
70
86
|
|
|
71
87
|
log_info "Building Android bundle..."
|
|
72
|
-
|
|
73
|
-
--platform android \
|
|
74
|
-
--entry-file index.js \
|
|
75
|
-
--dev false \
|
|
76
|
-
--bundle-output build/outputs/android/remotes/${PROJECT_NAME//-/_}.container.js.bundle \
|
|
77
|
-
2>&1 | tail -5
|
|
88
|
+
"$SCRIPT_DIR/pika-build.sh" android 2>&1 | tail -10
|
|
78
89
|
|
|
79
90
|
# Copy to deploy directory with platform subdirs
|
|
80
91
|
cp -r build/outputs/ios/remotes/* "$BUILD_DIR/ios/"
|
|
@@ -147,9 +158,12 @@ log_success "Build complete: $BUILD_DIR"
|
|
|
147
158
|
# =============================================================================
|
|
148
159
|
log_info "Deploying to Vercel..."
|
|
149
160
|
|
|
150
|
-
#
|
|
161
|
+
# First deploy to get the project linked and get a URL
|
|
162
|
+
log_info "Initial deployment..."
|
|
151
163
|
DEPLOY_OUTPUT=$(vercel "$BUILD_DIR" $PROD_FLAG --yes 2>&1)
|
|
152
|
-
|
|
164
|
+
|
|
165
|
+
# Extract URL more carefully - look for vercel.app deployment URLs
|
|
166
|
+
DEPLOY_URL=$(echo "$DEPLOY_OUTPUT" | grep -oE 'https://[a-zA-Z0-9._-]+\.vercel\.app' | head -1)
|
|
153
167
|
|
|
154
168
|
if [[ -z "$DEPLOY_URL" ]]; then
|
|
155
169
|
log_error "Failed to get deployment URL"
|
|
@@ -157,10 +171,80 @@ if [[ -z "$DEPLOY_URL" ]]; then
|
|
|
157
171
|
exit 1
|
|
158
172
|
fi
|
|
159
173
|
|
|
174
|
+
# For production, use VERCEL_PROD_URL if set, otherwise try to auto-detect
|
|
175
|
+
if [[ "$PROD_FLAG" == "--prod" ]]; then
|
|
176
|
+
if [[ -n "$VERCEL_PROD_URL" ]]; then
|
|
177
|
+
# Use the saved/provided production URL
|
|
178
|
+
DEPLOY_URL="$VERCEL_PROD_URL"
|
|
179
|
+
log_info "Using production URL: $DEPLOY_URL"
|
|
180
|
+
else
|
|
181
|
+
log_info "Detecting production alias from Vercel..."
|
|
182
|
+
|
|
183
|
+
# Try to get alias from the deployed URL
|
|
184
|
+
PROD_DOMAIN=$(vercel inspect "$DEPLOY_URL" --json 2>/dev/null | node -e "
|
|
185
|
+
const data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
|
|
186
|
+
const alias = data.alias || data.aliases || [];
|
|
187
|
+
const prod = Array.isArray(alias) ? alias[0] : alias;
|
|
188
|
+
if (prod) console.log(prod);
|
|
189
|
+
" 2>/dev/null || echo "")
|
|
190
|
+
|
|
191
|
+
if [[ -n "$PROD_DOMAIN" ]]; then
|
|
192
|
+
PROD_DOMAIN=$(echo "$PROD_DOMAIN" | sed 's|^https://||')
|
|
193
|
+
DEPLOY_URL="https://$PROD_DOMAIN"
|
|
194
|
+
log_info "Detected production alias: $DEPLOY_URL"
|
|
195
|
+
else
|
|
196
|
+
# Use the deployment URL as-is (first deploy)
|
|
197
|
+
log_info "Using deployment URL as production URL: $DEPLOY_URL"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# Save for future deploys
|
|
201
|
+
echo "$DEPLOY_URL" > "$PROD_URL_FILE"
|
|
202
|
+
log_success "Saved production URL to $PROD_URL_FILE"
|
|
203
|
+
fi
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
log_info "Deployment URL: $DEPLOY_URL"
|
|
207
|
+
|
|
208
|
+
# =============================================================================
|
|
209
|
+
# Step 3: Update mf-manifest.json with correct publicPath and redeploy
|
|
210
|
+
# =============================================================================
|
|
211
|
+
log_info "Updating publicPath in manifests..."
|
|
212
|
+
|
|
213
|
+
# Update iOS manifest
|
|
214
|
+
if [[ -f "$BUILD_DIR/ios/mf-manifest.json" ]]; then
|
|
215
|
+
node -e "
|
|
216
|
+
const fs = require('fs');
|
|
217
|
+
const manifest = JSON.parse(fs.readFileSync('$BUILD_DIR/ios/mf-manifest.json', 'utf8'));
|
|
218
|
+
manifest.metaData.publicPath = '$DEPLOY_URL/ios/';
|
|
219
|
+
fs.writeFileSync('$BUILD_DIR/ios/mf-manifest.json', JSON.stringify(manifest, null, 2));
|
|
220
|
+
console.log('Updated iOS publicPath to: $DEPLOY_URL/ios/');
|
|
221
|
+
"
|
|
222
|
+
fi
|
|
223
|
+
|
|
224
|
+
# Update Android manifest
|
|
225
|
+
if [[ -f "$BUILD_DIR/android/mf-manifest.json" ]]; then
|
|
226
|
+
node -e "
|
|
227
|
+
const fs = require('fs');
|
|
228
|
+
const manifest = JSON.parse(fs.readFileSync('$BUILD_DIR/android/mf-manifest.json', 'utf8'));
|
|
229
|
+
manifest.metaData.publicPath = '$DEPLOY_URL/android/';
|
|
230
|
+
fs.writeFileSync('$BUILD_DIR/android/mf-manifest.json', JSON.stringify(manifest, null, 2));
|
|
231
|
+
console.log('Updated Android publicPath to: $DEPLOY_URL/android/');
|
|
232
|
+
"
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
# Redeploy with updated manifests
|
|
236
|
+
log_info "Redeploying with updated manifests..."
|
|
237
|
+
FINAL_OUTPUT=$(vercel "$BUILD_DIR" $PROD_FLAG --yes 2>&1)
|
|
238
|
+
FINAL_URL=$(echo "$FINAL_OUTPUT" | grep -oE 'https://[a-zA-Z0-9._-]+\.vercel\.app' | head -1)
|
|
239
|
+
|
|
240
|
+
if [[ -n "$FINAL_URL" ]]; then
|
|
241
|
+
DEPLOY_URL="$FINAL_URL"
|
|
242
|
+
fi
|
|
243
|
+
|
|
160
244
|
log_success "Deployed to: $DEPLOY_URL"
|
|
161
245
|
|
|
162
246
|
# =============================================================================
|
|
163
|
-
# Step
|
|
247
|
+
# Step 4: Show integration info
|
|
164
248
|
# =============================================================================
|
|
165
249
|
echo ""
|
|
166
250
|
echo "=============================================="
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# Pika Mini-Game Build Script
|
|
4
|
+
#
|
|
5
|
+
# Builds the mini-game using the Pika host's build environment to ensure
|
|
6
|
+
# Module Federation compatibility.
|
|
7
|
+
#
|
|
8
|
+
# Usage:
|
|
9
|
+
# ./scripts/pika-build.sh ios
|
|
10
|
+
# ./scripts/pika-build.sh android
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
set -e
|
|
14
|
+
|
|
15
|
+
PLATFORM=${1:-ios}
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
18
|
+
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
19
|
+
PROJECT_NAME=$(node -e "console.log(require('./app.json').name)" 2>/dev/null || basename "$PROJECT_DIR" | sed 's/-/_/g')
|
|
20
|
+
|
|
21
|
+
# Pika host repo - contains the correct node_modules
|
|
22
|
+
# Change this to your robotapp location or set PIKA_HOST_DIR env var
|
|
23
|
+
PIKA_HOST_DIR="${PIKA_HOST_DIR:-$HOME/robotapp}"
|
|
24
|
+
|
|
25
|
+
echo "🎮 Pika Mini-Game Builder"
|
|
26
|
+
echo "========================="
|
|
27
|
+
echo "Project: ${PROJECT_NAME}"
|
|
28
|
+
echo "Platform: ${PLATFORM}"
|
|
29
|
+
echo "Host dir: ${PIKA_HOST_DIR}"
|
|
30
|
+
echo ""
|
|
31
|
+
|
|
32
|
+
# Verify host directory exists
|
|
33
|
+
if [ ! -d "${PIKA_HOST_DIR}/node_modules/@callstack/repack" ]; then
|
|
34
|
+
echo "❌ Error: Pika host not found at ${PIKA_HOST_DIR}"
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Please either:"
|
|
37
|
+
echo " 1. Set PIKA_HOST_DIR environment variable to your robotapp location"
|
|
38
|
+
echo " 2. Or clone robotapp to ~/robotapp and run 'npm install'"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "Example:"
|
|
41
|
+
echo " export PIKA_HOST_DIR=/path/to/robotapp"
|
|
42
|
+
echo " ./scripts/pika-build.sh ios"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Create workspace in host's mini-games folder (temporarily)
|
|
47
|
+
WORKSPACE_DIR="${PIKA_HOST_DIR}/mini-games/_build_${PROJECT_NAME}"
|
|
48
|
+
|
|
49
|
+
echo "📁 Setting up build workspace..."
|
|
50
|
+
rm -rf "${WORKSPACE_DIR}"
|
|
51
|
+
mkdir -p "${WORKSPACE_DIR}"
|
|
52
|
+
|
|
53
|
+
# Copy source files
|
|
54
|
+
cp -r "${PROJECT_DIR}/src" "${WORKSPACE_DIR}/"
|
|
55
|
+
cp "${PROJECT_DIR}/index.js" "${WORKSPACE_DIR}/"
|
|
56
|
+
cp "${PROJECT_DIR}/app.json" "${WORKSPACE_DIR}/"
|
|
57
|
+
cp "${PROJECT_DIR}/babel.config.js" "${WORKSPACE_DIR}/"
|
|
58
|
+
cp "${PROJECT_DIR}/rspack.config.mjs" "${WORKSPACE_DIR}/"
|
|
59
|
+
cp "${PROJECT_DIR}/tsconfig.json" "${WORKSPACE_DIR}/" 2>/dev/null || true
|
|
60
|
+
|
|
61
|
+
# Create react-native.config.js
|
|
62
|
+
cat > "${WORKSPACE_DIR}/react-native.config.js" << 'EOF'
|
|
63
|
+
module.exports = {
|
|
64
|
+
commands: require('@callstack/repack/commands/rspack'),
|
|
65
|
+
};
|
|
66
|
+
EOF
|
|
67
|
+
|
|
68
|
+
# Create package.json with peerDependencies
|
|
69
|
+
cat > "${WORKSPACE_DIR}/package.json" << EOF
|
|
70
|
+
{
|
|
71
|
+
"name": "${PROJECT_NAME}",
|
|
72
|
+
"version": "1.0.0",
|
|
73
|
+
"private": true,
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build:ios": "npx react-native webpack-bundle --platform ios --entry-file index.js --dev false --bundle-output build/outputs/ios/local/index.ios.bundle --assets-dest build/outputs/ios/local",
|
|
76
|
+
"build:android": "npx react-native webpack-bundle --platform android --entry-file index.js --dev false --bundle-output build/outputs/android/local/index.android.bundle --assets-dest build/outputs/android/local"
|
|
77
|
+
},
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"react": "18.3.1",
|
|
80
|
+
"react-native": "0.77.0"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
EOF
|
|
84
|
+
|
|
85
|
+
echo "🔨 Building for ${PLATFORM}..."
|
|
86
|
+
|
|
87
|
+
cd "${WORKSPACE_DIR}"
|
|
88
|
+
|
|
89
|
+
# Set public path if MF_PUBLIC_PATH is set
|
|
90
|
+
if [ -n "$MF_PUBLIC_PATH" ]; then
|
|
91
|
+
export MF_PUBLIC_PATH
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
npm run build:${PLATFORM}
|
|
95
|
+
|
|
96
|
+
echo "📁 Copying build output..."
|
|
97
|
+
mkdir -p "${PROJECT_DIR}/build/outputs/${PLATFORM}"
|
|
98
|
+
cp -r "${WORKSPACE_DIR}/build/outputs/${PLATFORM}/remotes" "${PROJECT_DIR}/build/outputs/${PLATFORM}/"
|
|
99
|
+
|
|
100
|
+
# Cleanup workspace
|
|
101
|
+
rm -rf "${WORKSPACE_DIR}"
|
|
102
|
+
|
|
103
|
+
echo ""
|
|
104
|
+
echo "✅ Build successful!"
|
|
105
|
+
echo ""
|
|
106
|
+
echo "Output: ${PROJECT_DIR}/build/outputs/${PLATFORM}/remotes/"
|
|
107
|
+
echo ""
|
|
108
|
+
echo "Container size:"
|
|
109
|
+
ls -lh "${PROJECT_DIR}/build/outputs/${PLATFORM}/remotes/"*container*.bundle 2>/dev/null || echo " (no container found)"
|
|
110
|
+
echo ""
|
|
111
|
+
echo "To test locally:"
|
|
112
|
+
echo " npx serve build/outputs/${PLATFORM}/remotes -l 9000 --cors"
|