前面讲了项目的 本地编译启动调试、生产编译,接着讲发布。
发布最重要的功能是 npm版本管理 以及npm publish。
发布
过程
关于发布这块,做的比较好的,可以看 umi的release,参考umi系列(四):npm script命令 – pnpm release。
一般公司用,可以做下以下,有精力可以更加完善,
云谦说过,他做脚手架这么多年沉淀下来的经验有,这里展示部分,这段话的出处找不到了,应该在umi相关的演讲、文档内:
- monorepos;
- 所有pkg包共用一个版本;
- 默认最新,启动项目,默认提示升级到最新版本;
本次ui库的方案与上述的第二点不一致,但无伤大雅;
第三点是脚手架框架的要求,与ui框架无关。
下面列举本次ui库做的内容,详细可参考 publish.js:
遍历各个pkgs,讲所有的pkg全部列出,
提示选择要发布的包
提示要发布的平台(npm 源)
提示输入版本更新的内容说明
提示输入发布的版本号(校验版本号)
执行npm publish 发布
根据是否有beta设置更多发布参数
发布成功后
更新对应pkg包(主要是版本号)
更新版本发布的记录文件
将以上内容做提交
提交前,
提示检查内容,
确定无误后,确认提交,
自动提交git仓库
技术点
prompt的验证
1 | const promptList2 = v => { |
npm publish的beta处理
1 | const publishNpmArgs = ['publish', '--registry', 'https://registry.npmjs.org/']; |
发布不上去与publishConfig
发布不上去,可能是 packageJson.publishConfig有关,改下值,重发一次。
ui项目架构
文档站点项目是用md来写页面
首先一定要明确认知到,本ui项目就是一个文档站点项目,而不是传统的业务jsx项目。
将以上定位认识清楚,非常必要。
传统业务项目与文档站点项目 其实同属于 页面系统项目。
只是二者的文件类型不一样,文档站点项目是用md来写页面,传统业务项目是用jsx来写页面。
当有编译器(loader),将md编译成jsx
所有的非传统业务项目,最终将转化成传统业务项目来解析。
所以,当有一个编译器,可以将md编译成jsx,那么 文档项目也变成了传统的业务jsx项目了。
所以本ui项目,其实就是 写了一个 md转义器,此时,你把所有的md文件看出jsx文件,
那么本ui项目将于传统项目无异。
dumi的源码没有非常细节的去看,不过其大致实现细节,与umi4的文档插件@umijs/plugin-docs一样。
去看 @umijs/plugin-docs 的源码,就知道,
@umijs/plugin-docs 写了一个loader,获取所有的md文件,转义成jsx语法后,再转发给 babel-loader 转义成低版本js,
最终渲染。
下面是 @umijs/plugin-docs 部分源码,详细参考umi系列(八) 文档插件 - 以 mdx 的方式来写文档:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42{
"test": "/\\.mdx?$/",
"use": [{
"loader": "D:\\git\\umi\\umi-next\\packages\\plugin-docs\\dist\\loader.js"
}],
}
{
"test": "/\\.mdx?$/",
"use": [{
"loader": "D:\\git\\umi\\umi-next\\packages\\bundler-webpack\\compiled\\babel-loader\\index.js",
"options": {
"sourceType": "unambiguous",
"babelrc": false,
"cacheDirectory": false,
"targets": {
"chrome": 80
},
"presets": [
["D:\\git\\umi\\umi-next\\packages\\babel-preset-umi\\dist\\index.js", {
"presetEnv": {},
"presetReact": {
"runtime": "automatic"
},
"presetTypeScript": {},
"pluginTransformRuntime": {},
"pluginLockCoreJS": {},
"pluginDynamicImportNode": false,
"pluginAutoCSSModules": true
}], {
"plugins": [
[null, {
"cwd": "D:\\git\\umi\\umi-next",
"absTmpPath": "D:/git/umi/umi-next/.umi"
}]
]
}
],
"plugins": ["D:\\git\\umi\\umi-next\\node_modules\\.pnpm\\react-refresh@0.12.0\\node_modules\\react-refresh\\babel.js"]
}
}],
}
这就像,你写的是 scss文件,经过scss-loader 转后,再给 css-loader,
虽然你写的是 scss less xxxcss xxyy任何后缀名都可以的文件,其实就是写css;
其原理是一样的。
纯正的umi项目
本ui项目 就是 dumi + @umijs/preset-dumi 的项目;
由于dumi只是做了 umi的转发之前,集成了@umijs/preset-dumi;
所以本项目 其实就是 umi+@umijs/preset-dumi。
我们将所有的md文件当jsx来认, @umijs/preset-dumi 是不是一下子觉得这就是一个很纯正简单的umi项目。
相当于本项目,通过 umi dev 启动;
通过 @umijs/preset-dumi 实现 md 转 jsx 的loader;
除此之外的路由、编译配置、开发启动、项目结构 全部就是通用的 umi逻辑。
ui项目小结
一个组件库 应该包含:
- 文档
- 目录结构设计
- monorepos 策略的包管理:是统一版本 还是什么;
- 如何开发调试[如何解决 每个 pkg 内都进行打包;]
- 打包[如何解决 每个 pkg 内都进行打包;]
- 版本管理
- 如何mock ajax
本ui项目 采用了monorepos模式;
npm版本管理上,采用的是非统一版本方式,后期如果相互引用的pkg较多时,采用统一版本管理比较好;
目前采用统一版本管理的有 umi、babel 等库;
开发编译直接用umi;
生产编译使用father-build;
开发、生产编译用的不是同一套配置,这点好处值得待定。
不过这点也与ui框架的场景有关:
如果是公司内部的组件二次封装;
如果公司的业务项目编译没有忽略 node_module 编译;
那么这样是没有问题的,毕竟最后都要交给业务项目外层再编译一次。
一个组件库的开发,
- 方案上最难的是诸如monorepos模式等的选择;
- 技术上最难的是编译(自动化构建),搞定编译原理,游刃有余;
todo
request请求
可以看 本ui库源码,要求去搭建一个真实的请求服务器,外网这种服务器还是比较多的,可以找找资源,
其实也可以直接启用express搭建一个服务器做请
可以思考下,yapi 如何利用起来给公司用。