1.udevçruleså®å¶åè°è¯
2.使用lerna管理monorepo及发npm包实战教程
udevçruleså®å¶åè°è¯
udevçruleså®å¶åè°è¯
å¨å®å¶é¡¹ç®ä¸ï¼å¯¹å¤è®¾ççææç管çåºæ¬é½å¨udev/systemd-udevæ¥ç®¡çãè¿é没æ对åºæ¬çudev使ç¨/rules书åè¿è¡ä»ç»ã
1. udevçruleså¯è½çä½ç½®
/lib/udev/rules.d -- udevé»è®¤/é¢ç½®çrules
/etc/udev/rules.d/ -- å®å¶çrulesï¼ ä¼å 级é«äº/lib/udev/rules.dï¼å®æ¹å»ºè®®å®¢æ·åçrulesé½æ¾è¿é
è³äºæ¾å¨åªä¸ªä½ç½®ï¼èªå·±å³å®å°±å¥½ï¼æ¢ç¶ä½ å¨ä¿®æ¹ç³»ç»å°±åºè¯¥ç¥éä½ å¨åä»ä¹
2. å®å¶èªå·±çrules
å®å¶çææçäºä»¶ï¼å ·ä½å°ruleså°±æ¯ï¼
1ï¼è¿æ»¤å°æ£ç¡®çudeväºä»¶ã
2ï¼æå®æ§è¡çå¨ä½ï¼ruleséçâRUNâï¼é常æ¯èæ¬ï¼æ¯ç«è¦å®æä¸ä¸ªåè½ï¼ç»å¤§å¤æ°åºæ¯é½ä¸æ¯ä¸ä¸ªå½ä»¤è½æå®çï¼
3.å°è¿éå°±è¦è®¾è®¡å°rulesçè°è¯äº
1ï¼å¦ä½ç¥éè¦è¿æ»¤çæ¯æ¡ä»¶ï¼
2ï¼å¦ä½å°å¿ è¦çåæ°ä¼ éç»RUNæ§è¡çèæ¬ï¼
æ¹æ³1:
udevadm monitor -p
-- çæµæ以çkernel/udevdççææäºä»¶ï¼ -pé项å¾æå¿ è¦ï¼æå°åºæ¬æ¬¡çææäºä»¶çä¸äºå±æ§
è¿éå°±æ¯æ¯è¾è®¾å¤æå ¥åæåºæ¶çäºä»¶å±æ§çä¸åï¼å¯ä½ä¸ºè¿æ»¤çæ¡ä»¶
æ¯å¦ï¼
rulesæ件对äºè§åï¼
å°è¿éå¾å¤æ¶åå°±è½æ»¡è¶³è¦æ±äºï¼å¦æè¿æ解å³ä¸éçåºæ¯ï¼å°±è¦è¿ä¸æ¥ä¿®æ¹è¿æ»¤æ¡ä»¶ã
man udevéä¼æç»å¤§é¨åçå ³é®åçä¿¡æ¯ï¼æ³å ¨é¨çå°±åªè½å»æ¸æºç ï¼ã
æ¹æ³2:
éè¿å¨RUNæå®çèæ¬éä¼ éåæ°ï¼æ¥æ¾å°è®¾å¤åå¨åä¸åå¨çå±æ§å·®å¼ã
æ¯å¦ï¼
åèä¿¡æ¯ï¼
aï¼ãudev è§åçå¹é é®
ACTIONï¼ ãã ããããããäºä»¶ (uevent) çè¡ä¸ºï¼ä¾å¦ï¼add( æ·»å è®¾å¤ )ãremove( å é¤è®¾å¤ )ã
KERNELï¼ ãã ããããããå æ ¸è®¾å¤å称ï¼ä¾å¦ï¼sda, cdromã
DEVPATHï¼ããããããã 设å¤ç devpath è·¯å¾ã
SUBSYSTEMï¼ ãããããã 设å¤çåç³»ç»å称ï¼ä¾å¦ï¼sda çåç³»ç»ä¸º blockã
BUSï¼ ãããããããããã 设å¤å¨ devpath éçæ»çº¿å称ï¼ä¾å¦ï¼usbã
DRIVERï¼ ãããã ãããã 设å¤å¨ devpath éç设å¤é©±å¨å称ï¼ä¾å¦ï¼ide-cdromã
IDï¼ ããããããã ãããã设å¤å¨ devpath éçè¯å«å·ã
SYSFS{ filename}ï¼ ãããã设å¤ç devpath è·¯å¾ä¸ï¼è®¾å¤çå±æ§æ件âfilenameâéçå 容ã
ãããããããããããããããä¾å¦ï¼SYSFS{ model}==âSTSSâ表示ï¼å¦æ设å¤çåå·ä¸º STSSï¼å该设å¤å¹é 该 å¹é é®ã
ãããããããããããããããå¨ä¸æ¡è§åä¸ï¼å¯ä»¥è®¾å®æå¤äºæ¡ SYSFS ç å¹é é®ã
ENV{ key}ï¼ ãããããã ã ç¯å¢åéãå¨ä¸æ¡è§åä¸ï¼å¯ä»¥è®¾å®æå¤äºæ¡ç¯å¢åéç å¹é é®ã
PROGRAMï¼ããããããããè°ç¨å¤é¨å½ä»¤ã
RESULTï¼ ãããããããã å¤é¨å½ä»¤ PROGRAM çè¿åç»æã
bï¼ãudev çéè¦èµå¼é®
NAMEï¼ãããããããããããå¨ /devä¸äº§çç设å¤æ件åãåªæ第ä¸æ¬¡å¯¹æ个设å¤ç NAME çèµå¼è¡ä¸ºçæï¼ä¹åå¹é çè§åå对该设å¤ç NAME èµå¼è¡ä¸ºå°è¢«å¿½ç¥ãå¦æ没æä»»ä½è§å对设å¤ç NAME èµå¼ï¼udev å°ä½¿ç¨å æ ¸è®¾å¤å称æ¥äº§ç设å¤æ件ã
SYMLINKï¼ããããããããã 为 /dev/ä¸ç设å¤æ件产ç符å·é¾æ¥ãç±äº udev åªè½ä¸ºæ个设å¤äº§çä¸ä¸ªè®¾å¤æ件ï¼æ以为äºä¸è¦çç³»ç»é»è®¤ç udev è§åæ产ççæ件ï¼æ¨è使ç¨ç¬¦å·é¾æ¥ã
OWNER, GROUP, MODEï¼ãã为设å¤è®¾å®æéã
ENV{ key}ï¼ãããããããããå¯¼å ¥ä¸ä¸ªç¯å¢åéã
cï¼ãudev çå¼åå¯è°ç¨çæ¿æ¢æä½ç¬¦
Linux ç¨æ·å¯ä»¥éæå°å®å¶ udev è§åæ件çå¼ãä¾å¦ï¼my_root_disk, my_printerãåæ¶ä¹å¯ä»¥å¼ç¨ä¸é¢çæ¿æ¢æä½ç¬¦ï¼
$kernel, %kï¼ãããããããã设å¤çå æ ¸è®¾å¤å称ï¼ä¾å¦ï¼sdaãcdromã
$number, %nï¼ããããããã 设å¤çå æ ¸å·ç ï¼ä¾å¦ï¼sda3 çå æ ¸å·ç æ¯ 3ã
$devpath, %pï¼ããããããã设å¤ç devpathè·¯å¾ã
$id, %bï¼ãããããããããã设å¤å¨ devpathéç ID å·ã
$sysfs{ file}, %s{ file}ï¼ãã 设å¤ç sysfsé file çå 容ãå ¶å®å°±æ¯è®¾å¤çå±æ§å¼ã
$env{ key}, %E{ key}ï¼ãããä¸ä¸ªç¯å¢åéçå¼ã
$major, %Mï¼ãããããããã设å¤ç major å·ã
$minor %mï¼ãããããããã设å¤ç minor å·ã
$result, %cï¼ããããããããPROGRAM è¿åçç»æã
$parent, %Pï¼ãããããã ç¶è®¾å¤ç设å¤æ件åã
$root, %rï¼ãããããããã udev_rootçå¼ï¼é»è®¤æ¯ /dev/ã
$tempnode, %Nï¼ãããããã临æ¶è®¾å¤åã
%%ï¼ããããããããããããç¬¦å· % æ¬èº«ã
$$ï¼ãããããããããããããç¬¦å· $ æ¬èº«ã
对æ¯ä¸ä¸åmanéçå·®å«ï¼$sysfs{ file}ï¼è¿ä¸ªå¨å®é 解å³é®é¢çæ¶åæ¯å¾æç¨çã
è¿ç§æ¹æ³éåè°è¯ç³»ç»å¯å¨çæ¶å对rulesçè°è¯ï¼è¿ä¸ªè¿ç¨ä¸æ¯æ²¡å¾udevadmin monitor使ç¨çãï¼å½ç¶ï¼å¯ä»¥å°è¯èªå·±åä¸ä¸ªsystemdå¯å¨æå¡ï¼è¿å°±æ¶åå°å¯å¨çæ¶æºãå ³èãå½±åï¼å®é æä½ä¼æ¯é¢æ³çå¤æï¼
è¿éæ两个ç¹ï¼
1. env - å¯ä»¥æ¯udeväºä»¶éçå±æ§ï¼-pæå°çï¼
2. $sysfs{ file}, è¿éçfileå°±æ¯å¨ç³»ç»/sysç®å½ä¸å¯¹åºçèç¹ä¸çæ件ï¼æäºæ åµä¸åªè½å¨sysfsçfileçå åæè½åç¡®åºåäºä»¶ã
使用lerna管理monorepo及发npm包实战教程
在维护多个package项目的同学来说,都会面临一个选择:这些package是放在一个仓库里维护还是放在多个仓库里单独维护。数量较少的时候,多个仓库维护不会有太大问题,但是当package数量逐渐增多时,一些问题逐渐暴露出来。最高和最低色带指标源码
因此,我们需要找寻一条新的道路来管理我们的项目,一个理想的开发环境可以抽象成这样:“只关心业务代码,可以直接跨业务复用而不关心复用方式,调试时所有代码都在源码中。”
在前端开发环境中,多 Git Repo,多 npm 则是这个理想的阻力,它们导致复用要关心版本号,调试需要npm link。而这些是茶叶源码标签Lerna + MonoRepo 最大的优势。
什么是lerna
用于管理具有多个包的JavaScript项目的工具。这个介绍可以说很清晰了,引入lerna后,上面提到的问题不仅迎刃而解,更为开发人员提供了一种管理多packages javascript项目的方式。
什么是monorepo
Monorepo 的全称是 monolithic repository,即单体式仓库,与之对应的是 Multirepo(multiple repository),这里的“单”和“多”是指每个仓库中所管理的模块数量。
Multirepo 是比较传统的做法,即每一个 package 都单独用一个仓库来进行管理。例如:Rollup, ...
Monorep 是把所有相关的 package 都放在一个仓库里进行管理,每个 package 独立发布。例如:React, Angular, Babel, Jest, Umijs, Vue ...
了解了基本概念后,详细介绍下使用方法与api。
常用命令
我们需要全局安装lerna工具。汉语源码
为所有项目安装依赖,类似于npm/yarn i
提交对项目的更新 运行该命令会执行如下的步骤:
使用lerna 初始化项目
类似npm init命令
为packages文件夹下的package安装依赖
卸载依赖
比对包是否发生过变更
显示packages下的各个package的version
清理node_modules
lerna run 运行npm script,可以指定具体的package。
lerna.json解析
version:当前库的版本
useWorkspaces: 是否使用workspace来管理依赖 npmClient: 允许指定命令使用的client, 默认是 npm, 可以设置成 yarn command.publish.ignoreChanges:可以指定那些目录或者文件的变更不会被publish command.bootstrap.ignore:指定不受 bootstrap 命令影响的包 command.bootstrap.npmClientArgs:指定默认传给 lerna bootstrap 命令的参数 command.bootstrap.scope:指定那些包会受 lerna bootstrap 命令影响 packages:指定包所在的目录
使用lerna的基本工作流
环境配置
初始化一个lerna工程
在本地目录下初始化一个lerna工程。 1、创建一个空的文件夹,命名为my-app:
2、初始化 通过cmd进入相关目录,进行初始化
3、添加一个测试package 默认情况下,package是放在packages目录下的。但是自己想做一个组件库,改为了components
4、安装各packages依赖 这一步操作,磐石指标源码官网上是这样描述的 在当前的Lerna仓库中引导包。安装所有依赖项并链接任何交叉依赖项。
5、发布 在发布的时候,就需要git工具的配合了。 所以在发布之前,请确认此时该lerna工程是否已经连接到git的远程仓库。你可以执行下面的命令进行查看。 本篇文章的代码托管在Github上。因此会显示此远程链接信息。 如果你还没有与远程仓库链接,请首先在github创建一个空的仓库,然后根据相关提示信息,进行链接。
第一次publish前我们需要执行
在输入用户名及密码之后执行这条命令
你就可以根据cmd中的提示,一步步的输出源码盒子发布packges了。 实际上在执行该条命令的时候,lerna会做很多的工作。
到这里为止,就是一个最简单的lerna的工作流了。但是lerna还有更多的功能等待你去发掘。生成的packages如下:
工作模式
lerna有两种工作模式,Independent mode和Fixed/Locked mode,在这里介绍可能会对初学者造成困扰,但因为实在太重要了,还是有必要提一下的。 lerna的默认模式是Fixed/Locked mode,在这种模式下,实际上lerna是把工程当作一个整体来对待。每次发布packges,都是全量发布,无论是否修改。但是在Independent mode下,lerna会配合Git,检查文件变动,只发布有改动的packge。
使用lerna提升开发流程体验
接下来,我们从一个demo出发,了解基于lerna的开发流程。
项目初始化
我们需要维护一个UI组件库,其包含2个组件,分别为House(房子)和Window(窗户)组件,其中House组件依赖于Window组件。
增加依赖
接下来,我们来为组件增加些依赖,首先House组件不能只由Window构成,还需要添加一些外部依赖(在这里我们假定为lodash)。我们执行:
这句话会将lodash增添到House的dependencies属性里 我们还需要将Window添加到House的依赖里,执行:
自动检测到window隶属于当前项目,直接采用symlink的方式关联过去。 symlink:符号链接,也就是平常所说的建立超链接,此时House的node_modules里的Window直接链接至项目里的Window组件,而不会再重新拉取一份,这个对本地开发是非常有用的。
发布到npm
接下来,我们只需要简单地执行lerna publish,确认升级的版本号,就可以批量将所有的package发布到远程。 默认情况下会推送到系统目前npm对应的registry里,实际项目里可以根据配置package.json切换所使用的npm客户端。
更新模块
接下来,我们变更了Window组件,执行一下lerna updated,便可以得知有哪些组件发生了变更。
我们可以看到,虽然我们只变更了window组件,但是lerna能够帮助我们检查到所有依赖于它的组件,对于没有关联的组件,是不会出现在更新列表里的,这个对于相比之前人工维护版本依赖的更新,是非常稳健的。
集中版本号或独立版本号
截止目前,我们已经成功发布了2个package,现在再新增一个Tree组件,它和其他2个package保持独立,随后我们执行lerna publish,它会提示Tree组件的版本号将会从0.0.0升级至1.0.0,但是事实上Tree组件仅仅是刚创建的,这点不利于版本号的语义化,lerna已经考虑到了这一点,它包含2种版本号管理机制。
如果需要各个组件维护自身的版本号,那么就使用independent模式,只需要去配置leran.json即可。
TIPS:
yarn workspaces 命令 在根目录安装 npm 包,以 lodash 为例:
总结
lerna不负责构建,测试等任务,它提出了一种集中管理package的目录模式,提供了一套自动化管理程序,让开发者不必再深耕到具体的组件里维护内容,在项目根目录就可以全局掌控,基于npm scripts,可以很好地完成组件构建,代码格式化等操作,并在最后一公里,用lerna变更package版本,将其上传至远端。
lerna最佳实践
项目地址: GitHub - Mrrabbitan/virtualList 为了能够使lerna发挥最大的作用,根据这段时间使用lerna 的经验,总结出一个最佳实践。下面是计划实现的一些特性。
工具整合 在这里引入的工具都是为了解决一个问题,就是工程和代码的规范问题。
Happy Hacking~~~