多系统集成:vue大型项目之分模块运行/打包

2023-11-18

本文以vue-cli3+为例,实现多系统集成下的分模块打包。分模块打包方式多种多样,下文可适用于多系统之间互不干扰,主系统可集成各子系统,各子系统又可单独运行的业务场景。

一、目标

我们要实现什么?所谓分模块打包,那么各个模块内就必须得有自己独立的入口文件,路由文件。按照这种构想,我在一个新的脚手架src目录下新建了一个projects目录:
图1
如上图,可以看到Aproject、B、C、D四个项目。我在A项目中建了assets,common和views文件夹,其中assets可以再建img和css的文件夹,common内可以放公共组件或者方法,views页面可以放页面,甚至你还可以建一个components文件夹专门用来放组件。

好了,我们的视图目录结构大概就是上面的样子。我们期待的是,我们可以打包这个A模块这个‘小vue’,就像打包一个完整vue的项目一样。那么如何实现这部分呢?


二、打包单个模块

我们知道,在package.json中,有项目启动,打包的命令。
在这里插入图片描述

我们可以从这里入手。

这里就不得不提到cross-env这个模块了。
我们之前在设置生产环境,测试环境,开发环境时也会用到这个模块。在这里不详细表述了。

cross-env:npm install --save-dev cross-env

现在我们的思路大概是这样的,当我们执行打包命令的时候,通过cross-env去找到我们的入口文件,然后再打包。

所以我们可以模仿环境变量的写法,在package中写入如下图代码。
在这里插入图片描述
代码:

    "dev:projectA": "cross-env PROJECT_NAME=projectA vue-cli-service serve",
    "dev:projectB": "cross-env PROJECT_NAME=projectB vue-cli-service serve",
    "dev:projectC": "cross-env PROJECT_NAME=projectC vue-cli-service serve",
    "dev:projectD": "cross-env PROJECT_NAME=projectD vue-cli-service serve",
    "build:projectA": "cross-env PROJECT_NAME=projectA vue-cli-service build",
    "build:projectB": "cross-env PROJECT_NAME=projectB vue-cli-service build",
    "build:projectC": "cross-env PROJECT_NAME=projectC vue-cli-service build",
    "build:projectD": "cross-env PROJECT_NAME=projectD vue-cli-service build",

写完了这些,我们就可以着手模仿vue配置小vue的文件了。

  • 在main.js中配置如下代码:
        import Vue from "vue";
		import App from "./App.vue";
		import router from "./router";
		import store from "./store";
		
		Vue.config.productionTip = false;
		
		new Vue({
		    router,
		    store,
		    render: h => h(App)
		}).$mount("#app");
  • 在App.vue中配置如下代码:
        <template>
		  <div id="app">
		    <router-view />
		  </div>
		</template>
		
		<style lang="less">
		
		</style>
  • 在router.js中配置如下代码
		import Vue from "vue";
		import Router from "vue-router";
		import Home from "./views/Home.vue";
		
		Vue.use(Router);
		
		export default new Router({
		  routes: [
		    {
		      path: "/",
		      name: "home",
		      component: Home
		    }
		  ]
		});
  • 在page文件夹中建立Home.vue,写入如下代码:
		<template>
		  <div>
		    我是a项目
		  </div>
		</template>
		
		<script>
		export default {};
		</script>
		
		<style></style>
  • 在项目最外层建立config文件夹,在其中新建projectsConfig.js写入:
const config = {
  projectA: {
    pages: {
      index: {
        entry: "src/projects/projectA/main.js",
        template: "public/index.html",
        filename: "index.html"
      }
    },
    devServer: {
      port: 8080, // 端口地址
      open: false, // 是否自动打开浏览器页面
      host: "0.0.0.0", // 指定使用一个 host,默认是 localhost
      https: false, // 使用https提供服务
      disableHostCheck: true,
      // 设置代理
      proxy: {
        "/eopenhapi": {
          target: "http://open.jdpay.com",
          changeOrigin: true
        },
        "/hapi": {
          target: "http://open.jdpay.com",
          changeOrigin: true
        }
      }
    }
  },
  projectB: {},
  projectC: {}
};
module.exports = config;
  • 把projectsConfig.js并入vue.config.js,vue.config.js中代码如下
const config = require("./config/projectsConfig.js");
let projectName = process.env.PROJECT_NAME;

module.exports = {
  ...config[projectName],
  // pages: conf.pages,

  // 基本路径
  // baseUrl: './',//vue-cli3.3以下版本使用
  publicPath: "./", // vue-cli3.3+新版本使用

  // 输出文件目录
  outputDir: "dist/" + projectName + "/"
};

写到这里我们就建立一个完整的小vue了。

  • 运行命令 cnpm run dev:projectA
    在这里插入图片描述

  • 运行命令 cnpm run build:projectA
    在这里插入图片描述
    效果完美。

三、打包总项目及子系统

一个大型项目必然会有公共模块,这里会写一个导航栏作为公共组件。

  1. 在projects下建立公共模块的文件夹common,写入前面A项目的目录结构,如图:
    在这里插入图片描述
  2. 在package.json中写入运行命令和打包命令。
 "dev:common": "cross-env PROJECT_NAME=common vue-cli-service serve",
 "build:common": "cross-env PROJECT_NAME=common vue-cli-service build",
  1. 在Home.vue中写公共导航

    这里会使用iview作为ui组件,但也因此有一个问题,我的A,B,C,D四个项目每个项目引入一遍UI框架,那打包出来整个项目将会非常的大,所以我们在项目必须采用按需引入的方式。(项目中还是下载整个ivew)

写入如下代码:

<template>
  <div class="main-content">
    <Layout>
      <header class="head-box">
        <Menu
          mode="horizontal"
          theme="primary"
          active-name="1"
          @on-select="menuClick"
        >
          <div class="layout-logo">Oralinge</div>
          <div class="layout-nav">
            <div class="layout-nav-content">
              <!-- 系统列表 -->
              <span v-for="(item, index) in systemList" :key="index">
                <MenuItem
                  :name="item.basepath + '?systemId=' + item.systemId"
                  @click="go(item)"
                >
                  <Icon type="ios-navigate"></Icon>
                  {{ item.title }}
                </MenuItem>
              </span>
            </div>
          </div>
          <div class="layout-right">
            <Dropdown>
              <!-- 登录姓名 -->
              <a href="javascript:void(0)">
                {{ user.userName }}
                <Icon type="ios-arrow-down"></Icon>
              </a>
              <!-- 退出登录 -->
              <DropdownMenu slot="list">
                <DropdownItem name="logout">退出登录</DropdownItem>
              </DropdownMenu>
            </Dropdown>
          </div>
        </Menu>
      </header>
    </Layout>
    <iframe
      :src="systemUrl"
      width="100%"
      height="100%"
      frameborder="0"
      class="iframe"
      id="bossIframe"
    ></iframe>
  </div>
</template>
<script>
import {
  Layout,
  Menu,
  MenuItem,
  Dropdown,
  DropdownItem,
  DropdownMenu
} from "view-design";

export default {
  components: {
    Layout,
    Menu,
    MenuItem,
    Dropdown,
    DropdownItem,
    DropdownMenu
  },
  data() {
    return {
      systemUrl: "",
      isFullscreen: false,
      loading: false,
      systemList: [
        {
          title: "A项目",
          basepath: "http://localhost:8080/#/",
          systemId: "A"
        },
        {
          title: "B项目",
          basepath: "http://localhost:8082/#/",
          systemId: "B"
        },
        {
          title: "C项目",
          basepath: "http://localhost:8083/#/",
          systemId: "c"
        },
        {
          title: "D项目",
          basepath: "http://localhost:8084/#/",
          systemId: "D"
        }
      ],
      user: {}
    };
  },
  mounted() {
    this.systemUrl =
      this.systemList[0].basepath + "?systemId=" + this.systemList[0].systemId;
  },
  methods: {
    menuClick(name) {
      this.systemUrl = name;
    }
  }
};
</script>

<style lang="less" scoped>
@head-height: 50px;
.main-content {
  height: 100%;
  padding-top: @head-height;
  box-sizing: border-box;
  overflow: hidden;
}
.head-box {
  width: 100%;
  height: @head-height;
  line-height: @head-height;
  position: fixed;
  top: 0;
  left: 0;
  min-width: 1200px;

  .ivu-menu-horizontal {
    height: 100%;
    line-height: @head-height;
  }
  .layout-logo {
    display: inline-block;
    width: 200px;
    color: #fff;
    font-size: 28px;
    text-align: center;
    vertical-align: top;
    position: absolute;
    left: 0;
    top: 0;
    background-color: #2d8cf0;
    z-index: 5;
  }
  .layout-nav {
    display: inline-block;
    width: 100%;
    height: 100%;
    padding-left: 200px;
    padding-right: 100px;
    box-sizing: border-box;
    overflow-x: auto;
    z-index: 4;
    &-content {
      //   width: 100%;
      overflow: hidden;
      height: 100%;
    }
  }
  .layout-right {
    padding-right: 20px;
    padding-left: 20px;
    position: absolute;
    right: 0;
    top: 0;
    background-color: #2d8cf0;
    z-index: 5;
    a {
      color: #fff;
    }
  }

  .ivu-menu-item-active {
    font-size: 20px;
  }
}
</style>

效果:
在这里插入图片描述
B项目使用同样的方法配置文件。
配置后效果如下:
在这里插入图片描述

到这里,我们就基本实现了分模块运行以及集体运行了。

下面看一下打包。
在分别运行了B项目和common的打包命令以后,效果正常。
在这里插入图片描述
另外,我在这里采用了iframe的方式嵌入了其他项目,是因为引入的方式打包的时候会打包太多。

这样做的好处就是公共项目仅仅作为一个外壳使用,其他项目与其并没有太多的关联,保证了每个项目模块的独立性。


四、demo地址

https://github.com/Oralinge/pointsmodule


以上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多系统集成:vue大型项目之分模块运行/打包 的相关文章

随机推荐

  • Django快速开发(精简版)

    1 使用虚拟环境 workon 虚拟环境名 2 退出虚拟环境 deactivate dajngo框架开发的大体流程 1 创建环境 mkvirtualenv 虚拟环境名 删除 rmvirtualenv 虚拟环境名 virtualenv p u
  • SMTP发送邮件

    SMTP是发送邮件的协议 Python内置对SMTP的支持 可以发送纯文本邮件 HTML邮件以及带附件的邮件 Python对SMTP支持有smtplib和email两个模块 email负责构造邮件 smtplib负责发送邮件 首先 我们来构
  • vue +C# mvc 坑

    1 把input标签放入到form表单中后 再将input中的值新增到数据库后 界面会刷新 解决 删除form 标签 原因待查
  • win11 安装opencv-python

    首先下载python3 7以上版本 installer版本 选择安装pip 添加环境 cmd 打开终端 pip install i https pypi tuna tsinghua edu cn simple opencv python p
  • List集合给另一个List集合赋值问题(即浅拷贝与深拷贝)

    问题 java中将一个list的内容复制给另一个list之后 去新的list进行操作的时候 原来的list也会发生变化 解决方案 直接采用 进行的复制属于浅层赋值 两者指向的使用一个地址 所以操作一个时另一个也会发生变化 如果不想出现这样的
  • 搜索插入位置 JavaScript

    在有序数组中查找 无则插入 元素 返回索引 题目详情 https leetcode cn com problems search insert position description 遍历数组查找 插入 查找比较简单 插入时会麻烦一些 如
  • Java中的String用法

    新手Java程序员了解String类型 1 String是什么数据类型 String在定义上是java lang包下的一个类 它不是基本的数据类型 String是不可变的 JVM使用字符串池来存储所有的字符串对象 2 创建String对象的
  • 阅读书源最新2020在线导入_最最最最最好用的小说神器,全网书源免费用!

    今天给大家分享的是小说软件 为了满足所有小伙伴的需求 今天安卓和苹果都安排上了 一款Android应用 一款iOS应用 两款应用都十分相似 都是可以自行添加书源的软件 几乎覆盖全网小说 阅读 Android 软件本身是没有任何资源的 如果不
  • elasticsearch心得体会

    1 聚合搜索的字段如果是求和的情况下 字段不能为string类型 那么排序时字段要求是不是也一样呢
  • Qt中带token的Http请求

    详细代码 get请求 QTimer timer timer setInterval 5000 设置超时时间 timer setSingleShot true 单次触发 if m pGetManager delete m pGetManage
  • gstreamer中tee如何实现动态增减支路(预览+截图+录像)

    系列文章目录 Gstreamer中获取帧数据的方式 gstreamer中如何使用probe 探针 获取帧数据 gstreamer拉流rtsp使用appsink获取帧数据 预览 截图 gstreamer中如何使用fakesink获取帧数据 预
  • Vue3/ Vue3 生命周期 钩子函数 总结 、Vue3 内 主要 钩子函数 、Vue2 和 Vue3 生命周期钩子函数对比

    一 Vue3 生命周期 钩子函数 总结 1 介绍 Vue组件简介 Vue是组件haul编程 从一个组件诞生到消亡 会经历很多过程 这些过程就叫做生命周期 例如 生命周期就是人出生到入土是一样的 有少年时期 青年时期 中年时期 老年时期 每个
  • Requests

    REQUESTS的基本操作 参考崔庆才爬虫 GET请求 import requests r requests get http www gdsgj com r encoding r apparent encoding 根据从返回内容中解析的
  • 构造函数不能被继承

    构造函数不同于其他类方法 因为他创建新的对象 而其他类方法只是被现有的对象调用 这是构造函数不被继承的原因之一 继承意味着派生类对象可以使用基类的方法 然而 构造函数在完成工作之前 对象并不存在 构造函数不能是虚函数 创建派生类对象时 将调
  • springboot项目获取真实用户ip(不是虚拟ip)

    最近在工作中遇见一个业务场景是获取用户真实的ip地址 就跟现在网上评论展示ip一样的业务场景 然后自己就去了解了一下 1 pom依赖配置
  • 数据库模式分解(应该比较易懂吧)

    数据库模式分解 部分函数依赖 函数依赖的确定 1对1的关系时 有两个函数依赖 1对多时 有一个函数依赖 多对多时 没有函数依赖 函数依赖类型 右 边 不 为 左 边
  • DVWA-XSS (Reflected)

    大约 跨站点脚本 XSS 攻击是一种注入问题 其中恶意脚本被注入到原本良性和受信任的网站上 当攻击者使用 Web 应用程序发送恶意代码 通常以浏览器端脚本的形式 时 就会发生 XSS 攻击 给其他最终用户 允许这些攻击成功的缺陷非常普遍 并
  • 机器学习论文总结

    作者简介 洪亮劼 Etsy数据科学主管 前雅虎研究院高级经理 长期从事推荐系统 机器学习和人工智能的研究工作 在国际顶级会议上发表论文20余篇 长期担任多个国际著名会议及期刊的评审委员会成员和审稿人 责编 何永灿 欢迎人工智能领域技术投稿
  • csgo修改服务器时间,csgo热身时间参数指令 热身时间怎么改

    反恐精英 全球攻势 简称CS GO 是一款由VALVE与Hidden Path Entertainment合作开发的第一人称射击游戏 游戏中可以更改相关控制命令 下面带来csgo热身时间参数指令 热身时间怎么改方法 csgo热身时间参数指令
  • 多系统集成:vue大型项目之分模块运行/打包

    本文以vue cli3 为例 实现多系统集成下的分模块打包 分模块打包方式多种多样 下文可适用于多系统之间互不干扰 主系统可集成各子系统 各子系统又可单独运行的业务场景 一 目标 我们要实现什么 所谓分模块打包 那么各个模块内就必须得有自己