Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于基于 Vue CLI 进行企业内二次开发的思考和问题 #2

Open
screetBloom opened this issue Jul 8, 2021 · 2 comments
Open

Comments

@screetBloom
Copy link
Owner

screetBloom commented Jul 8, 2021

背景

我本人是 Vue CLI 生态技术的爱好者,期望可以基于 Vue CLI 进行企业内的跨 Vue/React 技术栈的二次定制


企业内的二次定制

1.插件发现策略

目前的 Vue CLI 的插件发现策略是 /^(@vue\/|vue-|@[\w-]+(\.)?[\w-]+\/vue-)cli-plugin-/

但是在公司内,是有一些诉求的:

  • 支持具有 React 语言风格的插件:@fe/react-cli-plugin-x
  • 跨技术栈插件同时具备公司内品牌形象:@fe/xxx-cli-plugin-x

这个时候直接使用 Vue CLI 就没法满足需求,需要进行侵入式的改造,Fork 是我不愿意采取的形式


2.插件使用打点

在企业内,我们开发一些插件是希望能够具体统计出这个插件服务的范围和使用次数的;比如一个编译提速的插件,需要了解到这个插件的使用范围和次数才能衡量出工具对业务的帮助,比如号称 xxx 工具可以提效人力 20%,但是没有数据是没人认可的

这个需求是需要对插件机制的加载执行进行打点统计的,一般情况下也需要进行侵入式的代码改造


3.插件分析

企业内忌讳重复建设,需要保证大家不会疯狂重复造类似轮子,而是类似能力的轮子可以以共建的方式持续迭代和维护,质量和人力节省上都能有提升
我们采取的策略是进行插件分析,通过大概的 Api + 名称 去判断是否重复


4.业务能力定制

比如目前 Vue CLI 仅在 create 阶段有 preset 能力,而企业内会希望在 service 阶段也能有 preset 能力

  1. 收敛 package.json 中的插件数量、对一线同学屏蔽过多插件带来的理解复杂度
  2. 企业内使用 Vue CLI 的部分项目 dependencies + devDependencies 数量可以达到 50+,preset 之后可以把 12+ 插件全部收敛,降低理解成本
  3. 对比 Umi 也有 preset 能力,只不过叫「垂直场景解决方案」或者「场景套件」

其它的定制能力:

比如

  • 部分能力要求 serve 后能够阻塞本地服务器的启动,比如 yarn serve/dev 后进行用户 inquirer 交互式对话
  • 拓展 PluginAPI、GeneratorAPI 的 Api 提供给业务同学使用等

And 其它一些诉求




我目前的方案

核心想法是希望能够在按需拓展能力的前提下,同时兼容 Vue CLI 已经沉淀的生态能力

  • 插件运行机制:重写了 Vue CLI 的插件发现、注册、加载、执行,兼容原始 Vue CLI 插件的加载和执行
  • API:Vue CLI API(PluginAPI、GeneratorAPI)等暴露的是一个个 class,直接 extends 然后按需覆盖、增加
  • 内置插件:Vue CLI 的插件基本都是一个个的 js 文件,以形如 require('vue-cli-service4/lib/config/app') 的方式获取此文件,然后直接执行即可,这部分增强的诉求不大

因为「运行机制」是完全重写的,因此可以支持自定义插件命名的发现策略、增加使用打点、插件分析等能力


现有方案存在的问题

  • API、内置插件 等可以随着 Vue CLI 生态一起升级,但是这个东西变成了黑盒,require 后并不知道它有什么,就会带来 Vue CLI 迭代过程 Api 或者是 内置插件 文件可能会引入一些我们自己代码不支持的新逻辑新,这个时候就要去定位和兼容
  • 大版本兼容的时候成本比较高

想了解一下是否有更优雅的解法

如果 Vue CLI 可以抽象一波,类似 @umijs/core 可能会比较棒
如何定制企业级前端研发框架

@screetBloom
Copy link
Owner Author

screetBloom commented Jul 26, 2021

关于Service Preset的设想

背景

企业内使用 Vue CLI 的方式:

  • 由某个团队对接公司基建,自定义大量 Service 插件(10+)
  • 业务同学在创建页面点选配置项(所谓的云端创建),vue create 创建并内置 Service 插件
  • 用户 git clone 到本地,看到的是一个业务属性完备的项目(内置了上述的 10+ 插件),直接开发即可
  • 如果业务需要其它能力则继续开发 service 插件

为什么需要这个功能

  • 可以把某些特定业务场景的插件集整合成一个开箱即用的preset提供给用户,比如根据业务属性提供 CRM 的业务preset、交易的preset,业务开发只需要根据统一入口的文档开发即可,无需关心引入了哪些插件集
  • 长期 dependencies + devDependencies 数量达到 20+,package.json 又臭又长且难以理解
  • 初始化时提供的内置插件其实业务根本不需要关注,但是必须要裸露到项目,增加了额外的理解成本

使用方式

// vue.config.js
module.exports = {
  pluginOptions: {
    presets: [
      "@fe/vue-cli-preset-crm"
      ["@fe/vue-cli-preset-ssr", { param: true }]
    ],
  },
}


如何定义 preset

导出一个返回 Object 的函数

interface ProjectOptions {
  publicPath?: string
  outputDir?: string
  pluginOptions?: object
}

interface Preset {
  plugins: string[]
}

module.exports = function(config: ProjectOptions) : Preset {
  return {}  as Preset
}

preset加载机制

参考 babel 、umi

加载策略:

  • 顺序加载
  • 深度优先
  • 同名插件, 后覆盖前,重复时进行 Warning 提示

顺序加载

插件执行时的合并顺序

  1. 内置插件
  2. presets 中声明的插件
  3. package.json 中安装的插件
// vue.config.js
module.exports = {
  pluginOptions: {
    // 执行顺序 a、b、c
    presets: ["@fe/vue-cli-preset-1"],
  },
}
// @fe/vue-cli-preset-1
module.exports = function() {
  return {
    plugins: [ require("a"), require("b"), require("c") ]
  };
}

深度优先

如果后续支持了返回 presets 嵌套的话,需要对 presets 进行深度优先配置加载
以下👇暂不考虑

// @fe/vue-cli-preset-2
module.exports = function() {
  return {
    presets: [ require("preset-a") ],
    plugins: [
      require("plugin-b1"),
      require("plugin-b2"),
    ]
  };
}

同名插件

  1. 内置插件
  2. presets 中声明的插件
  3. package.json 中安装的插件

如下三个代码块这里👇 插件执行顺序 = a、c、b
需要给出提示 请注意:preset 中的 @fe/vue-cli-plugin-b插件被项目 package.json 覆盖了

// vue.config.js
module.exports = {
  pluginOptions: {
    // 执行顺序 a、c、b
    presets: ["@fe/vue-cli-preset-1"],
  },
}
// @fe/vue-cli-preset-1
module.exports = function() {
  return {
    plugins: [ require("@fe/vue-cli-plugin-a"), require("@fe/vue-cli-plugin-b"), require("@fe/vue-cli-plugin-c") ]
  };
}
// package.json
"dependencies": {
   "@fe/vue-cli-plugin-b": "~2.0.0",
}

@screetBloom
Copy link
Owner Author

screetBloom commented Aug 6, 2021

豪群的建议

  1. Vue CLI 5 会增加 plugins 字段解决上述的部分插件问题
  2. service preset 有兴趣支持,但是没想清楚细节,可以针对上面的👆的想法再讨论和考虑一波
  3. 不认可支持 service 阻塞增加交互这个功能
  4. Vue CLI 会继续维护, 是作为单纯的 webpack 项目的入口,还是要接入 Vite,这个还没定,得看后面 Vite 生态怎么发展,当前阶段规划只考虑 webpack 生态

企业内部实现时需要同时支持 vite、webpack、esbuild



关键信息

  1. 后续 Vue 首推的 CLI 工具可能要增加 create-vue ,主要提供基于 Vite 的 Vue 模板,加上 Cypress 用于测试
  2. 豪群近期的精力也主要在这个上面,最近会开源,可参考这部分的实现作为重构思路


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant