多项目的组件共用方案

6,263 阅读5分钟

现如今,前端开发基本离不开模块化了,那么多项目的组件共用就会变成一个比较头疼的问题,很多人都习惯ctrl c和ctrl v,这样容易导致项目中后期维护困难,我们当然也不能这么low,早期在项目开发中我也探索了几个组件共用的方案。

解决方案

方案一 cdn/服务器

使用cdn引入组件的方案应该是减少打包时间以及访问时间最显著的方案了,但是缺点也非常明显,就是组件频繁更新时,需要频繁刷新cdn。

将打包好的组件文件放在服务器上同理,更新频繁的时候也是需要频繁更新服务器上的文件,不方便。

方案二 发布至npm

我最早的时候也是把很多组件文件发布至npm上,这样组员可以很方便的获取组件资源,但是问题亦非常明显,首先,npm的访问速度不稳定,很多时候需要借助某些上网手段,其次,频繁更新npm,也会带来一长串的版本号,发布的时候也非常的麻烦;而使用国内镜像源,又需要等待镜像同步,也比较耗时;至于发布至npm私服,我估计大部分中小公司都没有建立npm私服。

方案三 使用git submodule

git可以使用git submodule直接将一个git仓库当做子模块放在项目中,只需要

git submodule add <url> <path>

其中,url为子模块的路径,path为该子模块存储的目录路径。 该方法的一大问题是git submodule使用起来异常的繁琐,比如删除,甚至没有一个专门的命令,必须借助一系列操作才能完成,最后考虑到项目组成员接受度的问题,放弃了这个方案。

方案四 在package.json依赖中使用git地址

这个方案是我目前依然在使用的最好的方案,没有额外的学习成本,封装好后使用方便,下面将详细介绍次方案。

以vue-cli项目为例(react项目原理一模一样,自己套用即可)

文件结构

vue项目的主要文件结构如以下所示

├─src
|  └─components
|      └─IframeCom
|          └─index.vue
├─package.json
├─script.js
├─vue.config.js

其中,components是放置于src文件夹下的组件文件夹,IframeCom是其中的一个组件文件夹,里面的index.vue即为暴露出的IframeCom的组件文件。

生成导出入口的脚本

script.js文件为写入导出文件的脚本文件,其内容如下:

const fs = require('fs');
const path = require('path');

// 生成导出文件
fs.readdir(path.join(__dirname, './src/components'), function (err, files) {
  if (err) {
     console.log('目录不存在')
     return
  }
  // 设置时间以提交git
  let content = `/*${new Date()}*/`
  let ex = []
  // 处理导出代码
  files.forEach(item => {
    // 读取目录名
    content = content + `import ${item} from './components/${item}';`
    ex.push(item)
  })
  ex = ex.join(",")
  content = content + `export { ${ex} }; `

  fs.writeFile(path.join(__dirname, './src/index.js'), content, 'utf8', (err) => {
    if (err) throw err;
  });
})

执行

node script.js

即可在src的目录下生成一个index.js文件,此文件即为导出组件的入口,内容如下(写入时间注释是为了确保git commit一定有东西提交):

/*Tue Jun 09 2020 14:07:43 GMT+0800 (GMT+08:00)*/import IframeCom from './components/IframeCom';export { IframeCom }; 

vue.config.js设置

因为组件一般样式比较少,所以直接打包进js中,在vue.config.js中写入

module.exports = {
  css: { extract: false }
};

package.json设置

之后在package.json文件中写好打包命令:

{
  "name": "compoment-demo",
  "version": "0.1.2",
  "private": false,
  "main": "lib/pikaz-compoment.umd.min.js",
  "scripts": {
    "lib": "vue-cli-service build --target lib --name pikaz-compoment --dest lib src/index.js",
    "serve": "vue-cli-service serve",
    "push": "node script.js && npm run lib && git add . && git commit -m 'commit' && git push"
  }
}

其中的lib命令

"vue-cli-service build --target lib --name compoment-demo --dest lib src/index.js"

为打包库的命令,--name后面跟着的compoment-demo是库的名称,随便填写,最后的src/index.js为项目入口,指定为src目录下的index.js文件即可。

再写一个上传git仓库的命令(需之前已连接远程仓库)

"push": "node script.js && npm run lib && git add . && git commit -m 'commit' && git push"

即先执行script.js文件生成库入口index.js文件,再执行打包库的命令,最后上传至git,一步到位,简化操作。

主项目的package.json设置

{
  "name": "project-demo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "npm install compoment-demo && vue-cli-service build"
  },
  "dependencies": {
    "compoment-demo": "git+https://github.com/pikaz-18/compoment-demo.git",
    "core-js": "^3.6.5",
    "vue": "^2.6.11"
  }
}

在dependencies依赖中写入组件库的地址,格式为git+git仓库地址,之后只需执行npm install compoment-demo即可安装与更新项目依赖,并将此命令写入打包命令中,确保每一次打包使用的组件库依赖都为最新的。

主项目中组件的使用

<template>
  <div class="demo">
    <iframe-com></iframe-com>
  </div>
</template>
<script>
import { IframeCom } from 'compoment-demo'
export default {
  name: 'App',
  components: {
    IframeCom
  }
}
</script>

和普通的组件一样的使用方法

项目demo地址

组件库

主应用项目

优点

最大的优点便是使用便捷,组件项目执行一个命令即可完成打包上传,不需要进行额外操作,主项目在打包的时候也可以实时更新组件库,使用时完全无感知,并且大部分公司都有搭建gitlab等,再不济也可以使用码云,使用成本可以说是非常低,更新速度也非常快。

最后

这仅仅是一个简易的组件共用demo,大家可以根据自己的项目需求去完善。你甚至可以把整个项目当做库导出,将每个页面当做基本组件,从而将多个项目的页面自由组合成一个saas系统,而且该方案并没有太大的侵入性,改造旧项目也是轻而易举,再也不用担心老板想要一个项目加入其他项目已有的功能而烦恼了,彻底扔掉无脑cv吧。

不过如果项目过大时,此方案也会带来打包时间过长,项目臃肿等问题,这个时候可能就需要使用微前端了。

如果觉得对你有帮助的话,不妨点个赞吧。