create-bubbles 0.1.27 → 0.1.28
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/dist/index.js +4 -4
- package/package.json +10 -2
- package/template-pnpm-vp-monorepo/.changeset/README.md +8 -0
- package/template-pnpm-vp-monorepo/.changeset/config.json +11 -0
- package/template-pnpm-vp-monorepo/.gitattributes +5 -0
- package/template-pnpm-vp-monorepo/.github/workflows/ci.yml +33 -0
- package/template-pnpm-vp-monorepo/.github/workflows/docs.yml +55 -0
- package/template-pnpm-vp-monorepo/.github/workflows/release.yml +54 -0
- package/template-pnpm-vp-monorepo/.vite-hooks/commit-msg +1 -0
- package/template-pnpm-vp-monorepo/.vite-hooks/pre-commit +1 -0
- package/template-pnpm-vp-monorepo/.vite-hooks/run.mjs +17 -0
- package/template-pnpm-vp-monorepo/.vscode/settings.json +23 -0
- package/{LICENSE → template-pnpm-vp-monorepo/LICENSE} +2 -2
- package/template-pnpm-vp-monorepo/README.md +93 -0
- package/template-pnpm-vp-monorepo/_gitignore +43 -0
- package/template-pnpm-vp-monorepo/apps/docs/.vitepress/config.mts +69 -0
- package/template-pnpm-vp-monorepo/apps/docs/guide/getting-started.md +70 -0
- package/template-pnpm-vp-monorepo/apps/docs/guide/release.md +73 -0
- package/template-pnpm-vp-monorepo/apps/docs/guide/workspace.md +84 -0
- package/template-pnpm-vp-monorepo/apps/docs/index.md +22 -0
- package/template-pnpm-vp-monorepo/apps/docs/package.json +23 -0
- package/template-pnpm-vp-monorepo/apps/docs/tsconfig.json +7 -0
- package/template-pnpm-vp-monorepo/apps/docs/vite.config.ts +12 -0
- package/template-pnpm-vp-monorepo/apps/playground/index.html +14 -0
- package/template-pnpm-vp-monorepo/apps/playground/package.json +24 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/App.vue +214 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/env.d.ts +6 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/main.ts +6 -0
- package/template-pnpm-vp-monorepo/apps/playground/src/style.css +728 -0
- package/template-pnpm-vp-monorepo/apps/playground/tsconfig.json +10 -0
- package/template-pnpm-vp-monorepo/apps/playground/vite.config.ts +29 -0
- package/template-pnpm-vp-monorepo/commitlint.config.mjs +3 -0
- package/template-pnpm-vp-monorepo/eslint.config.mjs +22 -0
- package/template-pnpm-vp-monorepo/mise.toml +3 -0
- package/template-pnpm-vp-monorepo/package.json +40 -0
- package/template-pnpm-vp-monorepo/packages/utils/LICENSE +21 -0
- package/template-pnpm-vp-monorepo/packages/utils/README.md +26 -0
- package/template-pnpm-vp-monorepo/packages/utils/_gitignore +4 -0
- package/template-pnpm-vp-monorepo/packages/utils/package.json +42 -0
- package/template-pnpm-vp-monorepo/packages/utils/scripts/verify-package.mjs +127 -0
- package/template-pnpm-vp-monorepo/packages/utils/src/index.ts +12 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/consumer/commonjs.cts +20 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/consumer/esm.mts +20 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/consumer/tsconfig.json +10 -0
- package/template-pnpm-vp-monorepo/packages/utils/tests/index.test.ts +30 -0
- package/template-pnpm-vp-monorepo/packages/utils/tsconfig.json +4 -0
- package/template-pnpm-vp-monorepo/packages/utils/vite.config.ts +20 -0
- package/template-pnpm-vp-monorepo/pnpm-workspace.yaml +27 -0
- package/template-pnpm-vp-monorepo/tsconfig/base.json +22 -0
- package/template-pnpm-vp-monorepo/tsconfig/node.json +8 -0
- package/template-pnpm-vp-monorepo/tsconfig/vue.json +7 -0
- package/template-pnpm-vp-monorepo/tsconfig.json +4 -0
- package/template-pnpm-vp-monorepo/vite.config.ts +38 -0
- package/template-vp-monorepo-react-nestjs/.spaces/01./344/274/201/344/270/232/347/272/247/351/241/271/347/233/256/347/272/247//346/235/203/351/231/220/344/270/216/350/217/234/345/215/225//346/212/200/346/234/257/345/245/221/347/272/246.md +5 -3
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//344/272/244/344/273/230/350/256/260/345/275/225.md +9 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//345/217/221/345/270/203/350/257/204/344/274/260.md +93 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//345/267/245/345/205/267//350/277/220/350/241/214/346/227/266/345/217/221/345/270/203/346/243/200/346/237/245.mjs +340 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/346/212/245/345/221/212.md +28 -6
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/catalog/en_US.json +4 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/i18n.config.mjs +9 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/report.json +16 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/comment-clean/source/app.ts +2 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/empty-scan/catalog/en_US.json +4 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/empty-scan/i18n.config.mjs +9 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/empty-scan/report.json +19 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214/output.json +84 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214//345/275/223/345/211/215/345/244/215/351/252/214.json +86 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214//346/243/200/346/237/245/347/273/223/346/236/234.json +30 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256/cli-/346/211/253/346/217/217/350/276/271/347/225/214//346/263/250/351/207/212/345/233/236/345/275/222.json +40 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203/bubblesjs-i18n-core-0.0.0.tgz +0 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203/bubblesjs-i18n-react-0.0.0.tgz +0 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203/bubblesjs-i18n-vue-0.0.1.tgz +0 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203//344/272/247/347/211/251/345/244/215/351/252/214.json +419 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//345/214/205/345/217/221/345/270/203//346/243/200/346/237/245/347/273/223/346/236/234.json +339 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//346/265/213/350/257/225/350/257/201/346/215/256//350/277/220/350/241/214/346/227/266/345/217/221/345/270/203/346/243/200/346/237/245.json +131 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//350/256/276/350/256/241/346/226/271/346/241/210.md +19 -0
- package/template-vp-monorepo-react-nestjs/.spaces/04./347/225/214/351/235/242/344/270/216/344/270/273/351/242/230//345/233/275/351/231/205/345/214/226//351/234/200/346/261/202/346/226/207/346/241/243.md +21 -3
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/274/232/350/257/235/347/256/241/347/220/206//346/212/200/346/234/257/345/245/221/347/272/246.md +5 -2
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/274/232/350/257/235/347/256/241/347/220/206//351/234/200/346/261/202/346/226/207/346/241/243.md +4 -3
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201/PRD.md +2 -1
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//346/212/200/346/234/257/345/245/221/347/272/246.md +3 -2
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//346/265/213/350/257/225/346/212/245/345/221/212.md +15 -12
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//350/201/224/350/260/203/350/256/260/345/275/225.md +6 -5
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//350/256/276/350/256/241/346/226/271/346/241/210.md +2 -1
- package/template-vp-monorepo-react-nestjs/.spaces/06./350/256/244/350/257/201/344/270/216/344/274/232/350/257/235//344/277/256/346/224/271/345/257/206/347/240/201//351/234/200/346/261/202/346/226/207/346/241/243.md +4 -3
- package/template-vp-monorepo-react-nestjs/.spaces/README.md +3 -2
- package/template-vp-monorepo-react-nestjs/apps/web/test/{password-actions.spec.ts → password/password-actions.spec.ts} +3 -3
- package/template-vp-monorepo-react-nestjs/apps/web/test/{password-reset-action.spec.ts → password/password-reset-action.spec.ts} +4 -2
- package/template-vp-monorepo-react-nestjs/apps/web/test/{workspaces-password-entry.spec.tsx → password/workspaces-password-entry.spec.tsx} +7 -7
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/README.md +2 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.test.ts +88 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/src/scanner.ts +34 -11
- package/template-vp-monorepo-react-nestjs/packages/i18n/cli/test/command.test.ts +36 -0
- package/template-vp-monorepo-react-nestjs/packages/i18n/react/src/use-store.ts +15 -5
- package/template-vp-monorepo-react-nestjs/tsconfig.lib.json +1 -1
- package/template-vp-react/package.json +5 -5
- package/template-vp-vue-eslint-vapor/.vscode/settings.json +53 -0
- package/template-vp-vue-eslint-vapor/package.json +1 -0
- package/template-vp-vue-eslint-vapor/pnpm-workspace.yaml +0 -24
- package/template-vp-vue-eslint-vapor/src/main.ts +2 -3
- package/template-vp-vue-eslint-vapor/vite.config.ts +26 -31
- package/template-vp-react/.vscode/settings.json +0 -18
- /package/{template-vp-vue-eslint-vapor → template-pnpm-vp-monorepo}/.vscode/extensions.json +0 -0
- /package/template-vp-monorepo-react-nestjs/apps/server/test/auth/{password-operations.spec.ts → password/password-operations.spec.ts} +0 -0
- /package/template-vp-monorepo-react-nestjs/apps/server/test/auth/{password.integration.spec.ts → password/password.integration.spec.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import e from"node:fs";import t from"node:path";import{fileURLToPath as n}from"node:url";import*as r from"@clack/prompts";import i from"cross-spawn";import a from"gradient-string";import o from"mri";const s={vue:a([`#42B883`,`#42B883`]),react:a([`#087EA4`,`#087EA4`]),taro:a([`#0000C2`,`#fff`]),nextjs:a([`#000`,`#fff`]),others:a([`#8B5CF6`,`#A855F7`])},c=o(process.argv.slice(2),{alias:{h:`help`,t:`template`},boolean:[`help`,`overwrite`],string:[`template`]}),l=process.cwd(),u=e=>e.trim().replace(/\/+$/g,``),d=e=>{if(!e)return;let t=e.split(` `)[0].split(`/`);return{name:t[0],version:t[1]}},f=t=>{let n=e.readdirSync(t);return n.length===0||n.length===1&&n[0]===`.git`},p=async n=>{await Promise.all(e.readdirSync(n).filter(e=>e!==`.git`).map(r=>e.promises.rm(t.resolve(n,r),{recursive:!0,force:!0})))},m=e=>/^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(e),h=e=>e.trim().toLowerCase().replace(/\s+/g,`-`).replace(/^[._]/,``).replace(/[^a-z\d\-~]+g/,`-`),g=[{name:`vue`,display:`Vue`,color:s.vue,variants:[{name:`vue-vp-eslint`,display:`vp + eslint`,color:s.vue},{name:`vp-vue-eslint-vapor`,display:`vp + eslint + vapor`,color:s.vue}]},{name:`react`,display:`React`,color:s.react,variants:[{name:`react-rsbuild-biome`,display:`rsbuild-biome`,color:s.react},{name:`vp-react`,display:`vp-react`,color:s.react},{name:`vp-react-shadcn`,display:`vp-react-shadcn`,color:s.react},{name:`vp-monorepo-react-nestjs`,display:`vp-monorepo-react-nestjs`,color:s.react},{name:`vp-monorepo-react-hono`,display:`vp-monorepo-react-hono`,color:s.react}]},{name:`taro`,display:`Taro`,color:s.taro,variants:[{name:`taro-vue-eslint`,display:`taro-vue + eslint`,color:s.taro},{name:`taro-react-oxc`,display:`taro-react + oxc`,color:s.taro}]},{name:`nextjs`,display:`NextJS`,color:s.nextjs,variants:[{name:`nextjs-vinext-eslint`,display:`nextjs + vinext + eslint`,color:s.nextjs}]},{name:`others`,display:`Others`,color:s.others,variants:[{name:`create-eletron-vite`,display:`Electron ↗`,color:s.others,customCommand:`pnpm create electron-vite@latest TARGET_DIR`}]}],_=g.map(e=>e.variants.map(e=>`${e.name}`)).reduce((e,t)=>e.concat(t),[]),v=`\
|
|
1
|
+
import e from"node:fs";import t from"node:path";import{fileURLToPath as n}from"node:url";import*as r from"@clack/prompts";import i from"cross-spawn";import a from"gradient-string";import o from"mri";const s={vue:a([`#42B883`,`#42B883`]),react:a([`#087EA4`,`#087EA4`]),monorepo:a([`#F59E0B`,`#FBBF24`]),taro:a([`#0000C2`,`#fff`]),nextjs:a([`#000`,`#fff`]),others:a([`#8B5CF6`,`#A855F7`])},c=o(process.argv.slice(2),{alias:{h:`help`,t:`template`},boolean:[`help`,`overwrite`],string:[`template`]}),l=process.cwd(),u=e=>e.trim().replace(/\/+$/g,``),d=e=>{if(!e)return;let t=e.split(` `)[0].split(`/`);return{name:t[0],version:t[1]}},f=t=>{let n=e.readdirSync(t);return n.length===0||n.length===1&&n[0]===`.git`},p=async n=>{await Promise.all(e.readdirSync(n).filter(e=>e!==`.git`).map(r=>e.promises.rm(t.resolve(n,r),{recursive:!0,force:!0})))},m=e=>/^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(e),h=e=>e.trim().toLowerCase().replace(/\s+/g,`-`).replace(/^[._]/,``).replace(/[^a-z\d\-~]+g/,`-`),g=[{name:`vue`,display:`Vue`,color:s.vue,variants:[{name:`vue-vp-eslint`,display:`vp + eslint`,color:s.vue},{name:`vp-vue-eslint-vapor`,display:`vp + eslint + vapor`,color:s.vue}]},{name:`react`,display:`React`,color:s.react,variants:[{name:`react-rsbuild-biome`,display:`rsbuild-biome`,color:s.react},{name:`vp-react`,display:`vp-react`,color:s.react},{name:`vp-react-shadcn`,display:`vp-react-shadcn`,color:s.react},{name:`vp-monorepo-react-nestjs`,display:`vp-monorepo-react-nestjs`,color:s.react},{name:`vp-monorepo-react-hono`,display:`vp-monorepo-react-hono`,color:s.react}]},{name:`monorepo`,display:`Monorepo`,color:s.monorepo,variants:[{name:`pnpm-vp-monorepo`,display:`pnpm + vp monorepo`,color:s.monorepo}]},{name:`taro`,display:`Taro`,color:s.taro,variants:[{name:`taro-vue-eslint`,display:`taro-vue + eslint`,color:s.taro},{name:`taro-react-oxc`,display:`taro-react + oxc`,color:s.taro}]},{name:`nextjs`,display:`NextJS`,color:s.nextjs,variants:[{name:`nextjs-vinext-eslint`,display:`nextjs + vinext + eslint`,color:s.nextjs}]},{name:`others`,display:`Others`,color:s.others,variants:[{name:`create-eletron-vite`,display:`Electron ↗`,color:s.others,customCommand:`pnpm create electron-vite@latest TARGET_DIR`}]}],_=g.map(e=>e.variants.map(e=>`${e.name}`)).reduce((e,t)=>e.concat(t),[]),v=`\
|
|
2
2
|
Usage: create-bubbles [OPTION]... [DIRECTORY]
|
|
3
3
|
|
|
4
4
|
Create a new Bubbles project in JavaScript or TypeScript.
|
|
@@ -9,7 +9,7 @@ Options:
|
|
|
9
9
|
|
|
10
10
|
Available templates:
|
|
11
11
|
${g.flatMap(e=>e.variants.map(t=>t.color(`${t.name.padEnd(28)}${e.name}`))).join(`
|
|
12
|
-
`)}`,y=(e,t)=>{console.log(`💦customCommand`,e,t);let n=t?t.name:`npm`,r=n===`yarn`&&t?.version.startsWith(`1.`);return e.replace(/^npm create (?:-- )?/,()=>n===`bun`?`bun x create-`:n===`pnpm`?`pnpm create `:e.startsWith(`npm create -- `)?`${n} create -- `:`${n} create `).replace(`@latest`,()=>r?``:`@latest`).replace(/^npm exec/,()=>n===`pnpm`?`pnpm dlx`:n===`yarn`&&!r?`yarn dlx`:n===`bun`?`bun x`:`npm exec`)},b={_gitignore:`.gitignore`},x=(n,r)=>{e.mkdirSync(r,{recursive:!0});for(let i of e.readdirSync(n)){let e=t.resolve(n,i),a=t.resolve(r,i);S(e,a)}},S=(t,n)=>{e.statSync(t).isDirectory()?x(t,n):e.copyFileSync(t,n)},C=(t,n)=>{let r=e.readFileSync(t,`utf-8`);e.writeFileSync(t,n(r),`utf-8`)},w=(e,n)=>{C(t.resolve(e,`package.json`),e=>e.replace(/"@vitejs\/plugin-react": ".+?"/,`"@vitejs/plugin-react-swc": "^4.0.1"`)),C(t.resolve(e,`vite.config.${n?`ts`:`js`}`),e=>e.replace(`@vitejs/plugin-react`,`@vitejs/plugin-react-swc`))};(async()=>{console.log(c);let o=c._[0]?u(c._[0]):void 0,x=c.template,C=c.overwrite,T=`bubbles-project`;if(c.help){console.log(v);return}let E=d(process.env.npm_config_user_agent),D=()=>r.cancel(`Operation cancelled`),O=o;if(!O){let e=await r.text({message:`Project name`,defaultValue:T,placeholder:T,validate:e=>(e||[]).length===0||u(e||``).length>0?void 0:`Invalid project name`});if(r.isCancel(e))return D();O=u(e)}if(e.existsSync(O)&&!f(O)){let e=C?`yes`:await r.select({message:O===`.`?`Current directory`:`Target directory "${O}" is not empty. Please choose how to proceed:`,options:[{label:`${s.vue(`Cancel operation`)}`,value:`no`},{label:`Remove existing files and continue`,value:`yes`},{label:`Ignore files and continue`,value:`ignore`}]});if(r.isCancel(e))return D();switch(e){case`yes`:p(O);break;case`no`:D();return}}let k=t.basename(t.resolve(O));if(!m(k)){let e=await r.text({message:`Package name is invalid. please input again:`,defaultValue:h(k),placeholder:h(k),validate(e){if(!m(e))return`Invalid package.json name`}});if(r.isCancel(e))return D();k=e}let A=x,j=!1;if(x&&!_.includes(x)&&(A=void 0,j=!0),!A){let e=await r.select({message:j?`"${x}" isn't a valia template. please choose from below:`:`Select a framework`,options:g.map(e=>{let t=e.color;return{label:t(e.display),value:e}})});if(r.isCancel(e))return D();console.log(`💦pkgInfo`,E);let t=await r.select({message:`Select a variant:`,options:e.variants.map(e=>{let t=e.color,n=e.customCommand?y(e.customCommand,E).replace(/ TARGET_DIR$/,``):void 0;return{label:t(e.display||e.name),value:e.name,hint:n}})});if(r.isCancel(t))return D();A=t}let M=t.
|
|
13
|
-
`,M!==l&&(B+=`\n cd ${V.includes(` `)?`"${V}"`:V} `)
|
|
12
|
+
`)}`,y=(e,t)=>{console.log(`💦customCommand`,e,t);let n=t?t.name:`npm`,r=n===`yarn`&&t?.version.startsWith(`1.`);return e.replace(/^npm create (?:-- )?/,()=>n===`bun`?`bun x create-`:n===`pnpm`?`pnpm create `:e.startsWith(`npm create -- `)?`${n} create -- `:`${n} create `).replace(`@latest`,()=>r?``:`@latest`).replace(/^npm exec/,()=>n===`pnpm`?`pnpm dlx`:n===`yarn`&&!r?`yarn dlx`:n===`bun`?`bun x`:`npm exec`)},b={_gitignore:`.gitignore`},x=(n,r)=>{e.mkdirSync(r,{recursive:!0});for(let i of e.readdirSync(n)){let e=t.resolve(n,i),a=t.resolve(r,b[i]??i);S(e,a)}},S=(t,n)=>{e.statSync(t).isDirectory()?x(t,n):e.copyFileSync(t,n)},C=(t,n)=>{let r=e.readFileSync(t,`utf-8`);e.writeFileSync(t,n(r),`utf-8`)},w=(e,n)=>{C(t.resolve(e,`package.json`),e=>e.replace(/"@vitejs\/plugin-react": ".+?"/,`"@vitejs/plugin-react-swc": "^4.0.1"`)),C(t.resolve(e,`vite.config.${n?`ts`:`js`}`),e=>e.replace(`@vitejs/plugin-react`,`@vitejs/plugin-react-swc`))};(async()=>{console.log(c);let o=c._[0]?u(c._[0]):void 0,x=c.template,C=c.overwrite,T=`bubbles-project`;if(c.help){console.log(v);return}let E=d(process.env.npm_config_user_agent),D=()=>r.cancel(`Operation cancelled`),O=o;if(!O){let e=await r.text({message:`Project name`,defaultValue:T,placeholder:T,validate:e=>(e||[]).length===0||u(e||``).length>0?void 0:`Invalid project name`});if(r.isCancel(e))return D();O=u(e)}if(e.existsSync(O)&&!f(O)){let e=C?`yes`:await r.select({message:O===`.`?`Current directory`:`Target directory "${O}" is not empty. Please choose how to proceed:`,options:[{label:`${s.vue(`Cancel operation`)}`,value:`no`},{label:`Remove existing files and continue`,value:`yes`},{label:`Ignore files and continue`,value:`ignore`}]});if(r.isCancel(e))return D();switch(e){case`yes`:p(O);break;case`no`:D();return}}let k=t.basename(t.resolve(O));if(!m(k)){let e=await r.text({message:`Package name is invalid. please input again:`,defaultValue:h(k),placeholder:h(k),validate(e){if(!m(e))return`Invalid package.json name`}});if(r.isCancel(e))return D();k=e}let A=x,j=!1;if(x&&!_.includes(x)&&(A=void 0,j=!0),!A){let e=await r.select({message:j?`"${x}" isn't a valia template. please choose from below:`:`Select a framework or project type`,options:g.map(e=>{let t=e.color;return{label:t(e.display),value:e}})});if(r.isCancel(e))return D();console.log(`💦pkgInfo`,E);let t=await r.select({message:`Select a variant:`,options:e.variants.map(e=>{let t=e.color,n=e.customCommand?y(e.customCommand,E).replace(/ TARGET_DIR$/,``):void 0;return{label:t(e.display||e.name),value:e.name,hint:n}})});if(r.isCancel(t))return D();A=t}let M=t.resolve(l,O);e.mkdirSync(M,{recursive:!0});let N=!1;A.includes(`-swc`)&&(N=!0,A=A.replace(`-swc`,``));let P=E?E.name:`npm`,{customCommand:F}=g.flatMap(e=>e.variants).find(e=>e.name===A)??{};if(F){let[e,...t]=y(F,E).split(` `),n=t.map(e=>e.replace(`TARGET_DIR`,()=>O));console.log(`💦replacedArgs`,n);let{status:r}=i.sync(e,n,{stdio:`inherit`});process.exit(r??0)}r.log.step(`scaffolding project in ${M}...`);let I=t.resolve(n(import.meta.url),`../..`,`template-${A}`),L=(n,r)=>{let i=t.join(M,b[n]??n);r?e.writeFileSync(i,r):S(t.join(I,n),i)},R=e.readdirSync(I);for(let e of R)e!==`package.json`&&L(e);let z=JSON.parse(e.readFileSync(t.join(I,`package.json`),`utf-8`));z.name=k,L(`package.json`,`${JSON.stringify(z,null,2)}\n`),N&&w(M,A.endsWith(`-ts`));let B=``,V=t.relative(l,M);console.log(`💦cwd`,l),console.log(`💦root`,M),console.log(`💦cdProjectName`,V),B+=`Done. Now run:
|
|
13
|
+
`,M!==l&&(B+=`\n cd ${V.includes(` `)?`"${V}"`:V} `);let H=A===`pnpm-vp-monorepo`?`pnpm`:P;switch(H){case`yarn`:B+=`
|
|
14
14
|
yarn`,B+=`
|
|
15
|
-
yarn dev`;break;default:B+=a([`pink`,`white`])(`\n ${
|
|
15
|
+
yarn dev`;break;default:B+=a([`pink`,`white`])(`\n ${H} install`),B+=a([`pink`,`white`])(`\n ${H} run dev`);break}r.outro(B)})().catch(e=>{console.error(`💦`,e)});export{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-bubbles",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"homepage": "https://github.com/435012357/bubblesjs/tree/master/packages/create-bubbles#readme",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/435012357/bubblesjs/issues"
|
|
@@ -20,7 +20,15 @@
|
|
|
20
20
|
"index.js",
|
|
21
21
|
"template-*",
|
|
22
22
|
"dist",
|
|
23
|
-
"template-*/**"
|
|
23
|
+
"template-*/**",
|
|
24
|
+
"!template-pnpm-vp-monorepo/**/node_modules/**",
|
|
25
|
+
"!template-pnpm-vp-monorepo/**/dist/**",
|
|
26
|
+
"!template-pnpm-vp-monorepo/**/coverage/**",
|
|
27
|
+
"!template-pnpm-vp-monorepo/**/.vite/**",
|
|
28
|
+
"!template-pnpm-vp-monorepo/**/.vitepress/cache/**",
|
|
29
|
+
"!template-pnpm-vp-monorepo/.vite-hooks/_/**",
|
|
30
|
+
"!template-pnpm-vp-monorepo/**/*.tsbuildinfo",
|
|
31
|
+
"!template-pnpm-vp-monorepo/**/*.tgz"
|
|
24
32
|
],
|
|
25
33
|
"type": "module",
|
|
26
34
|
"publishConfig": {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changesets
|
|
2
|
+
|
|
3
|
+
根项目、`docs`、`playground` 和 `@bubblesjs/utils` 均为 `private: true`,目前没有 npm 发布对象。根目录 `tsconfig/` 是普通配置目录,不作为工作区包,也不参与版本与发布。
|
|
4
|
+
|
|
5
|
+
以下流程保留给将来新增的公开包:修改公开包后运行 `pnpm changeset`,选择包、版本类型并填写变更说明。
|
|
6
|
+
|
|
7
|
+
合并变更后运行 `pnpm version-packages` 更新版本和锁文件;运行 `pnpm release` 发布。
|
|
8
|
+
将来的公开包默认使用 `@bubblesjs/<名称>`,例如 `@bubblesjs/math`。若复制 utils 作为公开包,须显式移除 `private: true`,设置 `publishConfig.access` 为 `public` 并完善发布元信息,确认 npm 账户拥有 `@bubblesjs` scope 或对应组织的包发布权限;只有更换 scope 时才同步替换包名与引用。完整步骤见 `apps/docs/guide/release.md`。
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
|
|
3
|
+
"changelog": "@changesets/cli/changelog",
|
|
4
|
+
"commit": false,
|
|
5
|
+
"fixed": [],
|
|
6
|
+
"linked": [],
|
|
7
|
+
"access": "public",
|
|
8
|
+
"baseBranch": "main",
|
|
9
|
+
"updateInternalDependencies": "patch",
|
|
10
|
+
"ignore": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
quality:
|
|
17
|
+
name: Check and build (${{ matrix.os }})
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
os: [ubuntu-latest, windows-latest]
|
|
21
|
+
runs-on: ${{ matrix.os }}
|
|
22
|
+
timeout-minutes: 20
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: pnpm/action-setup@v4
|
|
26
|
+
with:
|
|
27
|
+
run_install: false
|
|
28
|
+
- uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version-file: .node-version
|
|
31
|
+
cache: pnpm
|
|
32
|
+
- run: pnpm install --frozen-lockfile
|
|
33
|
+
- run: pnpm ready
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Deploy docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
concurrency:
|
|
7
|
+
group: pages
|
|
8
|
+
cancel-in-progress: false
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
pages: write
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 15
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- uses: pnpm/action-setup@v4
|
|
22
|
+
with:
|
|
23
|
+
run_install: false
|
|
24
|
+
- uses: actions/setup-node@v4
|
|
25
|
+
with:
|
|
26
|
+
node-version-file: .node-version
|
|
27
|
+
cache: pnpm
|
|
28
|
+
- run: pnpm install --frozen-lockfile
|
|
29
|
+
- name: Resolve GitHub Pages base
|
|
30
|
+
shell: bash
|
|
31
|
+
env:
|
|
32
|
+
REPOSITORY: ${{ github.repository }}
|
|
33
|
+
run: |
|
|
34
|
+
owner_name="${REPOSITORY%%/*}"
|
|
35
|
+
repository_name="${REPOSITORY#*/}"
|
|
36
|
+
if [[ "${repository_name,,}" == "${owner_name,,}.github.io" ]]; then
|
|
37
|
+
echo "DOCS_BASE=/" >> "$GITHUB_ENV"
|
|
38
|
+
else
|
|
39
|
+
echo "DOCS_BASE=/$repository_name/" >> "$GITHUB_ENV"
|
|
40
|
+
fi
|
|
41
|
+
- run: pnpm docs:build
|
|
42
|
+
- uses: actions/configure-pages@v5
|
|
43
|
+
- uses: actions/upload-pages-artifact@v3
|
|
44
|
+
with:
|
|
45
|
+
path: apps/docs/.vitepress/dist
|
|
46
|
+
deploy:
|
|
47
|
+
needs: build
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
environment:
|
|
50
|
+
name: github-pages
|
|
51
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
52
|
+
steps:
|
|
53
|
+
- name: Deploy to GitHub Pages
|
|
54
|
+
id: deployment
|
|
55
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
concurrency:
|
|
7
|
+
group: release-main
|
|
8
|
+
cancel-in-progress: false
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: write
|
|
12
|
+
pull-requests: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
release:
|
|
16
|
+
if: github.ref == 'refs/heads/main' && vars.RELEASE_ENABLED == 'true'
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 20
|
|
19
|
+
env:
|
|
20
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
with:
|
|
24
|
+
fetch-depth: 0
|
|
25
|
+
- uses: pnpm/action-setup@v4
|
|
26
|
+
with:
|
|
27
|
+
run_install: false
|
|
28
|
+
- uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version-file: .node-version
|
|
31
|
+
cache: pnpm
|
|
32
|
+
registry-url: https://registry.npmjs.org
|
|
33
|
+
- run: pnpm install --frozen-lockfile
|
|
34
|
+
- run: pnpm ready
|
|
35
|
+
- name: Version packages or publish to npm
|
|
36
|
+
if: env.NPM_TOKEN != ''
|
|
37
|
+
uses: changesets/action@v1
|
|
38
|
+
with:
|
|
39
|
+
publish: pnpm release
|
|
40
|
+
version: pnpm version-packages
|
|
41
|
+
commit: "chore(release): version packages"
|
|
42
|
+
title: "chore(release): version packages"
|
|
43
|
+
env:
|
|
44
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
45
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
46
|
+
- name: Create version PR
|
|
47
|
+
if: env.NPM_TOKEN == ''
|
|
48
|
+
uses: changesets/action@v1
|
|
49
|
+
with:
|
|
50
|
+
version: pnpm version-packages
|
|
51
|
+
commit: "chore(release): version packages"
|
|
52
|
+
title: "chore(release): version packages"
|
|
53
|
+
env:
|
|
54
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node .vite-hooks/run.mjs commitlint --edit "$1"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node .vite-hooks/run.mjs staged
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const [command, ...args] = process.argv.slice(2);
|
|
7
|
+
const commands = {
|
|
8
|
+
staged: [resolve(dirname(require.resolve("vite-plus/package.json")), "bin/vp"), "staged"],
|
|
9
|
+
commitlint: [resolve(dirname(require.resolve("@commitlint/cli/package.json")), "cli.js")],
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
if (!Object.hasOwn(commands, command)) {
|
|
13
|
+
throw new Error(`未知 Git hook 命令: ${command}`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const result = spawnSync(process.execPath, [...commands[command], ...args], { stdio: "inherit" });
|
|
17
|
+
process.exitCode = result.status ?? 1;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"npm.scriptRunner": "vp",
|
|
3
|
+
"editor.defaultFormatter": "oxc.oxc-vscode",
|
|
4
|
+
"[javascript]": {
|
|
5
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
6
|
+
},
|
|
7
|
+
"[javascriptreact]": {
|
|
8
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
9
|
+
},
|
|
10
|
+
"[typescript]": {
|
|
11
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
12
|
+
},
|
|
13
|
+
"[typescriptreact]": {
|
|
14
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
15
|
+
},
|
|
16
|
+
"oxc.disableNestedConfig": true,
|
|
17
|
+
"oxc.fmt.disableNestedConfig": true,
|
|
18
|
+
"editor.formatOnSave": true,
|
|
19
|
+
"editor.formatOnSaveMode": "file",
|
|
20
|
+
"editor.codeActionsOnSave": {
|
|
21
|
+
"source.fixAll.oxc": "explicit"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) [year] [copyright holder]
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Monorepo Template
|
|
2
|
+
|
|
3
|
+
基于 **pnpm workspace + Vite+ + Vue 3 + VitePress + Changesets** 的 monorepo 模板。参考 `antv-next-pro` 的工程结构,提供可运行的应用、文档站和可构建的内部共享 TypeScript 包。
|
|
4
|
+
|
|
5
|
+
根项目、`docs`、`playground` 和 `@bubblesjs/utils` 均为 `private: true`,目前没有 npm 发布对象。`@bubblesjs` scope 同样用于内部包标识;Changesets 与发布流程保留给将来新增的公开包。
|
|
6
|
+
|
|
7
|
+
## 环境与启动
|
|
8
|
+
|
|
9
|
+
通过 create-bubbles 创建项目,在交互菜单中选择 **Monorepo → pnpm + vp monorepo**,或直接指定模板:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm create bubbles my-monorepo -t pnpm-vp-monorepo
|
|
13
|
+
cd my-monorepo
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- Node.js 24(最低 24.11.0;`.node-version` / `mise.toml` 固定 24.21.0)
|
|
17
|
+
- pnpm 12.10.1(`packageManager` 固定版本)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm install
|
|
21
|
+
pnpm dev
|
|
22
|
+
# 另一个终端启动文档
|
|
23
|
+
pnpm docs:dev
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Playground 在 <http://localhost:5173>,文档在 <http://localhost:5174>。Playground 通过源码 alias 消费 `@bubblesjs/utils`,首次开发无需预构建共享包;文档站点独立运行。
|
|
27
|
+
|
|
28
|
+
## 目录结构
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
apps/
|
|
32
|
+
playground/ Vue 3 示例应用,验证共享包的实际使用
|
|
33
|
+
docs/ VitePress 中文文档
|
|
34
|
+
packages/
|
|
35
|
+
utils/ 内部共享工具包,ESM / CJS / 类型声明
|
|
36
|
+
tsconfig/ 共享严格 TypeScript 配置(base / node / vue)
|
|
37
|
+
.changeset/ 版本记录及发布配置
|
|
38
|
+
.github/workflows/ Windows / Linux CI、手动发布及文档部署
|
|
39
|
+
.vite-hooks/ 暂存文件检查、Conventional Commits 校验
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 常用命令
|
|
43
|
+
|
|
44
|
+
| 命令 | 作用 |
|
|
45
|
+
| --------------------------------------------------------- | ---------------------------------------------- |
|
|
46
|
+
| `pnpm dev` / `pnpm preview` | 启动 / 预览 playground |
|
|
47
|
+
| `pnpm docs:dev` / `pnpm docs:build` / `pnpm docs:preview` | 文档开发 / 构建 / 预览 |
|
|
48
|
+
| `pnpm build` | 按工作区依赖顺序构建所有包与应用 |
|
|
49
|
+
| `pnpm test` | 执行共享包单元测试,不进入 watch 模式 |
|
|
50
|
+
| `pnpm typecheck` | 根配置、共享包、Vue 应用及文档的类型检查 |
|
|
51
|
+
| `pnpm lint` | Oxlint 检查 TS/JS,ESLint 检查 Vue SFC |
|
|
52
|
+
| `pnpm format` / `pnpm format:check` | 格式化 / 检查格式 |
|
|
53
|
+
| `pnpm check` | 格式、lint、类型和单元测试 |
|
|
54
|
+
| `pnpm verify:packages` | 本地构建并验证 ESM/CJS、消费类型与打包文件清单 |
|
|
55
|
+
| `pnpm ready` / `pnpm run ci` | 完整检查、全量构建和本地产物验证 |
|
|
56
|
+
| `pnpm changeset` | 为将来公开包记录版本变更 |
|
|
57
|
+
| `pnpm version-packages` | 更新将来公开包的版本、CHANGELOG 和锁文件 |
|
|
58
|
+
| `pnpm release` | 为将来公开包保留的 Changesets npm 发布流程 |
|
|
59
|
+
| `pnpm hooks:install` | 初始化 Git 后手动安装提交检查 hooks |
|
|
60
|
+
|
|
61
|
+
Vite+ 统一提供 dev/build/pack/test/lint/fmt/run。任务缓存由 Vite+ 管理;构建产物验证和聚合质量检查每次实际执行。`pnpm verify:packages` 只检查本地产物,不执行 npm 发布。
|
|
62
|
+
|
|
63
|
+
pnpm 12 的 `pnpm ci` 是清理后安装依赖的内置命令。执行本项目的完整验证请使用 `pnpm ready` 或 `pnpm run ci`。
|
|
64
|
+
|
|
65
|
+
## 复制为新项目
|
|
66
|
+
|
|
67
|
+
1. 复制源码,跳过 `node_modules`、`dist`、`.vitepress/cache`、`.vitepress/dist`。
|
|
68
|
+
2. 修改根 `package.json` 的项目名。内部包默认沿用 `@bubblesjs` scope;只有更换 scope 时,才同步替换包名、`workspace:*` 依赖、alias、TS paths、消费类型示例及文档中的 `@bubblesjs`。
|
|
69
|
+
3. 替换各 `LICENSE` 中的年份和版权人,按需要修改许可证。将来新增公开包时,再填写 `author`、`repository`、`homepage`、`bugs`;发布到 npm 的账户需拥有 `@bubblesjs` scope 或对应组织的包发布权限。
|
|
70
|
+
4. 执行 `pnpm install` 更新锁文件,然后运行 `pnpm ready`。
|
|
71
|
+
5. 如需 Git hooks,先初始化 Git(新仓库可执行 `git init -b main`),再运行 `pnpm hooks:install`。源码压缩包或尚未初始化 Git 的目录也可以正常安装。
|
|
72
|
+
|
|
73
|
+
`pnpm hooks:install` 执行 `vp config --hooks-dir .vite-hooks --no-agent`,手动安装暂存文件检查与 Conventional Commits 校验。`pnpm install` 负责安装依赖,Git hooks 在初始化仓库后按需启用。
|
|
74
|
+
|
|
75
|
+
模板使用 TypeScript 6.x(`^6.0.3`),工作区统一从 catalog 获取版本。升级到 TypeScript 7 前应验证 Volar 的支持情况。VitePress 使用与 Vite 8 兼容的 `2.0.0-alpha.20`,升级时一起验证文档构建。
|
|
76
|
+
|
|
77
|
+
## 扩展工作区
|
|
78
|
+
|
|
79
|
+
新增应用放在 `apps/*`,共享包放在 `packages/*`。每个项目创建独立 `package.json`。内部共享包和应用设为 `private: true`;应用名称可继续使用 `playground`、`docs` 等,无需添加 scope。若将来复制 utils 为公开包,例如 `@bubblesjs/math`,须显式移除 `private: true`,设置 `publishConfig.access` 为 `public` 并完善发布元信息。
|
|
80
|
+
|
|
81
|
+
外部依赖使用 `catalog:`,版本集中维护在 `pnpm-workspace.yaml`;工作区依赖使用 `workspace:*`。复制 `packages/utils` 可得到带测试和双格式导出的共享包;复制 `apps/playground` 可得到 Vue 应用。修改包名后同步更新 import、alias 和消费类型测试。
|
|
82
|
+
|
|
83
|
+
共享 TS 配置放在根目录 `tsconfig/`,通过相对路径 `extends` 使用。Vue 应用使用 `tsconfig/vue.json`,Node / 库使用 `tsconfig/node.json`,它们继承 `tsconfig/base.json`。这是普通配置目录,不包含 `package.json`,也不作为工作区包或依赖。
|
|
84
|
+
|
|
85
|
+
详细说明见 [快速开始](apps/docs/guide/getting-started.md)、[工作区约定](apps/docs/guide/workspace.md) 和 [发布指南](apps/docs/guide/release.md)。
|
|
86
|
+
|
|
87
|
+
## CI、发布与文档部署
|
|
88
|
+
|
|
89
|
+
推送 `main` 或创建 PR 时,CI 在 Linux 和 Windows 上执行 `pnpm ready`,使用与本地一致的 Node 和 pnpm 版本。
|
|
90
|
+
|
|
91
|
+
将来新增公开包后,Release 工作流需先设置仓库变量 `RELEASE_ENABLED=true`,再从 `main` 手动运行。无 `NPM_TOKEN` 时只创建版本 PR,有 token 时支持 npm 发布。仓库需允许 GitHub Actions 创建 PR。首次使用之前完成包名、许可证、仓库元信息和 npm 权限的配置。
|
|
92
|
+
|
|
93
|
+
文档工作流手动运行。将 GitHub Pages 的构建来源设为 **GitHub Actions**,工作流会根据仓库名设置 `DOCS_BASE`。本地默认为 `/`,也可指定部署子路径(例如 PowerShell:`$env:DOCS_BASE = '/my-project/'`,然后 `pnpm docs:build`)。
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
coverage/
|
|
15
|
+
.pnpm-store/
|
|
16
|
+
.vite/
|
|
17
|
+
.vite-hooks/_/
|
|
18
|
+
**/.vitepress/cache/
|
|
19
|
+
**/.vitepress/dist/
|
|
20
|
+
*.tgz
|
|
21
|
+
|
|
22
|
+
# dotenv environment variable files
|
|
23
|
+
.env
|
|
24
|
+
.env.*
|
|
25
|
+
!.env.example
|
|
26
|
+
|
|
27
|
+
# Editor directories and files
|
|
28
|
+
.vscode/*
|
|
29
|
+
!.vscode/settings.json
|
|
30
|
+
!.vscode/extensions.json
|
|
31
|
+
.idea
|
|
32
|
+
.DS_Store
|
|
33
|
+
*.suo
|
|
34
|
+
*.ntvs*
|
|
35
|
+
*.njsproj
|
|
36
|
+
*.sln
|
|
37
|
+
*.sw?
|
|
38
|
+
|
|
39
|
+
# AI agent worktrees
|
|
40
|
+
.claude/worktrees/
|
|
41
|
+
!.vscode/
|
|
42
|
+
!.vscode/settings.json
|
|
43
|
+
!.vscode/extensions.json
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { defineConfig } from "vitepress";
|
|
2
|
+
|
|
3
|
+
const basePath = (process.env.DOCS_BASE ?? "/").trim().replace(/^\/+|\/+$/g, "");
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
title: "Monorepo Starter",
|
|
7
|
+
description: "基于 pnpm、Vue 3 与 Vite+ 的可复用 Monorepo 模板",
|
|
8
|
+
lang: "zh-CN",
|
|
9
|
+
base: basePath ? `/${basePath}/` : "/",
|
|
10
|
+
cleanUrls: true,
|
|
11
|
+
lastUpdated: true,
|
|
12
|
+
markdown: {
|
|
13
|
+
theme: { light: "github-light", dark: "github-dark" },
|
|
14
|
+
},
|
|
15
|
+
themeConfig: {
|
|
16
|
+
nav: [
|
|
17
|
+
{ text: "快速开始", link: "/guide/getting-started" },
|
|
18
|
+
{ text: "工作区约定", link: "/guide/workspace" },
|
|
19
|
+
{ text: "版本与发布", link: "/guide/release" },
|
|
20
|
+
],
|
|
21
|
+
sidebar: {
|
|
22
|
+
"/guide/": [
|
|
23
|
+
{
|
|
24
|
+
text: "使用模板",
|
|
25
|
+
items: [
|
|
26
|
+
{ text: "快速开始", link: "/guide/getting-started" },
|
|
27
|
+
{ text: "工作区约定", link: "/guide/workspace" },
|
|
28
|
+
{ text: "版本与发布", link: "/guide/release" },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
search: {
|
|
34
|
+
provider: "local",
|
|
35
|
+
options: {
|
|
36
|
+
locales: {
|
|
37
|
+
root: {
|
|
38
|
+
translations: {
|
|
39
|
+
button: { buttonText: "搜索文档", buttonAriaLabel: "搜索文档" },
|
|
40
|
+
modal: {
|
|
41
|
+
displayDetails: "显示详细列表",
|
|
42
|
+
resetButtonTitle: "清除搜索",
|
|
43
|
+
backButtonTitle: "返回",
|
|
44
|
+
noResultsText: "没有找到相关结果",
|
|
45
|
+
footer: {
|
|
46
|
+
selectText: "选择",
|
|
47
|
+
navigateText: "切换",
|
|
48
|
+
closeText: "关闭",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
outline: { label: "本页目录", level: [2, 3] },
|
|
57
|
+
docFooter: { prev: "上一篇", next: "下一篇" },
|
|
58
|
+
lastUpdated: { text: "最后更新于" },
|
|
59
|
+
returnToTopLabel: "返回顶部",
|
|
60
|
+
sidebarMenuLabel: "菜单",
|
|
61
|
+
darkModeSwitchLabel: "主题",
|
|
62
|
+
lightModeSwitchTitle: "切换到浅色模式",
|
|
63
|
+
darkModeSwitchTitle: "切换到深色模式",
|
|
64
|
+
skipToContentLabel: "跳转到内容",
|
|
65
|
+
footer: {
|
|
66
|
+
message: "从一个共享包、一份文档和一个应用开始。",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# 快速开始
|
|
2
|
+
|
|
3
|
+
这个模板把应用、共享包、文档和工程配置组织到一个 pnpm 工作区。示例应用使用 `@bubblesjs/utils`,文档站点独立运行。你可以沿着示例应用的依赖关系继续添加自己的功能。
|
|
4
|
+
|
|
5
|
+
根项目、`docs`、`playground` 和 `@bubblesjs/utils` 均为 `private: true`,目前没有 npm 发布对象。utils 是内部共享包,仍可构建 ESM/CJS 和类型声明。
|
|
6
|
+
|
|
7
|
+
## 环境要求
|
|
8
|
+
|
|
9
|
+
- Node.js `>=24.11.0 <25`
|
|
10
|
+
- pnpm `12.10.1`,与根目录 `package.json` 的 `packageManager` 保持一致
|
|
11
|
+
|
|
12
|
+
仓库通过 `.node-version` 和 `mise.toml` 固定 Node.js `24.21.0`,便于本地与 CI 使用同一版本。
|
|
13
|
+
|
|
14
|
+
在项目根目录安装依赖,然后启动应用:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm install
|
|
18
|
+
pnpm dev
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
文档站点使用 VitePress,单独启动:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm docs:dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
示例应用默认使用 `http://localhost:5173`,文档默认使用 `http://localhost:5174`。两个开发服务都启用了 `strictPort`,端口被占用时会提示错误。打开终端中输出的本地地址即可浏览。
|
|
28
|
+
|
|
29
|
+
Playground 通过源码别名消费共享包,修改 `packages/utils/src/` 后即可在示例应用中观察变化。
|
|
30
|
+
|
|
31
|
+
## 常用命令
|
|
32
|
+
|
|
33
|
+
以下命令均在仓库根目录运行:
|
|
34
|
+
|
|
35
|
+
| 命令 | 用途 |
|
|
36
|
+
| ----------------------- | -------------------------------------------- |
|
|
37
|
+
| `pnpm dev` | 启动示例应用 |
|
|
38
|
+
| `pnpm docs:dev` | 启动文档站点 |
|
|
39
|
+
| `pnpm check` | 运行质量检查与测试 |
|
|
40
|
+
| `pnpm ready` | 完整验证:质量检查、测试、构建与包产物检查 |
|
|
41
|
+
| `pnpm build` | 构建工作区内的包、应用和文档 |
|
|
42
|
+
| `pnpm test` | 运行单元测试 |
|
|
43
|
+
| `pnpm typecheck` | 检查工作区的 TypeScript 和 Vue 类型 |
|
|
44
|
+
| `pnpm verify:packages` | 检查本地 ESM/CJS 和类型产物,不执行 npm 发布 |
|
|
45
|
+
| `pnpm changeset` | 为将来公开包的变更添加版本记录 |
|
|
46
|
+
| `pnpm version-packages` | 消费 changeset,更新将来公开包的版本与日志 |
|
|
47
|
+
| `pnpm release` | 为将来公开包保留的 npm 发布流程 |
|
|
48
|
+
| `pnpm hooks:install` | 初始化 Git 后手动安装提交检查 hooks |
|
|
49
|
+
|
|
50
|
+
提交前推荐运行 `pnpm ready`。备用命令是 `pnpm run ci`,显式执行根 `package.json` 中的 `ci` 脚本。在 pnpm 12 中,`ci` 是内置安装命令,因此调用同名项目脚本需要保留 `run`。
|
|
51
|
+
|
|
52
|
+
只运行某个应用或包时,可以使用 pnpm 的过滤器。例如:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm --filter docs build
|
|
56
|
+
pnpm --filter docs preview
|
|
57
|
+
pnpm --filter @bubblesjs/utils test
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 用模板开始自己的项目
|
|
61
|
+
|
|
62
|
+
1. 把仓库复制到自己的项目目录,设置自己的 Git 远程仓库。
|
|
63
|
+
2. 修改根 `package.json` 的 `name`,内部包默认沿用 `@bubblesjs` scope,私有应用名称无需更改。只有更换 scope 时,才同步修改包名、工作区引用、源码别名和包产物检查脚本。
|
|
64
|
+
3. 替换文档标题、描述、首页内容和示例应用内容。
|
|
65
|
+
4. 更新作者和许可证信息。将来新增公开包时,再完善 `repository`、`homepage`、`bugs` 等发布元信息;若复制 utils 作为公开包,须显式移除 `private: true` 并设置 `publishConfig.access` 为 `public`。
|
|
66
|
+
5. 执行 `pnpm install` 更新锁文件,然后运行 `pnpm ready` 完成全部验证。
|
|
67
|
+
|
|
68
|
+
如需启用提交前的暂存文件检查与 Conventional Commits 校验,先初始化 Git(新仓库可执行 `git init -b main`),再运行 `pnpm hooks:install`。依赖安装完成后,Git hooks 由这个命令按需启用。
|
|
69
|
+
|
|
70
|
+
添加新代码之前,先阅读[工作区约定](./workspace)。需要发布 npm 包时,完成[版本与发布](./release)中的初始化步骤。
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 版本与发布
|
|
2
|
+
|
|
3
|
+
根项目、`docs`、`playground` 和 `@bubblesjs/utils` 均为 `private: true`,目前没有 npm 发布对象。utils 用于内部共享,仍可构建与验证 ESM/CJS 和类型声明;`pnpm verify:packages` 是本地产物检查,不执行 npm 发布。
|
|
4
|
+
|
|
5
|
+
以下 Changesets 流程保留给将来新增的公开包,例如 `@bubblesjs/math` 或 `@bubblesjs/i18n`。
|
|
6
|
+
|
|
7
|
+
根目录 `tsconfig/` 只保存共享 TypeScript 配置,不作为工作区包,也不参与版本与发布。
|
|
8
|
+
|
|
9
|
+
## 初始化自己的发布信息
|
|
10
|
+
|
|
11
|
+
第一次发布前,完成以下配置:
|
|
12
|
+
|
|
13
|
+
1. 将来的公开包默认使用 `@bubblesjs/<名称>`,例如 `@bubblesjs/math`,私有应用名称无需更改。若复制 utils 作为公开包,须显式移除 `private: true` 并设置 `publishConfig.access` 为 `public`。只有更换 scope 时,才同步更新包名、工作区引用、Vite 与 TypeScript 别名,以及包产物检查脚本。
|
|
14
|
+
2. 更新包清单中的 `repository`、`homepage`、`bugs`、作者和许可证信息,确保链接指向自己的项目。
|
|
15
|
+
3. 检查 `.changeset/config.json` 的默认分支。模板使用 `main`;你的仓库若使用其他分支,需要同步修改配置与工作流。
|
|
16
|
+
4. 确认可发布包的 `files`、`exports`、类型入口和版本,并保持 `publishConfig.access` 为 `public`。模板初始版本是起点,首次发布的目标版本由 changeset 决定。
|
|
17
|
+
5. 发布到 npm 的账户需拥有 `@bubblesjs` scope 或对应组织的包发布权限。在 GitHub 仓库配置具有目标包发布权限的 `NPM_TOKEN` secret,并将仓库变量 `RELEASE_ENABLED` 设置为字符串 `true`,启用发布工作流。
|
|
18
|
+
|
|
19
|
+
执行 `pnpm install` 更新锁文件,再执行 `pnpm ready` 完成质量检查、测试、构建与包产物检查。验证通过后再进行发布。
|
|
20
|
+
|
|
21
|
+
## 记录包的变更
|
|
22
|
+
|
|
23
|
+
当修改会影响共享包的使用者时,运行:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm changeset
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
选择受影响的包、版本级别,并写清行为变化。将生成的 `.changeset/*.md` 与实现一起提交。现有私有项目(包括 utils)不参与 npm 发布,此流程用于将来的公开包。
|
|
30
|
+
|
|
31
|
+
## 本地更新版本和发布
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pnpm version-packages
|
|
35
|
+
pnpm install
|
|
36
|
+
pnpm ready
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
检查包版本、变更日志和锁文件,提交版本变更后,在具有 npm 发布权限的环境运行:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pnpm release
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`version-packages` 消费 changeset 并修改仓库文件;`release` 会把符合条件的新版本发布到 npm。先确认包名、目标版本和构建产物。
|
|
46
|
+
|
|
47
|
+
## GitHub 发布工作流
|
|
48
|
+
|
|
49
|
+
`.github/workflows/release.yml` 使用手动触发 `workflow_dispatch`,并要求在 `main` 分支运行。在 Actions 页面运行它之前,先完成上述发布配置。
|
|
50
|
+
|
|
51
|
+
- `RELEASE_ENABLED` 未设置为 `true` 时,发布任务跳过。
|
|
52
|
+
- 启用后,Changesets Action 可以创建或更新版本 PR。
|
|
53
|
+
- 版本 PR 合并后,再次手动运行工作流可发布新版本;仅配置了 `NPM_TOKEN` 时才执行 npm 发布。
|
|
54
|
+
|
|
55
|
+
模板不会因一次普通代码推送自动开启 npm 发布。自己的包完成初始化后,可根据团队流程调整触发条件。
|
|
56
|
+
|
|
57
|
+
## 部署文档
|
|
58
|
+
|
|
59
|
+
文档的静态输出位于 `apps/docs/.vitepress/dist/`。本地构建和预览:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pnpm --filter docs build
|
|
63
|
+
pnpm --filter docs preview
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
默认站点路径是 `/`。部署到子路径时,通过 `DOCS_BASE` 设置,例如在 PowerShell 中:
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
$env:DOCS_BASE = '/my-repository/'
|
|
70
|
+
pnpm --filter docs build
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
使用 GitHub Pages 时,在仓库设置里将 Pages 的构建来源设置为 GitHub Actions,然后手动运行 `.github/workflows/docs.yml`。工作流根据仓库名称计算 `DOCS_BASE`,上传文档产物并执行 Pages 部署。组织或用户首页仓库,以及自定义域名部署,需确认最终路径与实际访问地址一致。
|