Compare commits
3 Commits
7bc20d517b
...
c26c2ed5d5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c26c2ed5d5 | ||
|
|
3d0c69c98e | ||
|
|
ca24ab9922 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,6 +1,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
/dist
|
dist
|
||||||
|
|
||||||
|
|
||||||
# local env files
|
# local env files
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
## DDD领域驱动设计的微服务前端案例
|
## DDD领域驱动设计的微服务前端案例
|
||||||
|
|
||||||
> 持续开发中,及时拉取代码,文档还不够完善,先凑合看!!目前只是demo,代码还会进行大规模封装细化和改造!
|
> 持续开发中,及时拉取代码,文档还不够完善,先凑合看!!目前只是demo,代码还会进行大规模封装细化和改造!
|
||||||
|
|||||||
@@ -1 +1,10 @@
|
|||||||
# 临时占位,上传空文件夹,保存文件结构用,后面删除
|
npm install
|
||||||
|
npm run build
|
||||||
|
npm run serve
|
||||||
|
|
||||||
|
|
||||||
|
构建与部署:
|
||||||
|
|
||||||
|
- 在构建生产环境时,先构建主模块,并将其产出(特别是 remoteEntry.js 和对应的资产文件)部署到服务器,并获取其 URL。
|
||||||
|
- 然后,在子模块的 vite.config.ts 中,将 remotes 的 URL 更新为生产环境主模块 remoteEntry.js 的绝对 URL。
|
||||||
|
- 最后再构建子模块。
|
||||||
16
front-end/app-product/index.html
Normal file
16
front-end/app-product/index.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
3636
front-end/app-product/package-lock.json
generated
Normal file
3636
front-end/app-product/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
35
front-end/app-product/package.json
Normal file
35
front-end/app-product/package.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "app-product",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --port 5001 --strictPort",
|
||||||
|
"serve": "vite preview --port 5001 --strictPort",
|
||||||
|
"build": "vite build",
|
||||||
|
"all": "npm run build && npm run serve",
|
||||||
|
"type-check": "vue-tsc --build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.12.2",
|
||||||
|
"pinia": "^3.0.3",
|
||||||
|
"vue": "^3.5.18",
|
||||||
|
"vue-router": "^4.0.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@originjs/vite-plugin-federation": "^1.4.1",
|
||||||
|
"@tsconfig/node22": "^22.0.2",
|
||||||
|
"@types/node": "^22.16.5",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
||||||
|
"@vue/tsconfig": "^0.7.0",
|
||||||
|
"npm-run-all2": "^8.0.4",
|
||||||
|
"typescript": "~5.8.0",
|
||||||
|
"vite": "^7.0.6",
|
||||||
|
"vite-plugin-vue-devtools": "^8.0.0",
|
||||||
|
"vue-tsc": "^3.0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
front-end/app-product/src/App.tsx
Normal file
17
front-end/app-product/src/App.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { defineComponent } from 'vue'
|
||||||
|
import { RouterLink, RouterView } from "vue-router";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
setup() {
|
||||||
|
return () => (
|
||||||
|
<>
|
||||||
|
{/* 仅作占位,主应用加载联邦模块时不会显示此内容 */}
|
||||||
|
<div class="order-federation-placeholder">
|
||||||
|
<h2>订单联邦模块(独立开发/测试用)</h2>
|
||||||
|
<p>此页面仅用于模块单独调试,实际运行时由主应用加载资源</p>
|
||||||
|
<p>单独开发时,可临时引入组件进行本地测试</p>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
6
front-end/app-product/src/domains/product/index.ts
Normal file
6
front-end/app-product/src/domains/product/index.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export * from './application/services/ProductApplicationService';
|
||||||
|
export * from './domain/entities/Product';
|
||||||
|
export * from './domain/enums/ErrorEnums';
|
||||||
|
export * from './domain/type/ProductType';
|
||||||
|
export * from './infr/api/HttpProductRepository';
|
||||||
|
export * from './ports/repositories/ProductRepository';
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Product } from "../../domain/entities/Product";
|
import { Product } from "@domains/product/domain/entities/Product.ts";
|
||||||
import { ProductType } from "../../domain/type/ProductType";
|
import { ProductType } from "@domains/product/domain/type/ProductType.ts";
|
||||||
import { ProductRepository } from "../../ports/repositories/ProductRepository";
|
import { ProductRepository } from "@domains/product/ports/repositories/ProductRepository";
|
||||||
import http from "@shared/infra/AxiosInfra";
|
// @ts-ignore
|
||||||
|
import { http } from "mainApp/shared";
|
||||||
import HttpConfig from "../config/HttpConfig";
|
import HttpConfig from "../config/HttpConfig";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -5,13 +5,13 @@ export const productRouter: Array<RouteRecordRaw> = [
|
|||||||
{
|
{
|
||||||
path: '/Products',
|
path: '/Products',
|
||||||
name: 'ProductList',
|
name: 'ProductList',
|
||||||
component: () => import('../views/ProductList.tsx'),
|
component: () => import('../views/ProductList.jsx'),
|
||||||
meta: { title: '商品列表' }
|
meta: { title: '商品列表' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/ProductDetail',
|
path: '/ProductDetail',
|
||||||
name: 'ProductDetail',
|
name: 'ProductDetail',
|
||||||
component: () => import('../views/ProductDetail.tsx'),
|
component: () => import('../views/ProductDetail.jsx'),
|
||||||
meta: { title: '商品详情' }
|
meta: { title: '商品详情' }
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { productModule } from '@/di/productModule';
|
import { product } from 'mainApp/productService';
|
||||||
import { ProductType } from '@domains/product/domain/type/ProductType';
|
import { ProductType } from '@domains/product/domain/type/ProductType';
|
||||||
import { defineComponent, onMounted, reactive } from 'vue'
|
import { defineComponent, onMounted, reactive } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
@@ -12,7 +12,7 @@ export default defineComponent({
|
|||||||
name: "productModule-ProductDetail",
|
name: "productModule-ProductDetail",
|
||||||
setup() {
|
setup() {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const productService = productModule.createProductApplicationService();
|
const productService = product.createProductApplicationService();
|
||||||
|
|
||||||
const state = reactive<storeType>({
|
const state = reactive<storeType>({
|
||||||
item: {} as ProductType,
|
item: {} as ProductType,
|
||||||
@@ -50,4 +50,12 @@ export default defineComponent({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// export default defineComponent({
|
||||||
|
// setup() {
|
||||||
|
// return () => (
|
||||||
|
// <div>商品详情</div>
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// })
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { defineComponent, onMounted, reactive } from 'vue'
|
import { defineComponent, onMounted, reactive } from 'vue'
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { productModule } from '@/di/productModule';
|
import { product } from 'mainApp/productService';
|
||||||
import { ProductType } from '@domains/product/domain/type/ProductType';
|
import { ProductType } from '@domains/product/domain/type/ProductType';
|
||||||
|
|
||||||
interface storeType {
|
interface storeType {
|
||||||
@@ -12,7 +12,7 @@ export default defineComponent({
|
|||||||
setup() {
|
setup() {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const productService = productModule.createProductApplicationService();
|
const productService = product.createProductApplicationService();
|
||||||
|
|
||||||
const state = reactive<storeType>({
|
const state = reactive<storeType>({
|
||||||
list: []
|
list: []
|
||||||
@@ -50,4 +50,12 @@ export default defineComponent({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// export default defineComponent({
|
||||||
|
// setup() {
|
||||||
|
// return () => (
|
||||||
|
// <div>商品列表</div>
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// })
|
||||||
11
front-end/app-product/src/main.ts
Normal file
11
front-end/app-product/src/main.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// import './assets/main.css'
|
||||||
|
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
|
||||||
|
import App from './App'
|
||||||
|
|
||||||
|
createApp(App)
|
||||||
|
.use(createPinia())
|
||||||
|
.mount('#app')
|
||||||
|
|
||||||
3
front-end/app-product/src/shared/types/product-federation.d.ts
vendored
Normal file
3
front-end/app-product/src/shared/types/product-federation.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
declare module 'mainApp/productService' {
|
||||||
|
export const product: any;
|
||||||
|
}
|
||||||
33
front-end/app-product/tsconfig.app.json
Normal file
33
front-end/app-product/tsconfig.app.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"src/**/*.d.ts",
|
||||||
|
"src/**/*",
|
||||||
|
"src/**/*.tsx",
|
||||||
|
"src/**/*.vue"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"src/**/__tests__/*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"verbatimModuleSyntax": false,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"jsxImportSource": "vue",
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./src/app/*"
|
||||||
|
],
|
||||||
|
"@shared/*": [
|
||||||
|
"./src/shared/*"
|
||||||
|
],
|
||||||
|
"@features/*": [
|
||||||
|
"./src/features/*"
|
||||||
|
],
|
||||||
|
"@domains/*": [
|
||||||
|
"./src/domains/*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
front-end/app-product/tsconfig.json
Normal file
11
front-end/app-product/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.app.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
19
front-end/app-product/tsconfig.node.json
Normal file
19
front-end/app-product/tsconfig.node.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": "@tsconfig/node22/tsconfig.json",
|
||||||
|
"include": [
|
||||||
|
"vite.config.*",
|
||||||
|
"vitest.config.*",
|
||||||
|
"cypress.config.*",
|
||||||
|
"nightwatch.conf.*",
|
||||||
|
"playwright.config.*",
|
||||||
|
"eslint.config.*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"noEmit": true,
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"types": ["node"]
|
||||||
|
}
|
||||||
|
}
|
||||||
50
front-end/app-product/vite.config.ts
Normal file
50
front-end/app-product/vite.config.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
|
import federation from '@originjs/vite-plugin-federation';
|
||||||
|
import {fileURLToPath, URL} from "node:url";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
federation({
|
||||||
|
name: 'productModule', // 联邦模块名称(主应用通过此名称引用)
|
||||||
|
filename: 'remoteEntry.js',
|
||||||
|
// 关键:声明远程模块(主模块)
|
||||||
|
remotes: {
|
||||||
|
mainApp: "http://localhost:5000/assets/remoteEntry.js"
|
||||||
|
},
|
||||||
|
exposes: { // 暴露给主应用的资源(按功能分组)
|
||||||
|
'./ProductDomain': './src/domains/product/index.ts', // 领域层(实体、服务、接口等)
|
||||||
|
'./ProductRouter': './src/features/product/router/index.ts' // 商品路由
|
||||||
|
},
|
||||||
|
shared: {
|
||||||
|
vue: { generate:false, requiredVersion: '^3.5.18' },
|
||||||
|
axios: { generate:false, requiredVersion: '^1.12.2' },
|
||||||
|
'vue-router': { generate:false, requiredVersion: '^4.0.6' },
|
||||||
|
pinia: { generate:false, requiredVersion: '^3.0.3' }
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
vue(),
|
||||||
|
vueJsx(),
|
||||||
|
vueDevTools()
|
||||||
|
],
|
||||||
|
build: {
|
||||||
|
target: 'esnext',
|
||||||
|
cssCodeSplit: true,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
format: 'es',
|
||||||
|
minifyInternalExports: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': fileURLToPath(new URL('./src/', import.meta.url)),
|
||||||
|
'@shared': fileURLToPath(new URL('./src/shared/', import.meta.url)),
|
||||||
|
'@features': fileURLToPath(new URL('./src/features/', import.meta.url)),
|
||||||
|
'@domains': fileURLToPath(new URL('./src/domains/', import.meta.url))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -7,10 +7,10 @@
|
|||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite --port 5000 --strictPort",
|
||||||
"build": "run-p type-check \"build-only {@}\" --",
|
"serve": "vite preview --port 5000 --strictPort",
|
||||||
"preview": "vite preview",
|
"build": "vite build",
|
||||||
"build-only": "vite build",
|
"all": "npm run build && npm run serve",
|
||||||
"type-check": "vue-tsc --build"
|
"type-check": "vue-tsc --build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { ProductApplicationService } from "../../domains/product/application/services/ProductApplicationService";
|
// 从商品联邦模块导入领域层资源
|
||||||
import { HttpProductRepository } from "../../domains/product/infr/api/HttpProductRepository";
|
import {
|
||||||
import { ProductRepository } from "../../domains/product/ports/repositories/ProductRepository";
|
ProductApplicationService,
|
||||||
|
HttpProductRepository,
|
||||||
|
ProductRepository
|
||||||
|
} from 'productModule/ProductDomain';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品领域的依赖注入配置
|
* 商品领域的依赖注入配置
|
||||||
@@ -21,7 +23,7 @@ import { ProductRepository } from "../../domains/product/ports/repositories/Prod
|
|||||||
* productModule.bindProductRepository = () => new MockProductRepository();
|
* productModule.bindProductRepository = () => new MockProductRepository();
|
||||||
* 这样测试就可以脱离真实 API,使用预设的模拟数据。
|
* 这样测试就可以脱离真实 API,使用预设的模拟数据。
|
||||||
*/
|
*/
|
||||||
export const productModule = {
|
export const product = {
|
||||||
|
|
||||||
// 绑定 仓储抽象接口 到 HTTP具体实现
|
// 绑定 仓储抽象接口 到 HTTP具体实现
|
||||||
bindProductRepository: (): ProductRepository => {
|
bindProductRepository: (): ProductRepository => {
|
||||||
@@ -32,7 +34,7 @@ export const productModule = {
|
|||||||
// 创建应用服务实例
|
// 创建应用服务实例
|
||||||
createProductApplicationService: (): ProductApplicationService => {
|
createProductApplicationService: (): ProductApplicationService => {
|
||||||
return new ProductApplicationService(
|
return new ProductApplicationService(
|
||||||
productModule.bindProductRepository()
|
product.bindProductRepository()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
|
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
|
||||||
import { productRouter } from '@features/product/router'
|
import { productRouter } from 'productModule/ProductRouter'
|
||||||
|
|
||||||
const baseRouter: Array<RouteRecordRaw> = [
|
const baseRouter: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
# 临时占位,上传空文件夹,保存文件结构用,后面删除
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
export default class HttpConfig {
|
export class HttpConfig {
|
||||||
public static DevBaseUrl: string = "http://127.0.0.1:3000/api"
|
public static DevBaseUrl: string = "http://127.0.0.1:3000/api"
|
||||||
public static prodBaseUrl: string = "http://127.0.0.1:9090/api/"
|
public static prodBaseUrl: string = "http://127.0.0.1:3000/api/"
|
||||||
public static apiList: string = ""
|
public static apiList: string = ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export default class ThemeConfig {
|
export class ThemeConfig {
|
||||||
public static primaryColor: string = '#1890ff'; // 主色调
|
public static primaryColor: string = '#1890ff'; // 主色调
|
||||||
public static layoutType: 'side' | 'top' = 'side'; // 侧边栏布局
|
public static layoutType: 'side' | 'top' = 'side'; // 侧边栏布局
|
||||||
}
|
}
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import HttpConfig from './HttpConfig';
|
|
||||||
import ThemeConfig from './ThemeConfig';
|
|
||||||
|
|
||||||
export { HttpConfig, ThemeConfig };
|
|
||||||
3
front-end/main-app/src/shared/index.ts
Normal file
3
front-end/main-app/src/shared/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./config/HttpConfig"
|
||||||
|
export * from "./config/ThemeConfig"
|
||||||
|
export { default as http } from "./infra/AxiosInfra"
|
||||||
41
front-end/main-app/src/shared/types/product-federation.d.ts
vendored
Normal file
41
front-end/main-app/src/shared/types/product-federation.d.ts
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// 声明领域层类型
|
||||||
|
declare module 'productModule/ProductDomain' {
|
||||||
|
import type { DefineComponent } from 'vue';
|
||||||
|
// 商品实体类型(与联邦模块一致)
|
||||||
|
export class Product {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
price: number;
|
||||||
|
imageUrl: string;
|
||||||
|
stock: number;
|
||||||
|
categoryId: number;
|
||||||
|
}
|
||||||
|
// 应用服务类型
|
||||||
|
export class ProductApplicationService {
|
||||||
|
constructor(repo: ProductRepository);
|
||||||
|
findAll(): Promise<Array<any>>; // TODO any 需要修改
|
||||||
|
findById(id: number): Promise<Product>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HttpProductRepository implements ProductRepository {
|
||||||
|
findAll(): Promise<Array<any>>; // TODO any 需要修改
|
||||||
|
findById(id: number): Promise<Product>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ProductRepository {
|
||||||
|
findAll(): Promise<Array<any>>; // TODO any 需要修改
|
||||||
|
findById(id: number): Promise<Product>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 声明视图类型(同理补充其他模块)
|
||||||
|
// declare module 'productModule/ProductViews' {
|
||||||
|
// import type { DefineComponent } from 'vue';
|
||||||
|
// export const ProductList: DefineComponent; // 商品列表页
|
||||||
|
// export const ProductDetail: DefineComponent; // 商品详情页
|
||||||
|
// }
|
||||||
|
|
||||||
|
declare module 'productModule/ProductRouter' {
|
||||||
|
export const productRouter: RouteRecordRaw[];
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { HttpConfig } from '@shared/config/index'
|
import { HttpConfig } from '@shared/config/HttpConfig'
|
||||||
|
|
||||||
export default class UrlCheckUtils {
|
export default class UrlCheckUtils {
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { defineConfig } from 'vite'
|
|||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
|
import federation from '@originjs/vite-plugin-federation';
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -11,7 +12,33 @@ export default defineConfig({
|
|||||||
vue(),
|
vue(),
|
||||||
vueJsx(),
|
vueJsx(),
|
||||||
vueDevTools(),
|
vueDevTools(),
|
||||||
|
federation({
|
||||||
|
name: 'mainApp', // 主应用模块名(联邦模块需通过此名引用)
|
||||||
|
remotes: { // 配置远程联邦模块地址(开发/生产需对应)
|
||||||
|
productModule: 'http://localhost:5001/assets/remoteEntry.js'
|
||||||
|
},
|
||||||
|
exposes: {
|
||||||
|
"./shared": "./src/shared/index.ts",
|
||||||
|
"./productService": "./src/app/di/productModule.ts",
|
||||||
|
},
|
||||||
|
shared: {
|
||||||
|
vue: { requiredVersion: '^3.5.18' },
|
||||||
|
axios: { requiredVersion: '^1.12.2' },
|
||||||
|
'vue-router': { requiredVersion: '^4.0.6' },
|
||||||
|
pinia: { requiredVersion: '^3.0.3' }
|
||||||
|
}
|
||||||
|
})
|
||||||
],
|
],
|
||||||
|
build: {
|
||||||
|
target: 'esnext',
|
||||||
|
minify: false,
|
||||||
|
cssCodeSplit: true,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
minifyInternalExports: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': fileURLToPath(new URL('./src/app/', import.meta.url)),
|
'@': fileURLToPath(new URL('./src/app/', import.meta.url)),
|
||||||
|
|||||||
Reference in New Issue
Block a user