使用vite搭建vue项目时,创建多个子项目的具体实现方案
1、项目启动入口设置
设置 package.json 的 scripts 的项目启动命令添加运行和构建命令
运行命令
"start": "node config/commandConfig.cjs ORDER_TARGET=DEV",
构建命令
"pack": "node config/commandConfig.cjs ORDER_TARGET=BUILD",
2、项目启动文件 commandConfig.cjs 文件处理
在项目根目录下创建 config->commandConfig.cjs 如下:
const fs = require('fs');
const colors = require('colors-console');
/**
* process.argv 获取的到的内容为npm run xxx 所对应的内容(ps:npm run dev project pro)
* [0] = 电脑系统中存储的node所对应的程序路径
* [1] = vue工程中所执行的当前指令对应的配置项文件路径
* [2] = 对应package.json当中scripts中的指令后所跟随的标识
* [3] = 所对应的项目名称为 project
* [4] = 为后新增的标识 pro
* [n] = 如果继续叠加,以此类推
* console.log(process.argv) argv: argv: ['C:\\Program Files\\nodejs\\node.exe','E:\\vite-multiple-project\\config\\commandConfig.cjs','ORDER_TARGET=DEV','project','pro']
*/
let [, , ORDER_TARGET, PROJECT_NAME] = process.argv;
// 运行环境
const finalTarget = (ORDER_TARGET && ORDER_TARGET?.split('=')[1]) || '';
if (!PROJECT_NAME) {
return console.log(colors(`red`, `> Project ${PROJECT_NAME} not found. Please create project ${PROJECT_NAME} first`));
}
/**
* 运行命令
*/
const ORDER_SCRIPT = finalTarget == 'DEV' ? `vite --mode ${PROJECT_NAME}` : `vite build --mode ${PROJECT_NAME}`; //获取执行命令
/**
* 检测当前执行命令中所携带的项目,在当前工程中是否已经具备,如果不具备,后续运行则会报错
*/
fs.exists(`./src/pages/${PROJECT_NAME}`, (v) => {
if (!v) return console.log(colors(`yellow`, `> reminder: The project referred to in the current command: ${PROJECT_NAME} does not exist`));
let exec = require('child_process').execSync;
/**
* 通过package.json当中定义的 ORDER_TARGET 来判定所执行的命令为启动(npm run dev)还是打包(npm run build)
* 通过截取对应的标识,进行动态判断当前所执行命令的动作指向
*/
exec(ORDER_SCRIPT, { stdio: 'inherit' });
});
3、项目构建时动态路由的引入,编写 vite 插件
此方案采用的统一的 main 入口,所以在构建时需要按需动态的引入路由,在根目录下创建 plugins 文件夹下创建文件 vite-plugin-router.js 插件如下:
//PROJECT_NAME 项目名称 运行哪个项目引入那个项目的路由
export default function vitePluginRoutes(PROJECT_NAME) {
const virtualModuleId = 'virtual:@vite-virtual-routes';
const resolvedVirtualModuleId = '\0' + virtualModuleId;
return {
name: 'vite-plugin-routes', // 必须的,将会在 warning 和 error 中显示
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
// 可根据自己项目架构调整
return `export { setupRouter } from "@/pages/${PROJECT_NAME}/router"`;
}
},
};
}
4、vite.config.ts 配置文件改造
import { defineConfig, loadEnv } from 'vite';
// 第三步自己创建的vite插件
import vitePluginRoutes from './plugins/vite-plugin-routes.js';
export default defineConfig(({ command, mode }) => {
// 此处可以判定运行环境还是开发环境
const FINAL_TARGET = command === 'serve' ? 'DEV' : 'BUILD';
// 此处可以获取运行的项目名称
const PROJECT_NAME = mode;
// 可以设置项目需要的信息添加的全局中
const APP_INFO = { PROJECT_NAME, FINAL_TARGET };
return {
define: {
APP_INFO: JSON.stringify(APP_INFO),
},
plugins: [
// 加载指定项目路由
vitePluginRoutes(PROJECT_NAME),
]
}
})
5、main.ts 入口文件引入虚拟路由
此处可根据自己的架构调整路由的导入名称和方式、与 vite-plugin-routes 对应
import { setupRouter } from 'virtual:@vite-virtual-routes';
6、创建多个项目和 env 环境变量
project-name/
|── scr/
│ ├── pages/
| | └── project01
| | | └── routers
| │ | └── routers
| | | └── api
| | | └── project01.vue
│ | └── project02
| | | └── routers
| │ | └── routers
| | | └── api
| | | └── project02.vue
| | └── app.vue
| | └── main.ts
├── plugins/
│ └── vite-plugin-routes.js
└── config/
| └── commandConfig.cjs
└── .env.project01
└── .env.project02
7、启动项目
npm run start + 项目名称
npm run start projcet01
7、构建项目
npm run pack + 项目名称
npm run pack projcet01