Compare commits
	
		
			No commits in common. "9341e4659411b0b640e72c5ffa2e127aefa3746b" and "248eba5975a3dee018402b17d02da89c731424bd" have entirely different histories.
		
	
	
		
			9341e46594
			...
			248eba5975
		
	
		
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@ -17,8 +17,6 @@ cp .env.example .env
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Development
 | 
					## Development
 | 
				
			||||||
 | 
					
 | 
				
			||||||
First, we need to build the remote first. Check [this](https://github.com/originjs/vite-plugin-federation/issues/525) for why.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
cd remote
 | 
					cd remote
 | 
				
			||||||
pnpm i
 | 
					pnpm i
 | 
				
			||||||
@ -48,16 +46,8 @@ pnpm build
 | 
				
			|||||||
pnpm serve
 | 
					pnpm serve
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Notes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- It's recommended to split the repository for Host and Remote, and deploy separately
 | 
					 | 
				
			||||||
- If you want to go with monorepo approach, make sure to setup a monorepo package manager (Pnpm workspace, Nx, etc.)
 | 
					 | 
				
			||||||
- This repo is still evolving, and might not be production-ready yet
 | 
					 | 
				
			||||||
- No SSR support (no plan for this)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## TODO
 | 
					## TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Pinia integration
 | 
					 | 
				
			||||||
- Build-mode works but Dev-mode not works (fixed)
 | 
					- Build-mode works but Dev-mode not works (fixed)
 | 
				
			||||||
- Enable CORS on remote JS assets (fixed)
 | 
					- Enable CORS on remote JS assets (fixed)
 | 
				
			||||||
- Scoped style still not works (fixed)
 | 
					- Scoped style still not works (fixed)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								host/error.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								host/error.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import type { NuxtError } from "#app"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  error: Object as () => NuxtError
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div>
 | 
				
			||||||
 | 
					    <h1>Ooops... Something went wrong...</h1>
 | 
				
			||||||
 | 
					    <NuxtLink to="/">Go back home</NuxtLink>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -14,17 +14,11 @@ export default defineNuxtConfig({
 | 
				
			|||||||
  vite: {
 | 
					  vite: {
 | 
				
			||||||
    server: {
 | 
					    server: {
 | 
				
			||||||
      proxy: {
 | 
					      proxy: {
 | 
				
			||||||
        // "^/node_modules/.*": {
 | 
					        "^/node_modules/.*": {
 | 
				
			||||||
        //   target: "http://localhost:3000",
 | 
					          target: "http://localhost:3000",
 | 
				
			||||||
        //   changeOrigin: true,
 | 
					 | 
				
			||||||
        //   rewrite: (path) =>
 | 
					 | 
				
			||||||
        //     path.replace(/^\/node_modules\//, "/_nuxt/node_modules/")
 | 
					 | 
				
			||||||
        // },
 | 
					 | 
				
			||||||
        "^/remote/*": {
 | 
					 | 
				
			||||||
          target: "http://localhost:3005",
 | 
					 | 
				
			||||||
          changeOrigin: true,
 | 
					          changeOrigin: true,
 | 
				
			||||||
          rewrite: (path) =>
 | 
					          rewrite: (path) =>
 | 
				
			||||||
            path.replace(/^\/remote\//, "")
 | 
					            path.replace(/^\/node_modules\//, "/_nuxt/node_modules/")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -39,7 +33,7 @@ export default defineNuxtConfig({
 | 
				
			|||||||
          remotes: {
 | 
					          remotes: {
 | 
				
			||||||
            remote: `${MFE_HOST}/_nuxt/remoteEntry.js`
 | 
					            remote: `${MFE_HOST}/_nuxt/remoteEntry.js`
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          shared: ["vue", "pinia"]
 | 
					          shared: ["vue"]
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -47,7 +41,6 @@ export default defineNuxtConfig({
 | 
				
			|||||||
      plugins: []
 | 
					      plugins: []
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  plugins: ["~/plugins/pinia"],
 | 
					 | 
				
			||||||
  experimental: {
 | 
					  experimental: {
 | 
				
			||||||
    asyncEntry: true
 | 
					    asyncEntry: true
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
  "type": "module",
 | 
					  "type": "module",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "build": "nuxt build",
 | 
					    "build": "nuxt build",
 | 
				
			||||||
    "dev": " nuxt dev --host",
 | 
					    "dev": " nuxt dev",
 | 
				
			||||||
    "prebuild": "npm run clean",
 | 
					    "prebuild": "npm run clean",
 | 
				
			||||||
    "pregenerate": "npm run clean",
 | 
					    "pregenerate": "npm run clean",
 | 
				
			||||||
    "generate": "nuxt generate",
 | 
					    "generate": "nuxt generate",
 | 
				
			||||||
@ -15,15 +15,13 @@
 | 
				
			|||||||
    "serve": "serve .output/public -p 3000 --single"
 | 
					    "serve": "serve .output/public -p 3000 --single"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@pinia/nuxt": "^0.11.2",
 | 
					    "nuxt": "^3.13.0",
 | 
				
			||||||
    "nuxt": "^4.0.3",
 | 
					 | 
				
			||||||
    "pinia": "^3.0.3",
 | 
					 | 
				
			||||||
    "vue": "^3.5.13"
 | 
					    "vue": "^3.5.13"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@originjs/vite-plugin-federation": "^1.4.1",
 | 
					    "@originjs/vite-plugin-federation": "^1.3.5",
 | 
				
			||||||
    "rimraf": "6",
 | 
					 | 
				
			||||||
    "serve": "~14.2.4",
 | 
					    "serve": "~14.2.4",
 | 
				
			||||||
    "vite-plugin-top-level-await": "^1.6.0"
 | 
					    "rimraf": "6",
 | 
				
			||||||
 | 
					    "vite-plugin-top-level-await": "~1.4.4"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
    <div class="grid grid-cols-1 gap-4">
 | 
					    <div class="grid grid-cols-1 gap-4">
 | 
				
			||||||
      <Suspense>
 | 
					      <Suspense>
 | 
				
			||||||
        <template #default>
 | 
					        <template #default>
 | 
				
			||||||
          <RemoteContactRouter label="propsFromHost"  @increment="handleLog" />
 | 
					          <RemoteContactRouter />
 | 
				
			||||||
        </template>
 | 
					        </template>
 | 
				
			||||||
        <template #fallback>
 | 
					        <template #fallback>
 | 
				
			||||||
          <div>Loading remote component...</div>
 | 
					          <div>Loading remote component...</div>
 | 
				
			||||||
@ -14,42 +14,12 @@
 | 
				
			|||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup>
 | 
				
			||||||
import {
 | 
					import { defineAsyncComponent } from "vue"
 | 
				
			||||||
  __federation_method_getRemote as getRemote,
 | 
					 | 
				
			||||||
  __federation_method_setRemote as setRemote,
 | 
					 | 
				
			||||||
  __federation_method_unwrapDefault as unwrapModule,
 | 
					 | 
				
			||||||
  type IRemoteConfig
 | 
					 | 
				
			||||||
} from "virtual:__federation__";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 公共的 remote 配置
 | 
					const RemoteContactRouter = defineAsyncComponent(() =>
 | 
				
			||||||
const commonRemoteConfig: Partial<IRemoteConfig> = {
 | 
					  import("remote/RemoteContactRouter")
 | 
				
			||||||
  format: "esm", // 取决于你的 remoteEntry.js 构建方式
 | 
					)
 | 
				
			||||||
  from: "vite"
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const loadRemoteContactRouter = async () => {
 | 
					 | 
				
			||||||
  // 运行时注册 remote
 | 
					 | 
				
			||||||
  setRemote("remote", {
 | 
					 | 
				
			||||||
    ...commonRemoteConfig,
 | 
					 | 
				
			||||||
    url: "http://localhost:3003/remote/_nuxt/remoteEntry.js"
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 获取远程模块
 | 
					 | 
				
			||||||
  const remoteModule = await getRemote("remote", "./RemoteContactRouter");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 解包 default 导出。
 | 
					 | 
				
			||||||
  // 如果远程模块是命名导出,例如 `export const RemoteContactRouter = ...`
 | 
					 | 
				
			||||||
  // 那么你应该使用 `return remoteModule.RemoteContactRouter;`
 | 
					 | 
				
			||||||
  return await unwrapModule(remoteModule);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 3. 使用 defineAsyncComponent 来加载组件
 | 
					 | 
				
			||||||
  const RemoteContactRouter = defineAsyncComponent(loadRemoteContactRouter);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const handleLog = (count: number) => {
 | 
					 | 
				
			||||||
    console.log("count: ", count);
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style scoped></style>
 | 
					<style scoped></style>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,13 +1,3 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div>
 | 
					  <div>Index page</div>
 | 
				
			||||||
    Index page:
 | 
					 | 
				
			||||||
    <p>Count: {{ counter.$state.count }}</p>
 | 
					 | 
				
			||||||
    <button type="button" @click="() => counter.increment()">
 | 
					 | 
				
			||||||
      increment+ pinia
 | 
					 | 
				
			||||||
    </button>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
import { useCounter } from "@/stores/counter"
 | 
					 | 
				
			||||||
const counter = useCounter()
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +0,0 @@
 | 
				
			|||||||
import { createPinia } from "pinia"
 | 
					 | 
				
			||||||
import { defineNuxtPlugin } from "#app"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineNuxtPlugin((nuxtApp) => {
 | 
					 | 
				
			||||||
  const pinia = createPinia()
 | 
					 | 
				
			||||||
  // @ts-expect-error need global
 | 
					 | 
				
			||||||
  window.__mfeHostPinia = pinia
 | 
					 | 
				
			||||||
  nuxtApp.vueApp.use(pinia)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
							
								
								
									
										1813
									
								
								host/pnpm-lock.yaml
									
									
									
									
									
								
							
							
						
						
									
										1813
									
								
								host/pnpm-lock.yaml
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,24 +0,0 @@
 | 
				
			|||||||
import { defineStore } from "pinia"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const useCounter = defineStore("counter", {
 | 
					 | 
				
			||||||
  state: () => ({
 | 
					 | 
				
			||||||
    count: 100
 | 
					 | 
				
			||||||
  }),
 | 
					 | 
				
			||||||
  actions: {
 | 
					 | 
				
			||||||
    increment() {
 | 
					 | 
				
			||||||
      this.count += 1
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async asyncIncrement() {
 | 
					 | 
				
			||||||
      console.log("asyncIncrement called")
 | 
					 | 
				
			||||||
      await sleep(300)
 | 
					 | 
				
			||||||
      this.count++
 | 
					 | 
				
			||||||
      return true
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  getters: {
 | 
					 | 
				
			||||||
    getCount: (state) => state.count
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
# Env
 | 
					 | 
				
			||||||
@ -1,38 +1,24 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div>
 | 
					  <div>
 | 
				
			||||||
    <p>Label:{{ label }}</p>
 | 
					    <component v-if="asyncPageComponent" :is="asyncPageComponent" />
 | 
				
			||||||
    <component
 | 
					 | 
				
			||||||
      v-if="asyncPageComponent"
 | 
					 | 
				
			||||||
      :is="asyncPageComponent"
 | 
					 | 
				
			||||||
      @increment="(v: number) => emit('increment', v)"
 | 
					 | 
				
			||||||
    />
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup>
 | 
				
			||||||
import { defineAsyncComponent } from "vue"
 | 
					import { defineAsyncComponent } from "vue"
 | 
				
			||||||
import { useHostPinia } from "~/composables/useHostPinia"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const props = defineProps<{
 | 
					 | 
				
			||||||
  label: string
 | 
					 | 
				
			||||||
}>()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const emit = defineEmits<{
 | 
					 | 
				
			||||||
  (e: "increment", count: number): void
 | 
					 | 
				
			||||||
}>()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
useHostPinia()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @todo
 | 
					 * @todo
 | 
				
			||||||
 * it'll be nice if there is a way to dynamically match route and render..
 | 
					 * it'll be nice if there is a way to dynamically match route and render..
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					console.log(">>", window.location.pathname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Index = defineAsyncComponent(() => import("@/pages/contact/index.vue"))
 | 
					const Index = defineAsyncComponent(() => import("@/pages/contact/index.vue"))
 | 
				
			||||||
const Properties = defineAsyncComponent(
 | 
					const Properties = defineAsyncComponent(() =>
 | 
				
			||||||
  () => import("@/pages/contact/properties.vue")
 | 
					  import("@/pages/contact/properties.vue")
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let asyncPageComponent: unknown
 | 
					let asyncPageComponent
 | 
				
			||||||
if (/\/contact\/properties/.test(window.location.pathname)) {
 | 
					if (/\/contact\/properties/.test(window.location.pathname)) {
 | 
				
			||||||
  asyncPageComponent = Properties
 | 
					  asyncPageComponent = Properties
 | 
				
			||||||
} else {
 | 
					} else {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
import { onBeforeMount } from "vue"
 | 
					 | 
				
			||||||
import { setActivePinia } from "pinia"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function useHostPinia() {
 | 
					 | 
				
			||||||
  onBeforeMount(() => {
 | 
					 | 
				
			||||||
    console.log("RMT: init pinia store from host: ")
 | 
					 | 
				
			||||||
    // @ts-expect-error global pinia host
 | 
					 | 
				
			||||||
    setActivePinia(window.__mfeHostPinia || createPinia())
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,17 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
export default defineEventHandler((event) => {
 | 
					 | 
				
			||||||
  const allowedOrigin = 'http://localhost:3003'; // 替换为你的前端项目域名
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  console.log('event', event)
 | 
					 | 
				
			||||||
  // 设置 CORS 响应头,允许来自特定源的请求
 | 
					 | 
				
			||||||
  event.node.res.setHeader('Access-Control-Allow-Origin', allowedOrigin);
 | 
					 | 
				
			||||||
  event.node.res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
 | 
					 | 
				
			||||||
  event.node.res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 如果请求是预检请求 (OPTIONS),则直接返回 204
 | 
					 | 
				
			||||||
  if (event.node.req.method === 'OPTIONS') {
 | 
					 | 
				
			||||||
    event.node.res.writeHead(204);
 | 
					 | 
				
			||||||
    event.node.res.end();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@ -5,14 +5,12 @@ import topLevelAwait from "vite-plugin-top-level-await"
 | 
				
			|||||||
export default defineNuxtConfig({
 | 
					export default defineNuxtConfig({
 | 
				
			||||||
  compatibilityDate: "2024-04-03",
 | 
					  compatibilityDate: "2024-04-03",
 | 
				
			||||||
  devtools: { enabled: false },
 | 
					  devtools: { enabled: false },
 | 
				
			||||||
  ssr: true,
 | 
					  ssr: false,
 | 
				
			||||||
  nitro: {
 | 
					  nitro: {
 | 
				
			||||||
    // preset: "static",
 | 
					    preset: "static"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  vite: {
 | 
					  vite: {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    $client: {
 | 
					    $client: {
 | 
				
			||||||
      base: "/",
 | 
					 | 
				
			||||||
      plugins: [
 | 
					      plugins: [
 | 
				
			||||||
        topLevelAwait({
 | 
					        topLevelAwait({
 | 
				
			||||||
          promiseExportName: "__tla",
 | 
					          promiseExportName: "__tla",
 | 
				
			||||||
@ -24,20 +22,19 @@ export default defineNuxtConfig({
 | 
				
			|||||||
          exposes: {
 | 
					          exposes: {
 | 
				
			||||||
            "./RemoteContactRouter": "./components/RemoteContactRouter.vue"
 | 
					            "./RemoteContactRouter": "./components/RemoteContactRouter.vue"
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
          shared: ["vue", "pinia"]
 | 
					          // shared: []
 | 
				
			||||||
 | 
					          shared: ["vue"]
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    $server: {
 | 
					    $server: {
 | 
				
			||||||
      plugins: [
 | 
					      plugins: []
 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // build: {
 | 
					    // build: {
 | 
				
			||||||
    //   target: "esnext"
 | 
					    //   target: "esnext"
 | 
				
			||||||
    // }
 | 
					    // }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  modules: ["@pinia/nuxt"],
 | 
					 | 
				
			||||||
  experimental: {
 | 
					  experimental: {
 | 
				
			||||||
    asyncEntry: true
 | 
					    asyncEntry: true
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@
 | 
				
			|||||||
  "type": "module",
 | 
					  "type": "module",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "build": "nuxt build",
 | 
					    "build": "nuxt build",
 | 
				
			||||||
    "dev": "nuxt dev --host",
 | 
					    "dev": "HOST=0.0.0.0 PORT=3001 nuxt dev",
 | 
				
			||||||
    "prebuild": "npm run clean",
 | 
					    "prebuild": "npm run clean",
 | 
				
			||||||
    "pregenerate": "npm run clean",
 | 
					    "pregenerate": "npm run clean",
 | 
				
			||||||
    "generate": "nuxt generate",
 | 
					    "generate": "nuxt generate",
 | 
				
			||||||
@ -12,18 +12,16 @@
 | 
				
			|||||||
    "postinstall": "nuxt prepare",
 | 
					    "postinstall": "nuxt prepare",
 | 
				
			||||||
    "clean": "rimraf .output dist",
 | 
					    "clean": "rimraf .output dist",
 | 
				
			||||||
    "clean2": "rimraf --glob node_modules",
 | 
					    "clean2": "rimraf --glob node_modules",
 | 
				
			||||||
    "serve": "PORT=3005 node .output/server/index.mjs  --cors --single"
 | 
					    "serve": "serve .output/public -p 3001 --cors --single"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@pinia/nuxt": "^0.11.2",
 | 
					    "nuxt": "^3.13.0",
 | 
				
			||||||
    "nuxt": "^4.0.3",
 | 
					 | 
				
			||||||
    "pinia": "^3.0.3",
 | 
					 | 
				
			||||||
    "vue": "^3.5.13"
 | 
					    "vue": "^3.5.13"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@originjs/vite-plugin-federation": "^1.4.1",
 | 
					    "@originjs/vite-plugin-federation": "^1.3.5",
 | 
				
			||||||
    "rimraf": "6",
 | 
					 | 
				
			||||||
    "serve": "~14.2.4",
 | 
					    "serve": "~14.2.4",
 | 
				
			||||||
    "vite-plugin-top-level-await": "^1.6.0"
 | 
					    "rimraf": "6",
 | 
				
			||||||
 | 
					    "vite-plugin-top-level-await": "~1.4.4"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,27 +3,13 @@
 | 
				
			|||||||
    <h1>rmt/pages/contact/index.vue</h1>
 | 
					    <h1>rmt/pages/contact/index.vue</h1>
 | 
				
			||||||
    <div>Contact index</div>
 | 
					    <div>Contact index</div>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
      count: {{ count }} / counterFromPinia: {{ counter.$state.count }} <br />
 | 
					      count: {{ count }}
 | 
				
			||||||
      <button type="button" @click="count++">increment+ local</button>
 | 
					      <button type="button" @click="count++">increment+</button>
 | 
				
			||||||
      <button type="button" @click="handleIncrementPinia">
 | 
					 | 
				
			||||||
        increment+ pinia
 | 
					 | 
				
			||||||
      </button>
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup>
 | 
				
			||||||
import { useCounter } from "@/stores/counter"
 | 
					 | 
				
			||||||
const counter = useCounter()
 | 
					 | 
				
			||||||
const count = ref(0)
 | 
					const count = ref(0)
 | 
				
			||||||
 | 
					 | 
				
			||||||
const emit = defineEmits<{
 | 
					 | 
				
			||||||
  (e: "increment", count: number): void
 | 
					 | 
				
			||||||
}>()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const handleIncrementPinia = () => {
 | 
					 | 
				
			||||||
  counter.increment()
 | 
					 | 
				
			||||||
  emit("increment", counter.$state.count)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style scoped>
 | 
					<style scoped>
 | 
				
			||||||
.rmt {
 | 
					.rmt {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,14 +1,10 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="rmt2">
 | 
					  <div>
 | 
				
			||||||
    <h1>rmt/pages/contact/properties.vue</h1>
 | 
					    <h1>rmt/pages/contact/properties.vue</h1>
 | 
				
			||||||
    <div>Contact prop</div>
 | 
					    <div>Contact prop</div>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
      <button type="button" @click="handleClick">Click: {{ counter }}</button>
 | 
					      <button type="button" @click="handleClick">Click: {{ counter }}</button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="links">
 | 
					 | 
				
			||||||
      <NuxtLink to="/">Go to home</NuxtLink>
 | 
					 | 
				
			||||||
      <NuxtLink to="/about">About</NuxtLink>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
<script setup>
 | 
					<script setup>
 | 
				
			||||||
@ -22,13 +18,3 @@ definePageMeta({
 | 
				
			|||||||
  name: "contact-properties"
 | 
					  name: "contact-properties"
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					 | 
				
			||||||
<style scoped>
 | 
					 | 
				
			||||||
.rmt2 {
 | 
					 | 
				
			||||||
  background: pink;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
.links {
 | 
					 | 
				
			||||||
  display: flex;
 | 
					 | 
				
			||||||
  gap: 2rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,24 +0,0 @@
 | 
				
			|||||||
import { defineStore } from "pinia"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const useCounter = defineStore("counter", {
 | 
					 | 
				
			||||||
  state: () => ({
 | 
					 | 
				
			||||||
    count: 999
 | 
					 | 
				
			||||||
  }),
 | 
					 | 
				
			||||||
  actions: {
 | 
					 | 
				
			||||||
    increment() {
 | 
					 | 
				
			||||||
      this.count += 1
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async asyncIncrement() {
 | 
					 | 
				
			||||||
      console.log("asyncIncrement called")
 | 
					 | 
				
			||||||
      await sleep(300)
 | 
					 | 
				
			||||||
      this.count++
 | 
					 | 
				
			||||||
      return true
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  getters: {
 | 
					 | 
				
			||||||
    getCount: (state) => state.count
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user