本文为Varlet
组件库源码主题浏览系列第一篇
Vue
开源的组件库有很多,根本各个大厂都会做一个,所以作为集体再反复造轮子其实意义也不是很大,然而笔者对于如何设计一个Vue
组件库还是挺感兴趣的。
不同的组件库架构必定有所不同,不过大体思路应该都差不多,笔者在泛滥组件库中筛选了Varlet 来进行分析,Varlet
是一个基于 Vue3
开发的 Material
格调的挪动端组件库,本系列的文章会全面解析这个我的项目,须要阐明的是,不会具体的看某个组件是怎么实现的,而是理解组件库整体的设计,以及按需引入、主题定制、屏幕适配、组件打包、VsCode
属性高亮等比拟有意思的话题,话不多说,开始吧。
Varlet 版本为:1.27.20
我的项目构造
先克隆Varlet
的我的项目:
git clone https://github.com/varletjs/varlet.git
初始构造如下:
packages
目录下存在很多独自的包,咱们前面都会进行介绍。
本地开发
依据官网文档的形容,咱们能够应用上面的命令进行本地开发:
Varlet
应用的包管理器是pnpm,pnpm
是一个速度快、节俭磁盘空间的软件包管理器,如果没装置的话须要先装置一下:
npm install -g pnpm
bootstrap
命令如下:
pnpm install && node scripts/bootstrap.mjs
先装置依赖,而后执行bootstrap.mjs
文件:
// bootstrap.mjsimport { buildCli, buildIcons, buildShared, buildUI, runTask } from './build.mjs';(async () => { await runTask('shared', buildShared) await Promise.all([runTask('cli', buildCli), runTask('icons', buildIcons)]) await runTask('ui', buildUI)})()
运行了一波工作,挨个来看,先看runTask
办法:
// build.mjsimport ora from 'ora'export async function runTask(taskName, task) { const s = ora().start(`Building ${taskName}`) try { await task() s.succeed(`Build ${taskName} completed!`) } catch (e) { s.fail(`Build ${taskName} failed!`) console.error(e.toString()) }}
ora是一个命令行的loading
工具,能够在终端显示难看的loading
成果,而后就是执行传入的工作函数。
shared
工作:
// build.mjsimport execa from 'execa'import { resolve } from 'path'const CWD = process.cwd()// 获取nodejs过程的当前工作目录,也就是我的项目的根目录const PKG_SHARED = resolve(CWD, './packages/varlet-shared')// varlet-shared包的绝对路径export const buildShared = () => execa('pnpm', ['build'], { cwd: PKG_SHARED })
execa是nodejs
的child_process的改良版本,返回的是一个Promise
,pnpm
运行命令能够省略run
,间接pnpm build
即可,所以上述这个工作就是在varlet-shared
包的目录下执行build
命令:
tsc && tsc -p tsconfig.cjs.json
应用两个配置文件执行了两次tsc
,也就是将src
目录下的ts
文件别离编译成了es
模块和commonjs
模块:
cli
工作:
// build.mjsconst PKG_CLI = resolve(CWD, './packages/varlet-cli')export const buildCli = () => execa('pnpm', ['build'], { cwd: PKG_CLI })
到varlet-cli
目录下执行build
命令:
tsc
同样也是编译ts
,这个包的入口为./lib/index.js
,未编译前lib
目录下只有这一个文件,显然其余文件都是缺失的:
须要先编译能力应用这个包,编译后后果如下:
icons
工作:
// build.mjsconst PKG_ICONS = resolve(CWD, './packages/varlet-icons')export const buildIcons = () => execa('pnpm', ['build'], { cwd: PKG_ICONS })
进入varlet-icons
目录下运行build
命令:
varlet-icons build
varlet-icons
命令的执行文件为同目录下的varlet-icons/lib/index.js
,具体逻辑咱们前面再说,先看一下运行后果:
其实就是将svg
文件编译成字体图标。
ui
工作:
// build.mjsconst PKG_UI = resolve(CWD, './packages/varlet-ui')export const buildUI = (noUmd) => execa('pnpm', ['compile', noUmd ? '--noUmd' : ''], { cwd: PKG_UI })
进入varlet-ui
目录下执行compile
命令,和后面几个工作不同,这个工作会接管一个参数,顾名思义,是否不要生成umd
,然而我搜寻了一下并没有找到有传true
的状况:
compile
命令如下:
varlet-cli compile
该命令的作用是打包varlet
的组件,具体实现逻辑前面再看,先看一下运行后果:
次要是编译组件,有三种产物:es
模块、commonjs
模块、umd
模块。
启动前的工作都运行完了,接下来就能够进入varlet-ui
目录启动服务了,启动命令pnpm dev
:
varlet-cli dev
这个命令做的事件比拟多,咱们前面再详解,大体上呢会把varlet-cli
目录下的site
目录复制到varket-ui
目录下,并且动静生成两个路由文件:mobile.routes.ts
、pc.routes.ts
:
拜访启动的页面:
报错了,起因很简略,笔者是Windows
电脑,门路的分隔符是反斜杠,所以生成的局部门路\
没有转换成/
,而\
和.varlet
组合起来会被认为是转义字符:
查看源码发现尽管曾经应用了slash来转换Windows
平台下的门路问题,然而不晓得为啥没有失效:
没方法,只能手动修复一下,咱们应用上面这种办法来转换:
import path from 'path'xxx.split(path.sep).join('/')
批改完当前文档页面示例显示进去了:
左边手机模拟器里的组件导入的是varlet-ui/src/xxx
目录下的,也就是开发目录下的组件,所以咱们间接批改就能够在页面上查看成果了。
我的项目的本地启动局部就到这里,咱们下篇再见~