目标:一套依赖(一个 node_modules)承载多个业务项目;启动/构建时通过环境变量选择“当前项目入口”,做到按项目入口打包,避免每个项目重复克隆+重复装依赖。
- 默认(单项目)完全不变:继续用根目录
index.html+src/index.tsx。 - 多项目模式:通过
PROJECT=projectA|projectB|...选择入口文件src/projects/<project>/index.tsx。 - 项目级
public:若存在src/projects/<project>/public,则该目录作为 Vite 的publicDir。 - 项目级路由覆盖:若存在
src/projects/<project>/routers,则@routers会指向该目录;否则回退到默认src/routers。
推荐结构(可按需增减):
src/projects/<project>/index.tsx:项目入口(类似你描述的app.js)。src/projects/<project>/routers/:项目路由(可先用“包装转发”复用默认路由)。src/projects/<project>/public/:项目静态资源(等价于 Vite 的public/)。
-
默认项目
npm run dev:vitenpm run build:vitenpm run preview:vite
-
Project A
npm run dev:vite:projectAnpm run build:vite:projectAnpm run preview:vite:projectA
-
Project B
npm run dev:vite:projectBnpm run build:vite:projectBnpm run preview:vite:projectB
以下脚本会根据 PROJECT 自动选择 dist 或 dist-<project>:
npm run serve:prod/npm run serve:dev/npm run serve:testnpm run http:prod/npm run http:dev/npm run http:test
示例:
PROJECT=projectA npm run build:production:projectAPROJECT=projectA npm run serve:prodPROJECT=projectA npm run http:prod
-
默认项目
npm run startnpm run build:productionnpm run prod:serve
-
Project A
npm run start:projectAnpm run build:production:projectAnpm run prod:serve:projectA
-
Project B
npm run start:projectBnpm run build:production:projectBnpm run prod:serve:projectB
构建产物目录:
- 默认:
dist-vite - 非默认:
dist-vite-<project>(例如dist-vite-projectA)
Webpack 构建产物目录:
- 默认:
dist - 非默认:
dist-<project>(例如dist-projectA)
-
创建入口文件:
src/projects/projectC/index.tsx -
(可选)创建路由目录:
src/projects/projectC/routers/
- 如果你想先复用默认路由:
routers/index.jsx里写:export { default } from '@src/routers'export * from '@src/routers'
routers/authRouter.jsx里写:export { default } from '@src/routers/authRouter'
-
(可选)创建静态资源目录:
src/projects/projectC/public/ -
增加脚本(两种方式选一种)
- 推荐:直接照着
projectA/projectB在根package.json里添加:cross-env PROJECT=projectC vite --host --config vite.config.tscross-env PROJECT=projectC vite build --config vite.config.ts
Vite 在构建时只会从 index.html 注入的入口脚本向下依赖分析。
当前实现会在构建/开发时把 index.html 里的默认入口 /src/index.tsx 替换为 /src/projects/<project>/index.tsx,因此不会把其它项目入口当成必需依赖链去打包。