正文
本文作者:IMWeb DeepKolos 原文出处:
IMWeb社区
未经同意,禁止转载
前不久发布了
vc-popup组件集
, 但是那时候完全只是展示没有如何使用的教程, 因为当时急于发布出来, 实在不妥, 抱歉~
既然是想自己东西可以让别人方便使用, 那就是打包成npm的包咯, 但是考虑
vc-popup
仅仅是popup的组件集, 不是完整的组件库, 所以很多时候用户仅仅想使用某个
popup
, 那么其他
popup
也打包进去, 就浪费带宽了, 所以需要一个每个
popup
单独发布到npm上去, 但是把依赖分开的时候之后开发就是带来不便, 比如一个包更新了, 需要在另一个手动更新, 为了解决这个不便, 就是
Lerna
登场的时候了,
用来方便开发和管理多个
package
~
但是自己实践的过程当中遇到一些问题和还有踩过一些坑, 所以在这里记录, 不过在开始之前, 先提一下
vc-popup
的更新
12-08: imgView支持懒加载图片,从加载状态的预设图片到加载完成的src同步变化~
安装Lerna
目前知道3种办法, 如果在使用
vscode
同学, 使用
cnpm
时候附带
--by=npm
可以避免
rg.exe
吃CPU的问题, 同理可以设置为
--by=yarn
, 一些包使用
cnpm
安装有问题的时候, 就可以使用让
cnpm
仅仅做下载, 安装交给
npm/yarn
> npm i -g lerna
> cnpm i -g lerna --by=npm
> yarn global add lerna
初始化一个demo
在日常使用输入命令的时候常用
&&
加快效率, 自己输入的次数多了, 才发现命令行相比于界面的优点在于可以串联多个简单的任务, 这个学期开始学习操作系统, 发现有个类似的名词
单道批处理系统
和
CMD批处理脚本
, 所以不言而喻咯~ 摁
{enter}
键的时候想想还有什么命令可以提前敲进去的
还有一个优点是, 命令是基于
字符组合
的确定, 而非
界面位置
, 所以界面需要层叠, 命名不需要, 字符组合容量大
> mkdir lerna-demo && cd lerna-demo && lerna init
前面因为需要穿插
cnpm
所以安装部分没有串联
由于键盘右边
shift
键位问题, 其实输入&&的时候并不是那么顺畅, 可以通过
AHK
来做转接, 我一般用笔记本键盘的时候按
aand{space}
生成
&&{space}
, 自己做的键盘, 因为调整过shift的位置就还是按&&
生成的查看生成的文件和目录
> ls
lerna.json package.json packages
分别查看文件内容
> head lerna.json && head package.json
{
"lerna": "2.5.1",
"packages": [
"packages/*"
],
"version": "0.0.0"
}
{
"devDependencies": {
"lerna": "^2.5.1"
}
}
然后新建目录s
> cd packages && mkdir module-0 module-1 module-2
初始化
package.json
> cd module-0 && npm init -y && cd ../module-1 && npm init -y && cd ../module-2 && npm init -y
Wrote to D:\DEV\Github\demo\lerna-demo\packages\module-0\package.json:
{
"name": "module-0",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
Wrote to D:\DEV\Github\demo\lerna-demo\packages\module-1\package.json:
{
"name": "module-1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Wrote to D:\DEV\Github\demo\lerna-demo\packages\module-2\package.json:
{
"name": "module-2",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
初始化每个module的
index.js
> echo export default require('./package.json').name > index.js && cat index.js > ../module-0/index.js && cat index.js > ../module-1/index.js
然后在
lerna-demo
新建index.js并编辑, 因为lerna会维护的是packages/*之间的依赖, 这里的
index.js
直接填写
module-2
的路径
> cd ../.. && code index.js
const msg = require('./packages/module-2')
console.log(msg);
设置
module
之间依赖, 现在
require
的时候就可以直接填写对应的
module
了
修改module-1的index.js
export default
require('./package.json').name
+ 'depends on [' + require('module-0').default + ']'
修改module-2的index.js
export default
require('./package.json').name
+ 'depends on [' + require('module-1').default + ']'
思考
正常途径如何添加npm包的依赖?
yarn add modue-name
有什么结果? 会从npm仓库下载该包下来, 解压到
node_modules/module-name
, 然后处理
packsage.json
依赖
那么是否意味着
Lerna
也会有这个类似的操作? 如果现在在开发module-2, 但是发现是module-1的bug, 把module-1的bug修改了, 需要发布一下到npm, 然后module-2再更新module-1的依赖, 那么可以猜测
Leran
通过某种手段让这个更新同步自动化了
那么基于猜测可以进行验证咯~ 先看手册, 查查这个类似的操作是什么~
看Example就很清晰知道的了, 那么开始生成依赖
> lerna add module-0 --scope=module-1
> lerna add module-1 --scope=module-2
那么可以预计操作结果是, module-2的
node_modules
有
module-1
的文件夹,并且包含了其内容, module-1同理
那么就可以猜测如何实现了
是递归复制文件? 验证一下 那么现在修改一下
module-0/index.js
然后,查看
module-1/node_modules/module-0/index.js
,
module-2
同理
把
module-0/index.js
该为如下
export default
require('./package.json').name + ' edited'
OK, 自动修改是同步更新的, 所以不是, 记得自己看linux的教程的时候有个工具是相关的,
ln
, 但是我使用的是, 文件系统是
NTFS
> ver
Microsoft Windows [Version 10.0.15063]
> ln --help
用法:ln [选项]... [-T] 目标 链接名 (第一种格式)
或:ln [选项]... 目标 (第二种格式)
或:ln [选项]... 目标... 目录 (第三种格式)
或:ln [选项]... -t 目录 目标... (第四种格式)
In the 1st form, create a link to TARGET with the name LINK_NAME.
In the 2nd form, create a link to TARGET in the current directory.
In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.
Create hard links by default, symbolic links with --symbolic.
By default, each destination (name of new link) should not already exist.
When creating hard links, each TARGET must exist. Symbolic links
can hold arbitrary text; if later resolved, a relative link is
interpreted in relation to its parent directory.
--more
但是我用的是windows哦, 那么猜测是通过windows的工具来实现的, 这个时候, 突然我想到了多次重装系统在网上习得的技巧
> mklink --help
The syntax of the command is incorrect.
Creates a symbolic link.
MKLINK [[/D] | [/H] | [/J]] Link Target
/D Creates a directory symbolic link. Default is a file
symbolic link.
/H Creates a hard link instead of a symbolic link.
/J Creates a Directory Junction.
Link Specifies the new symbolic link name.
Target Specifies the path (relative or absolute) that the new link
refers to.
之前重装系统多了, 会通过mklink把C盘的Users
Juction
到D盘去, 之后每次恢复系统的时候一些程序的配置也就不用重新设置的了, 具体可以参考
网上的教程
, 需要装系统的时候操作的(文件解压出来, 但是还没重启, 启动安装的时候), 记得好像不能在系统安装之后操作
来验证咯, 这时候就不能使用
ls -all
来查看了(安装了cygwin, 并且把bin目录放在path里了, 所以可以用), 而是需要使用
dir
所以, lerna在windows下是通过建立
Juction
来解决
依赖包同步更新
的问题~ linux的话, 也就不言而喻咯, 使用的应该是类似的工具
ln
~
通过
webpack
设置
babel
转码, 然后通过
lerna-demo/index.out.js
来验证结果咯~
> webpack && node index.out.js
Hash: 3378d33b254656002585
Version: webpack 3.10.0
Time: 1031ms
Asset Size Chunks Chunk Names
index.out.js 4.14 kB 0 [emitted] main
[0] ./index.js 83 bytes {0} [built]
[1] ./packages/module-2/index.js 183 bytes {0} [built]
[2] ./packages/module-2/package.json 233 bytes {0} [built]
[3] ./packages/module-1/index.js 183 bytes {0} [built]
[4] ./packages/module-1/package.json 233 bytes {0} [built]
[5] ./packages/module-0/index.js 141 bytes {0} [built]
[6] ./packages/module-0/package.json 196 bytes {0} [built]
module-2 depends on [module-1 depends on [module-0 edited]]
结果就出来了, demo测试通过 再想一下改造
vc-popup
的时候会可能出现什么问题? Lerna解决的是在
packages/*
的依赖, 也就是回到了例子的问题了
const msg = require('./packages/module-2')
console.log(msg);
这里说明的是在不在packages文件夹内就不能享受依赖更新同步的福利了
开工
任何对
试验性
的改造, 都推荐新建分支里面进行~