一、业务场景
最近有一个项目**“低代码开发平台”**:对设计器的源码进行修改,成功扩展新模块,通过封装函数并导出,增强了可视化设计器的功能性和可复用性。
功能点:退拽生成动态表单,并且绑定字段,返回给后端生成MySQL数据库表
但是原本的依赖是没有这个 数据库 模块,一开始采用的是依赖的开发文档的开放API进行模块扩展,但是由于依赖还在不断地迭代,有些开放函数/API 最后也没了,影响了我们自己的项目,所以经过多方查看,接触到一个前端的新概念:web前端工程化 monorepo
简单来说就是:**在项目中引入项目中的模块文件,打包成依赖给项目本身使用。**类似于以下示例图:
二、web前端工程化 – monorepo介绍
注释:monorepo这个工具用来管理多个不同项目的单一库,项目与项目之间可能有相关联系,但是逻辑又是独立互不影响。
前端Monorepo这个东西其实本质上来说,就是指的是将『一个项目的所有前端代码存储在一个统一的代码仓库中』的开发的模式。
传统的一般的前端开发,就是一个项目去npm去下载不同的库来辅助主项目,而npm中的单个库都是独立的代码仓库,当需要安装的npm包越来越多的时候,我们需要去各个仓库里面维护管理多个独立的库就变得越来越困难,越来越庞大。
那么monorepo就是思想就是,将多个应用程序、库和模块组织在同一个代码仓库里,使用统一的版本控制系统进行管理。
这就是web前端工程化。
monorepo 就一定需要专门的工具(库)才能实现吗?
答案当然是否定的,严格意义上说,只要将多个项目放在一个存储库里就算 monorepo。
现在主流的 monorepo 所承担的责任并不只是存储的问题,还可以承担比如依赖管理,增量构建等一系列工程化的功能,已经成为工程化技术中非常有价值的一块领域,所以有时你为了实现某个特殊的功能不得不借助社区的力量,或者站在大佬的肩膀上。
monorepo是什么
monorepo 是一个单个 git 存储库,可容纳多个应用程序和库的源代码以及它们的工具。
目前 Babel, Angular, React,Vue, Ember, Meteor, Jest等许多开源项目都使用该种模式来管理代码。
三、具体实操
1、首先创建一个my-monorepo文件夹;
2、确保安装了包管理工具pnpm;
3、利用 pnpm init 在根目录初始化;
4、 新建两个文件夹:apps和packages
在 packages 文件下创建存放 公共的东西:比如公共函数、模块等。
在此说明:packages下主要是为了用来放表单设计器的源码(源码来自Gitee),我是直接复制过来放进去的
5、在根目录创建 pnpm-workspace.yaml 文件;
packages:
# 放置各种项目
- "apps/*"
# 放置各种公共模块
- "packages/*"
pnpm-workspace.yaml 文件的作用是定义一个 pnpm 工作区,它允许你在多个包之间共享依赖项和代码。这个文件通常位于项目的根目录下,包含了工作区中所有包的信息。
这个配置文件告诉 pnpm,所有的包都在 packages 和apps目录下。当你运行 pnpm install 时,pnpm 会自动安装所有在 packages 和apps目录下的包及其依赖项。
6、跨项目安装依赖包
"devDependencies": {
"@epic-designer/core": "workspace:*",// 直接在引用里面写然后指定为`workspace:*`
"@epic-designer/script": "workspace:*",
"@epic-designer/ui": "workspace:*",
"@epic-designer/utils": "workspace:*",
"epic-designer": "workspace:*"
}
这里的"@epic-designer/core": "workspace:*"的的意思就是说,指定依赖项是从这个工作区里面去找的那个包,安装过来,平常一般我们这里的话就是写版本号嘛,
但是monorepo这里就是无论啥版本,去安装现在工作区(workspace)里面的这个@test/api的现有版本,不需要每次都去手动更改依赖项的版本号这个意思。
pnpm install 一下,就可以看到 my-monorepo 的vue项目就有这个epic-designer的包了。
这样我就能直接去改源码,然后在apps中的某个项目中就能直接使用epic-designer源码修改以后得成果,摆脱原作者不停更新版本带来的不稳定性。
7、项目中实际使用epic-designer
在apps文件下创建两个正常的vite项目,可以是很多个,我列举了两个,根据实际情况自定义
在 apps文件下执行以下语句:
pnpm create vite 项目名称
web文件就是一个完整的vite项目:
在项目中可以正常调用刚刚在根目录下面的依赖:@epic-designer/core
<template>
<EDesigner
ref="designerRef"
@save="handleSubmit"
title="EDesigner数据回显示例"
>
<template #header-prefix>
<div>欢迎使用EDesigner设计器</div>
</template>
</EDesigner>
</template>
<script lang="ts" setup>
import { EDesigner, type PageSchema } from "@epic-designer/core";
import { ref, onMounted } from "vue";
const designerRef = ref<InstanceType<typeof EDesigner>>();
</script>
实际的页面效果:
在web文件
至此完成了项目的工程化,实现依赖本地化,对于不稳定依赖或者模块,这样的工程化方式是很有用的。
四、项目打包
我虽然实操可行,但是我有一个疑问,担心web这个项目打包以后会失去@epic-designer/core依赖。
一开始还是很担心在根目录下面的公共依赖会不会不参与打包,于是尝试了一下,发现在element参与打包了,element是根目录下的依赖: