create-apollo-monorepo 0.2.0 → 0.3.1
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/index.mjs +118 -1
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -325,9 +325,47 @@ function writeRootPackageJson(targetDir, dirName) {
|
|
|
325
325
|
"backend:setup": "pnpm --filter ./apps/backend setup",
|
|
326
326
|
},
|
|
327
327
|
engines: { node: ">=20", pnpm: ">=9" },
|
|
328
|
-
|
|
328
|
+
pnpm: {
|
|
329
|
+
// apollo-cms transitively pulls multiple esbuild versions (0.18, 0.25, 0.27).
|
|
330
|
+
// pnpm's binary symlink can pick the wrong platform binary for esbuild's
|
|
331
|
+
// postinstall version check, failing with "Expected X.Y.Z but got A.B.C".
|
|
332
|
+
// Allow listed packages to run their build/postinstall scripts; the rest
|
|
333
|
+
// are skipped (pnpm 10 default is empty allow-list).
|
|
334
|
+
onlyBuiltDependencies: [
|
|
335
|
+
"@swc/core",
|
|
336
|
+
"@swc/core-darwin-arm64",
|
|
337
|
+
"@swc/core-darwin-x64",
|
|
338
|
+
"@swc/core-linux-arm64-gnu",
|
|
339
|
+
"@swc/core-linux-x64-gnu",
|
|
340
|
+
"esbuild",
|
|
341
|
+
"msw",
|
|
342
|
+
"sharp",
|
|
343
|
+
"unrs-resolver",
|
|
344
|
+
"@rolldown/binding-darwin-arm64",
|
|
345
|
+
"@rolldown/binding-linux-x64-gnu",
|
|
346
|
+
"@rolldown/binding-linux-arm64-gnu",
|
|
347
|
+
"better-sqlite3",
|
|
348
|
+
"core-js",
|
|
349
|
+
"core-js-pure",
|
|
350
|
+
],
|
|
351
|
+
},
|
|
329
352
|
};
|
|
330
353
|
writeFileSync(resolve(targetDir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|
|
354
|
+
|
|
355
|
+
// .npmrc — keep peer-deps lenient and hoist esbuild's platform binaries so
|
|
356
|
+
// its postinstall version check resolves the correct one across nested
|
|
357
|
+
// dependency trees.
|
|
358
|
+
writeFileSync(
|
|
359
|
+
resolve(targetDir, ".npmrc"),
|
|
360
|
+
[
|
|
361
|
+
"auto-install-peers=true",
|
|
362
|
+
"strict-peer-dependencies=false",
|
|
363
|
+
"public-hoist-pattern[]=*esbuild*",
|
|
364
|
+
"public-hoist-pattern[]=*types*",
|
|
365
|
+
"shell-emulator=true",
|
|
366
|
+
"",
|
|
367
|
+
].join("\n"),
|
|
368
|
+
);
|
|
331
369
|
}
|
|
332
370
|
|
|
333
371
|
function writePnpmWorkspace(targetDir) {
|
|
@@ -540,6 +578,20 @@ export default config;
|
|
|
540
578
|
resolve(dir, ".gitignore"),
|
|
541
579
|
["node_modules", ".next", "dist", ".env.local", ""].join("\n"),
|
|
542
580
|
);
|
|
581
|
+
|
|
582
|
+
// Vercel project config for the frontend. Skip cron + region pinning is
|
|
583
|
+
// optional; configure Root Directory + "Include all submodules" in the
|
|
584
|
+
// Vercel UI when linking the project.
|
|
585
|
+
const vercelJson = {
|
|
586
|
+
$schema: "https://openapi.vercel.sh/vercel.json",
|
|
587
|
+
regions: ["sin1"],
|
|
588
|
+
};
|
|
589
|
+
writeFileSync(resolve(dir, "vercel.json"), JSON.stringify(vercelJson, null, 2) + "\n");
|
|
590
|
+
|
|
591
|
+
writeFileSync(
|
|
592
|
+
resolve(dir, ".vercelignore"),
|
|
593
|
+
["node_modules", ".next", ".env.local", ""].join("\n"),
|
|
594
|
+
);
|
|
543
595
|
}
|
|
544
596
|
|
|
545
597
|
function writeReadme(targetDir, dirName, frontendName, assetPrefix) {
|
|
@@ -629,6 +681,71 @@ Do **not** edit files inside \`apps/backend\`. Open issues / PRs in the
|
|
|
629
681
|
|
|
630
682
|
Shared dev env lives in the root \`.env.local\`. The backend reads its own
|
|
631
683
|
\`apps/backend/.env.local\` (already populated by the installer).
|
|
684
|
+
|
|
685
|
+
## Deploy on Vercel
|
|
686
|
+
|
|
687
|
+
Two Vercel projects, one repo. Each project picks up its own Root Directory.
|
|
688
|
+
|
|
689
|
+
### 1) Backend project
|
|
690
|
+
|
|
691
|
+
- **Import** this repo into Vercel as a new project.
|
|
692
|
+
- **Root Directory**: \`apps/backend\`
|
|
693
|
+
- **Build Command**: \`cd ../.. && pnpm install --frozen-lockfile && pnpm --filter ./apps/backend build\`
|
|
694
|
+
- **Install Command**: leave empty (handled in build)
|
|
695
|
+
- **Settings → Git → Include all submodules: ON** (Vercel checks out an empty \`apps/backend\` otherwise)
|
|
696
|
+
- **Environment variables**:
|
|
697
|
+
\`\`\`
|
|
698
|
+
DATABASE_URL=postgresql://…
|
|
699
|
+
APOLLO_SECRET=<openssl rand -hex 32>
|
|
700
|
+
NEXT_PUBLIC_SITE_URL=https://yourdomain.com # the PUBLIC origin
|
|
701
|
+
NEXT_PUBLIC_DEFAULT_LOCALE=en
|
|
702
|
+
${singleOrigin ? `APOLLO_ASSET_PREFIX=${assetPrefix}` : "# APOLLO_ASSET_PREFIX=/cms-assets # only when single-origin"}
|
|
703
|
+
CRON_SECRET=<random> # protects /api/cron
|
|
704
|
+
# Storage on Vercel cannot use local FS — pick one:
|
|
705
|
+
# Vercel Blob: BLOB_READ_WRITE_TOKEN=…
|
|
706
|
+
# S3 / R2 / Spaces: S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_BUCKET, S3_REGION, S3_ENDPOINT
|
|
707
|
+
APOLLO_DISABLE_LOCAL_STORAGE=1
|
|
708
|
+
\`\`\`
|
|
709
|
+
- **Cron**: \`apps/backend/vercel.json\` declares \`/api/cron\` on a 5-minute schedule (from apollo-cms upstream).
|
|
710
|
+
|
|
711
|
+
### 2) Frontend project
|
|
712
|
+
|
|
713
|
+
- **Import the same repo** as a separate Vercel project.
|
|
714
|
+
- **Root Directory**: \`apps/frontend\`
|
|
715
|
+
- **Build Command**: \`cd ../.. && pnpm install --frozen-lockfile && pnpm --filter ./apps/frontend build\`
|
|
716
|
+
- **Install Command**: leave empty
|
|
717
|
+
- **Settings → Git → Include all submodules: ON**
|
|
718
|
+
- **Environment variables**:
|
|
719
|
+
\`\`\`
|
|
720
|
+
NEXT_PUBLIC_SITE_URL=https://yourdomain.com
|
|
721
|
+
${singleOrigin
|
|
722
|
+
? ` BACKEND_INTERNAL_URL=https://<your-backend>.vercel.app\n NEXT_PUBLIC_APOLLO_ASSET_PREFIX=${assetPrefix}`
|
|
723
|
+
: ` NEXT_PUBLIC_BACKEND_URL=https://<your-backend>.vercel.app`
|
|
724
|
+
}
|
|
725
|
+
\`\`\`
|
|
726
|
+
|
|
727
|
+
### 3) Custom domain
|
|
728
|
+
|
|
729
|
+
Attach \`yourdomain.com\` to the **frontend** project${singleOrigin ? " (in single-origin mode it's the public entry point)" : ""}. The backend stays on its \`*.vercel.app\` URL${singleOrigin ? " — that's what the rewrite proxies to" : ""}.
|
|
730
|
+
|
|
731
|
+
### 4) Skip duplicate builds (optional)
|
|
732
|
+
|
|
733
|
+
Each push triggers both projects to rebuild. Add an **Ignored Build Step** in
|
|
734
|
+
each project's Settings → Git:
|
|
735
|
+
|
|
736
|
+
- **Backend**: \`git diff HEAD^ HEAD --quiet -- apps/backend\` (exits 0 → skip build)
|
|
737
|
+
- **Frontend**: \`git diff HEAD^ HEAD --quiet -- apps/frontend\`
|
|
738
|
+
|
|
739
|
+
### Gotchas
|
|
740
|
+
|
|
741
|
+
- **Submodule must be initialized** on Vercel — the "Include all submodules"
|
|
742
|
+
toggle is the most common reason builds fail with a missing \`apps/backend\`.
|
|
743
|
+
- **OAuth callbacks** for email providers must use the public domain:
|
|
744
|
+
\`https://yourdomain.com/api/email/oauth/callback\`.${singleOrigin ? " The frontend rewrite forwards it to the backend." : ""}
|
|
745
|
+
- **Cron** runs on the backend project only. Vercel sends \`Authorization:
|
|
746
|
+
Bearer $CRON_SECRET\` automatically when \`CRON_SECRET\` is set.${singleOrigin ? `
|
|
747
|
+
- **Better Auth** uses \`trustedProxyHeaders: true\` so the rewrite proxy's
|
|
748
|
+
\`x-forwarded-host\` lands cookies at the public origin without extra config.` : ""}
|
|
632
749
|
`;
|
|
633
750
|
writeFileSync(resolve(targetDir, "README.md"), readme);
|
|
634
751
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-apollo-monorepo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Scaffold a monorepo with a frontend app and Apollo CMS as a git submodule backend (single-origin via Next.js rewrites + assetPrefix)",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-apollo-monorepo": "index.mjs"
|