# plugin-build
当前版本为 3.x 版本,下面解释的也是 3.x 版本的使用。
version 3.0.3 之后,不需要安装指定的 pnpm 版本。
# 简介
plugin-build 使用了umijs cross-spawn模块进行构建工作,依托于pnpm的workspace实现多个插件的打包,其核心是nodejs执行shell脚本,同宿主一起使用vue-cli-service的构建能力。
# 技术选型
yargs + inquirer + pnpm workspace + cross-spawn
1、使用稳定的多包管理工具进行打包
2、插件项目的打包和主应用的打包同时使用一致的打包工具,无依赖问题的冲突
3、插件打包配置化,暴露前端熟悉的打包配置文件,降低使用成本
4、打包工具轻量化,不会因为项目的特性存在多个版本打包工具,可以做到升级打包工具并不影响项目的打包
5、升级成本只需注入一些配置文件和安装打包工具即可直接打包,提供对应的命令进行初始化配置
pnpm workspace 和 yarn lerna
1、lerna + yarn 学习成本会高一些,pnpm 学习曲线较为平缓
2、pnpm使用 虚拟包管理器 的原理 可以显著减少依赖的安装时间和磁盘空间,可以减少线上打包的时间
3、pnpm自带filter可以过滤对应包进行构建, lerna命令通过--scope过滤包
4、lerna 已经停止维护
参考文档 https://juejin.cn/post/7104088592426729480
# 打包流程图
# 安装
npm i -g @esign/plugin-build@latest --registry=https://registry-npm.tsign.cn/
安装之后,你可以在命令中执行 plugin-build
命令,看看是否展示出了一份所有可用命令的版主信息,来验证它是否安装成功。
# 插件目录
现阶段规定的插件目录即是在主应用下面的 plugins
目录。下面是 plugins
的目录结构。
# 子命令行
# 项目工程安装构建工具
pnpm add -Dw @esign/plugin-build@latest --registry=https://registry-npm.tsign.cn/
# init 初始化插件项目结构
plugin-build init
# 基本配置
无
# build 构建项目中插件指令
plugin-build build
# 若有 mode 参数,可配置为
plugin-build build -- --mode=prod
# 基本配置
--scope
, -s
构建指定插件,用于插件的单独打包;多个插件用逗号隔开。
- 参数类型:
string
示例:
plugin-build build --scope ./plugins/base/hello-world-plugin
注意事项
build
指令用于构建这个应用的插件指令。插件目录由于是写死的,所以当前指令只会扫描plugins
目录进行插件构建。构建出来的文件会根据/plugins/config.json
文件中的数据进行输入和输出。(备注:输出格式现阶段只存在umd
格式)- config.json 中现阶段定义如下:
// config.json { "name": "", "plugins": { // something } }
- 设置
--mode=prod
后,命令行工具会取出对应的宿主工程下根目录下的.env.prod
文件里面的有效键值对组合成对象注入到插件打包构建进程的环境中(webpack.DefinePlugin(process.env, dotEnv)
)
# dirdocs 构建指令集说明文档指令
plugin-build dirdocs --entry [入口文件(夹)] --output [出口文件夹]
# 基本配置
--entry
, -e
指令集的入口文件(夹)
- 参数类型:
string
示例:
# 构建所有扩展点的指令集文件
plugin-build dirdocs --entry ./demo-event-api
# 构建指令扩展点的指令集文件
plugin-build dirdocs --entry ./demo-event-api/hello-world-epu
--output
, -o
扩展点文档的出口文件夹;不传,则文档输出在各个扩展点指令集文件夹下
- 参数类型:
string
示例:
# 输出到指定的文件夹
plugin-build dirdocs --entry ./demo-event-api --output ./demo-event-api/docs
--sync-eep-info
, -s
是否将扩展点文档同步至 extension-point-info.json 文件中
- 参数类型:
boolean
- 默认值:
false
示例:
# 输出到指定的文件夹
plugin-build dirdocs --entry ./demo-event-api --sync-eep-info
注意事项
- 扩展点指定集的目录结构要符合指令集文件目录规范,扩展点的指令集的入口文件为
index.[tj]s
- 不设置
output
参数,若入口为指令集根目录,则在entry
下新建docs
文件夹;若入口为某个扩展点指令集目录/文件,则在entry
下新建README.md
文件 - 扩展点指令集的api需提供相应的注释,
注释规范
如下:
# 指令集文档注释规范
常用语法:
@file
:- 语法:
@file <description>
- 描述: 标记提供文件的说明
- 语法:
@name
:- 语法:
@name <name>
- 描述: 标记当前文件的名称
- 语法:
@author
:- 语法:
@author <name>
- 描述: 标记提供文件的作者,多名作者用
,
隔开
- 语法:
@version
:- 语法:
@version <version>
- 描述: 标记提供文件的版本
- 语法:
@since
:- 语法:
@since <updateDate>
- 描述: 标记提供文件的更新时间
- 语法:
@property
:- 语法:
@property <type> <name> [<description>]
- 描述: 标记是一种方便地记录类、命名空间或其他对象的静态属性列表的方法
- 语法:
@namespace
:- 语法:
@namespace
- 描述: 标记表示对象为其成员创建命名空间
- 语法:
@typedef
:- 语法:
@typedef [<type>] <namepath>
- 描述: 标签在描述自定义类型时是很有用的,这里用来描述页面数据源:
pageData
和全局数据源:globalData
- 语法:
@memberof
:- 语法:
@memberof <parentNamepath>
- 描述: 标记标明成员隶属于哪一个父级标识符
- 语法:
@description, @desc
:- 语法:
@description <some description>
- 描述: 标记允许提供正在记录一般说明
- 语法:
@param
:- 语法:
@param [<type>] <name> [<description>]
- 描述: 标记提供函数参数的名称、类型和描述
- 语法:
@returns
:- 语法:
@return [{type}] [description]
- 描述: 标记记录函数返回的值
- 语法:
@ignore
:- 语法:
@ignore
- 描述: 标签表示在代码中的注释不应该出现在文档中
- 语法:
示例
- 在每个扩展点指令集文件顶部,添加
扩展点信息
,格式如下:/** * 扩展点信息, @file 标识必有,否则无法识别该块状注释 * @file 指令集可通过`window.esignbridge.$directive[name]`调用 * @name hello-world-epu * @author anuo<anuo@tsign.cn> * @version 0.0.1 * @since 2023-08-23 * @property {} [视图=宽高默认0,0,无loading效果] 宽度、高度、loading * @property {} [插件类型=UI类] * @property {} [空逻辑=不支持] UI类型暂不支持 */
- 扩展点提供的
页面数据源
,格式如下:/** * 页面数据源 * @typedef {object} pageData * @property {string} name 名称 * @property {string} [sex] 性别, 非必填 * @property {number} [age=18] 年龄, 非必填,默认值为18 * @property {Object} userInfo 用户信息 * @property {string} userInfo.token 用户token */
- 扩展点指令集提供有
uplinkApi
、downlinkApi
、processApi
、utilsApi
、eventApi
五大类指令,在编写注释时,需添加@namespace
指定空间,以processApi
为例:/** * 流程类 * @namespace */ const processApi = {}
- 扩展点指令集书写
api
时,注释应格式如下:/** * 触发流程事件 * @param {string} name 名称 * @param {Object} value 参数 * @param {string} value.name 名称 * @param {number} [value.age=18] 年龄,默认值为 18 * @returns {void} * @memberof processApi */ emitProcessNextClick(name: string, value: Record<string, any>) {}, /** * 监听流程事件,返回对象值 * @returns {Object} 包含用户信息的对象。 * @property {string} name - 用户名。 * @property {number} age - 用户年龄。 * @property {string} email - 用户邮箱。 */ onProcessNextClick() { return { name: '张三', age: '18', email: 'xxxxxx@tsign.cn' } },
# cp 发布平台中合并主客插件产物指令
# 客开工程添加脚本
plugin-build cp -f [客开插件产物地址] -t [宿主目标地址] --cwd [workspace]
# 基本配置
--from
, -f
客开插件产物地址
- 参数类型:
string
--to
, -t
宿主目标地址
- 参数类型:
string
--cwd
工作区地址
- 参数类型:
string
注意事项
客开工程添加脚本
- 地址可为相对地址,可为绝对地址,内部使用
path.resolve()
将路径转换为绝对路径