Vue3 MF

在 Vue3 中,我们提供了两个示例项目供参考:

  • vue3-base:基础项目,用于书写通用业务组件对外暴露,它通常是一些项目的基石。
  • vue3-project:基础项目,用于和其他通用业务组件进行集成,它通常是一些项目的业务逻辑。

💡TIP:两个业务的 demo 仅仅只是部分依赖以及 emp 的配置不一样,你可以根据业务需求进行自由选择或者组合。

前期准备

在开始之前,请确保你已经配备了如下开发环境:

  • Node.js >= 20.0.0
  • npm >= 8

💡TIP:建议你使用 nvm 来管理 node 版本,直接执行 nvm use 20 命令即可完成开发环境设置

安装 emp⚡

快速上手

项目初始化

在对项目进行初始化之前,我们先克隆 emp 仓库,将示例代码拉取到本地。

git clone https://github.com/empjs/emp

🚨 如果你无法拉取项目至本地,请检查你的网络环境或代理设置是否可以访问 github,如果仍不能解决,请联系我们。

在拉取完成代码后,我们进入代码的根目录,安装项目依赖,推荐使用PNPM进行安装:

npm
yarn
pnpm
bun
npm install

运行示例项目

🚧 注意:在运行示例项目之前,请确保你已经完成了前期准备,并当前目录处于 emp 仓库的根目录下。

vue3 demo

首先进入示例项目的根目录:

# 运行 vue-3-base 示例项目
cd demos/vue3

然后运行代码:

npm
yarn
pnpm
bun
npm dev

运行成功后,您可以分别访问http://localhost:9302/http://localhost:9301/进行查看。

演示效果

:9301 基站效果:

:9302 应用效果:

远程组件调用

vue-3-project/src/Home.vue
<template>
  <div>
    <h1>Vue 3 Project</h1>
    <h2>vue3Base/TableComponent</h2>
    <TableComponent />
    <h2>vue3Base/JSXComponent</h2>
    <JSXComponent />
    <TsxScript attr1="aaa" :attr2="true" />
    <ButtonComponent attr1="bbb" :attr2="true" />
  </div>
</template>

<script lang="ts">
export default {
  name: 'App',
}
</script>

<script lang="ts" setup>
import TableComponent from '@v3/TableComponent'
import JSXComponent from '@v3/JSXComponent'
import TsxScript from '@v3/TsxScript'
import ButtonComponent from '@v3/ButtonComponent'
//
import { onMounted, onUnmounted, onBeforeMount } from 'vue'
onMounted(() => console.log('onMounted'))
onUnmounted(() => console.log('onUnmounted'))
onBeforeMount(() => console.log('onBeforeMount'))

</script>

<style lang="less" scoped></style>

项目配置

vue-3-base/emp.config.ts
import {defineConfig} from '@empjs/cli'
import lightningcss from '@empjs/plugin-lightningcss'
import Vue3 from '@empjs/plugin-vue3'
import {pluginRspackEmpShare} from '@empjs/share'
export default defineConfig(() => {
  return {
    plugins: [
      Vue3(),
      lightningcss(),
      pluginRspackEmpShare({
        name: 'vue3Base',
        // dts: {
        //   consumeTypes: true,
        //   generateTypes: {
        //     compilerInstance: 'vue-tsc',
        //   },
        // },
        shared: {
          vue: {
            requiredVersion: '^3',
          },
        },
        exposes: {
          './ButtonComponent': './src/components/ButtonComponent',
          './TableComponent': './src/components/TableComponent',
          './JSXComponent': './src/components/JSXComponent',
          './TsxScript': './src/components/TsxScript',
          './Antd': './src/Antd',
          './Home': './src/Home',
        },
      }),
    ],
    appEntry: 'main.ts',
    server: {port: 9301, open: false},
    html: {title: 'EMP Vue3 Base'},
    debug: {
      clearLog: false,
      showRsconfig: false,
    },
  }
})
vue-3-project/emp.config.ts
import {defineConfig} from '@empjs/cli'
import Vue3 from '@empjs/plugin-vue3'
import {pluginRspackEmpShare} from '@empjs/share'
// cf vue3
const deploy = process.env.DEPLOY
const isCf = deploy === 'cloudflare'
//
export default defineConfig(store => {
  const ip = store.getLanIp()
  const vue3Base = isCf ? 'https://mf-vue3.sc.empjs.dev/host/emp.js' : `http://${ip}:9301/emp.js`
  return {
    plugins: [
      Vue3(),
      pluginRspackEmpShare({
        name: 'vue3Project',
        shared: {
          vue: {
            requiredVersion: '^3',
          },
        },
        remotes: {
          '@v3': `vue3Base@${vue3Base}`,
        },
      }),
    ],
    appEntry: 'main.ts',
    server: {port: 9302},
    html: {title: 'EMP Vue3 Projects'},
    debug: {
      clearLog: false,
      showRsconfig: false,
    },
  }
})

常见问题

使用yarn无法启动项目,缺失部分module

在Vue项目中,我们使用了 @empjs/plugin-vue2@empjs/plugin-vue3 两个插件,在实际开发中,我们注意到了这个模块缺失导致的问题。 这是因为在这两个插件中,我们引用了 vue-loader 这个依赖,而这个依赖又依赖于 webpack, 由于yarn的包管理机制,我们无法在高版本的Node版本下安装 webpack 的低版本,所以导致了这一问题的发生。

目前对于这个问题的解决,我们提供了两种方案进行选择:

  • (✨推荐) 使用 pnpm 包管理器解决这一问题。由于pnpm在这种情况下,会自动将webpack安装更为适合当前node版本的版本,而不是抛出警告然后不安装它,所以使用pnpm可以完美解决这一问题。

  • 如果你想继续使用yarn,您可以手动安装 webpack 这一依赖,具体安装命令如下:

    yarn add webpack

如果您在npm中遇到类似的问题,您也可以尝试这两个方案进行解决。