具有组合前端/后端功能(Vue 和 Express)的插件架构

Posted

技术标签:

【中文标题】具有组合前端/后端功能(Vue 和 Express)的插件架构【英文标题】:Architecture for plugins with combined frontend/backend functionality (Vue and Express) 【发布时间】:2022-01-03 18:38:54 【问题描述】:

我有一个带有 Vue CLI 生成的前端应用程序和一个 Express 后端应用程序的存储库。该 repo 设置为标准 Vue CLI 应用程序,具有***后端 src 文件夹。 Express 应用定义了一些 JSON API 并提供已编译的 Vue 应用的静态文件。

我想为它构建一个插件系统:插件创建新的 API 端点,但可以选择创建 .vue 单文件组件以在前端使用。这些 SFC 将通过 Vue 路由器中动态生成的路由公开。最终,插件将位于专用的 NPM 包中。

我遇到的问题是如何从前端 src 树之外的位置正确导入这些 .vue 组件。目前我正在这样做:

// vue.config.js

// generated dynamically with fs.readDirSync
process.env.VUE_APP_PLUGINS = JSON.stringify([
  name: 'my-plugin',
  component: '/path/to/src-backend/plugins/my-plugin/my-plugin.vue'
];
// router.js

JSON.parse(process.env.VUE_APP_PLUGINS).forEach(plugin => 
  routes.push(
    name: plugin.name,
    path: `/plugins/$plugin.name`,
    component: import(plugin.component)
  );
);

我在导入调用时遇到前端错误:Uncaught (in promise) Error: Cannot find module '/full/path/to/my-plugin.vue'。这是有道理的,因为浏览器无法从我的文件系统中读取。

我还尝试在 vue.config.js 中创建别名,并使用更短的别名模块路径,如下所示:

// vue.config.js

module.exports = 
  // [...]
  configureWebpack: 
    resolve: 
      alias: 
        '@plugins': path.resolve(__dirname, 'src-backend/plugins')
      ,
      extensions: ['vue', 'js', 'json']
    
  

可能有一种方法可以解决这种依赖关系解决问题,但我也质疑我的架构是否是最好的方法。谢谢你的建议。

【问题讨论】:

【参考方案1】:

我发现了动态导入失败的问题。 Webpack 引擎对传递给import() 的表达式非常讲究。它必须能够推断出有关起始路径和理想文件名的信息。这是解决方案:

// vue.config.js

// generated dynamically with fs.readDirSync
process.env.VUE_APP_PLUGINS = JSON.stringify([
  name: 'my-plugin',
  component: 'my-plugin-component'
];

moduel.exports = 
  // ...

  // setup alias for cleaner path in frontend import
  configureWebpack: 
    resolve: 
      alias: 
        '@plugins': path.resolve(__dirname, 'src-backend/plugins')
      
    
  

// Vue router.js

JSON.parse(process.env.VUE_APP_PLUGINS).forEach(comp => 
  routes.push(
    path: `/plugins/$comp.name/$comp.component`,
    name: `$comp.name-$comp.component`,
    component: () => import('@plugins/' + comp.name + '/components/' + comp.component + '.vue')
  );
);

在字符串文字中包含@plugins/ 非常重要,包含.vue 也是如此,我认为这可以防止它在前端预加载我不想要的仅后端js 文件。

当我过渡到 NPM 模块时,我仍然担心这个插件架构,但它现在可以工作。

【讨论】:

以上是关于具有组合前端/后端功能(Vue 和 Express)的插件架构的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将自定义错误从后端(Express)传递到前端(Vue)

单独的 Vue 前端和 Express 后端的 NGINX 设置

Vue.js+express建站

Express - 使用 axios 返回具有命名路由参数的某些文档

Vue 全家桶 + Express 实现的博客(后端API全部自己手写)

Vue 全家桶 + Express 实现的博客(后端API全部自己手写)