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

MIP CLI 2.0 #624

Open
chenqiushi opened this issue May 31, 2019 · 10 comments
Open

MIP CLI 2.0 #624

chenqiushi opened this issue May 31, 2019 · 10 comments
Assignees
Labels
enhancement New feature or request

Comments

@chenqiushi
Copy link
Contributor

chenqiushi commented May 31, 2019

要解决什么问题

  1. 第三方依赖过多(50+),导致安装、更新速度极慢
  2. 项目组织结构存在调整优化的空间
  3. 其他补充

描述一下你理想中的解决方案

  1. 整体使用 Typescript 重构,更新配套编译、lint 工具等
  2. 所有命令使用插件机制,统一入口进行调度,运行时安装、加载。
  • 官方插件。管理在 mip-cli/plugins 目录。其中使用频率最高的命令(如 build,dev,init)可以内置,其他插件运行时加载。
  • 自定义插件。用户自己管理,按照命名规则及目录规范,发布到 NPM

CLI 应提供一种方式(如一个 plugin 包 cli-shared-utils),暴露命令行常用接口(logger、spinner、server、env 等)给插件使用。

  1. 完善的单元测试,覆盖率不低于 90%
  2. 其他补充

描述你的备选方案
清晰准确的描述你考虑的备选方案

补充信息
补充其他信息,如截图等

@chenqiushi chenqiushi added the enhancement New feature or request label May 31, 2019
@clark-t
Copy link
Contributor

clark-t commented Jun 3, 2019

整体思路差不多,但是 utils 感觉没必要拆成包吧,直接跟着 CLI 一起升级感觉就可以了

@clark-t
Copy link
Contributor

clark-t commented Jun 3, 2019

CLI 支持的指令

我觉得 CLI 可以分成 core 和 功能插件两部分,core 负责命令行的解析和插件调度,并且提供:

# 安装插件
mip2 install xxx
# 卸载插件
mip2 remove xxx
# 升级插件
mip2 update xxx/all
# 打印当前已安装的插件列表,可打印插件名和当前插件版本号、是否存在最新版等信息
mip2 list
# 查看当前 MIP2 版本
mip2 version

其他可能还缺少的部分可以补充。

插件的管理和发布

默认采用 npm 包的方式进行 MIP2 插件管理,比如 mip2-plugin-dev 则对应 mip2 dev -xxx -xxxmip2-plugin-dev-sf 则对应 mip2 dev sf --xxx ---xxx

为了插件开发时本地调试方便,应该要提供一种加载本地插件的方法。这个我们讨论一下。

插件使用方式

功能插件在安装好之后,可以通过 mip2 xxx xxxxx 的方式调用,比如 mip2-plugin-dev 的插件的命令为:

mip2 dev xxxxx

这样 CLI 会自动解析好相关参数并传递给对应的插件进行执行

插件的复用机制

在实践过程当中,发现一种情况比较常见,就是插件的复用机制。比如目前现有的 mip-cli-plugin-sf 在功能上依赖了 mip2-dev 的编译和路由功能。关于这一块我的想法是增加一个插件的复用机制,通过 webpack/tapable 的方式进行组织,由 dev 模块通过 tapable 机制主动暴露钩子、方法等等,然后由其插件主动进行控制。

所有的插件都挂载到一个 global.MIP2 的大对象上,通过 MIP2.require('xxx') 的方法去加载其他插件,CLI 会自动去查找插件并返回插件对象,如果不存在则提示用户下载或者自动下载。

插件是否需要跟 CLI 强耦合

这里主要问题在于,插件是需要继承自一个由 CLI 核心提供的共同基类呢,还是统一一个对象格式,由插件开发者自行按照格式实现即可。如果统一使用 CLI 提供的基类,那么插件是无法独立于 CLI 直接使用的,比如 mip2-build,在编译上线的项目当中其实可以直接使用这个包进行上线即可,并不需要先通过 CLI 加载执行 mip2-build 去进行组件上线编译。

所以这里估计也得讨论一下。

@clark-t
Copy link
Contributor

clark-t commented Jun 3, 2019

DEV 功能升级

增量编译

目前 mip2 dev 只提供了全量编译的功能,目前开发的组件越来越多,在初始启动的时候会变得有些慢了,所以需要支持组件在 dev 模式下的增量编译。即通过 server 访问到对应组件的时候再将其添加到 webpack 的 entry 中进行编译;

proxy 机制

目前 dev 的 proxy 只是基于源码替换 URL 的 proxy,应该升级成真正的 proxy,从目前的反馈来看,通过 proxy 来解决开发时跨域问题的需求还是很多的;

@clark-t
Copy link
Contributor

clark-t commented Jun 3, 2019

VALIDATE 功能升级

#449

@chenqiushi
Copy link
Contributor Author

chenqiushi commented Jun 3, 2019

mip2-plugin-dev 则对应 mip2 dev -xxx -xxx,mip2-plugin-dev-sf 则对应 mip2 dev sf --xxx ---xxx

这一块 mip2 dev sf 应该是属于 mip2 dev 的子命令,可以同属一个插件 mip2-plugin-dev 来管理。不然如果有 mip2 dev sf2 , mip2 dev sf3 不是得发布 3 个插件。

所有的插件都是 mip2-plugin-<name> 的形式

@clark-t
Copy link
Contributor

clark-t commented Jun 3, 2019

dev 可以集成自己的 a b c 命令,也可以外部插件扩展 sf,我的意思是这样子的,就跟 CLI 允许内置插件和扩展插件一样,可以增加插件灵活性

@clark-t
Copy link
Contributor

clark-t commented Jun 3, 2019

经讨论,明确了几个问题:

插件复用机制

每个插件模块对外暴露的是一个对象,对象的接口格式由 CLI 或者一个公用的 utils 包来进行统一;插件以依赖的形式去调用其他插件,而不是以 MIP2.require('xxx') 的方式去管理,CLI 只负责命令解析和插件调度、插件升级卸载等等;

插件不强依赖 CLI

插件统一对外暴露的对象里面必须提供的 run 方法用于接收参数,并且插件的功能是完整的,不依赖 CLI 提供任何功能,因此可以直接通过 const plugin = require('xxx') ; plugin.run({xxx}) 的方式进行具体功能的直接使用

@chenqiushi
Copy link
Contributor Author

chenqiushi commented Jun 3, 2019

目录组织形式初定如下(具体随时修改):

mip2/packages
    |-- mip-cli
    |   |-- cli
    |   |   |-- bin
    |   |       `-- mip2
    |   |   |-- lib
    |   |   |-- utils
    |   |   |-- ...
    |   |   |-- README.md
    |   |   `-- package.json
    |   |-- cli-plugin-dev
    |   |   |-- src
    |   |   |-- README.md
    |   |    `-- package.json
    |   |-- cli-plugin-build
    |   |   |-- src
    |   |   |-- README.md
    |   |    `-- package.json
    |   |-- cli-plugin-validate
    |   |   |-- src
    |   |   |-- README.md
    |   |    `-- package.json
    |   |-- cli-plugin-utils
    |   |   |-- src
    |   |   |-- README.md
    |   |    `-- package.json
    |   |-- ...
    |   `-- ...
    |
    `-- mip

其中 ,mip-cli/cli 模块是命令行工具本身,主要完成:

  • CLI 的基础功能。如版本、更新、显示插件列表、获取帮助信息等
  • Plugins 的加载/安装/调度。包括官方命令 plugins 及 社区(用户自定义) plugins

cli-plugin-<name> 是官方插件,相互之间可以进行调度,具体方式 @clark-t 可以补充

Plugins 之间存在一些需要公用的方法和模块,如 logger env exit 等,抽离出来在 cli-plugins-utils 里进行管理,开发插件时可以引入避免冗余。

Plugins 可以独自管理发布,单个 plugin 能够以 nodejs 模块的形式引入,以编程的方式使用,如:

const build = require('mip-cli-plugin-build');

build(foo, bar);

也可以安装 mip2 CLI,通过命令行工具进行调度:

npm install mip2

mip2 build

@clark-t
Copy link
Contributor

clark-t commented Jun 3, 2019

为避免命名上的冲突,我觉得 cli-plugins-utils 应该命名为 cli-utils 会比较好点,npm 包名为 mip-cli-utils;
utils 除了提供公用方法之外,还提供 TS 的类型定义之类,统一约束 CLI 插件对外暴露的格式;

插件我认为应该对外暴露的是一个对象而不是方法:

{
  command,
  run({/* 参数 */}),
  /* api */
  /* hooks */
}

其中 plugins.run({/* ... */}) 就等价于秋实君上面提到的 build(foo, bar) 的调用方式

@clark-t
Copy link
Contributor

clark-t commented Jun 5, 2019

目前有个问题,比如在开发模式下除了最基础的 webpack 和 server 之外,可能还需要 proxy、autoreload、autoopen 等功能,但这些不是必须的,比如 autoopen 功能目前在 1.0 里面几乎是默认不开启的,所以这些功能是否也可以插件化?也就是插件的插件,然后给开发者提供配置方法比如通过 mip.config.js 去决定是否使用某些插件

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

No branches or pull requests

2 participants