前端架构: 脚手架之包管理工具的案例对比及workspaces特性的使用与发布过程

npm的workspaces 特性


1 )使用或不使用包管理工具的对比

  • vue-cli 这个脚手架使用 Lerna 管理,它的项目显得非常清晰
  • 在 vue-cli 中包含很多 package 点开进去,每一个包都有package.json
  • 它里面有很多项目,再没有 Lerna 之前去维护和管理这么多包是会非常困难的
  • 而 webpack 至今还没有用任何的包管理工具,在其 lib 下会有非常多的模块
  • 而且它还自己写了很多脚本来进行管理各种功能
  • 同上上述正反两个例子,可见,不使用包管理工具,整个项目维护起来会很麻烦
  • 比如说你想去给 webpack 做一些贡献,很麻烦很困难,因为你不太清楚,你的改动对整体一个影响
  • 如果使用包管理以后,它就会拆的很清楚,你的改动就是聚合在一个package里面的,这个就是用包管理一些好处
  • 包管理目前流行的两种方式是 workspaces 和 Lerna

2 )workspaces 的基本使用

  • 在一个脚手架项目中,比如xyzcli项目中(之前一直用这个脚手架演示)创建workspaces 目录
    • $ mkdir workspaces && cd workspaces
  • 在 workspaces 目录中执行
    • $ npm init -y
    • 其实,在使用 npm init 的过程中,通过 $ npm init --help
    • 可以看到 Options 中存在 [-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
    • 也就是 -w 的参数, 比如:$ npm init -w a -w b 默认一路回车
    • 这样,就会在 workspaces 目录下新建了两个包:a 和 b,每个包中,都存在package.json,其name属性分别为 a 和 b
    • 在 workspace/node_modules下 生成a和b的两个软链
    • 在 workspace/package.json 中,存在 workspaces 的配置
      "workspaces": ["a","b"
      ]
      
  • 好,现在结构基本搭建完成,现在我要在 workspaces 目录对a包进行安装依赖
    • $ npm i vue -w a
    • 这时候,a包中安装了 chalk 的依赖,但是a包中没有生成 node_modules 目录
    • 在 workspaces 目录下的 node_modules 中安装了 chalk, 而 a 的 package.json 中的 dependencies 是 chalk
    • 同时,b包中的package.json中是没有的
  • 这是 workspace 非常有意思的特性,它把各个内层包的依赖抽象到了最外层来进行管理
  • 这里借助了 commonjs 中对 node_moduels 查找的特性,如果当前查找不到,去上一层目录中去查找
  • 由于此特性,可以通过最外层来管理依赖包,这样的好处是非常明显的
  • 现在在a包中使用chalk, 在package.json中添加 "type": "module" 在 a/index.js 中编写
    import  chalk from 'chalk';export default {print() {console.log(chalk.red('Hello workspace'))}
    }
    
  • 现在继续修改 a/package.json 中的 name属性,修改为:“@somegroup/a”
  • 这时候,a包就会在后续发布中,自动在 somegroup 分组中了,这个 somegroup 可以是自己起的任意组名
  • 好现在在workspaces目录中新增一个具有cli功能的包,比如就叫做 cli 这个脚手架包
  • $ npm init -w cli 一路回车, 创建了 cli 这个脚手架包
  • 将 cli 包的 package.json 目录中的name属性改成和a包同组,如:"name": "@somegroup/cli"
  • 同时在 workspaces/cli 的package.json中添加 bin 属性
    {"bin": {"cli": "bin/cli.mjs"}
    }
    
  • 因为这时候 cli 脚手架包的 name 不是在一开始创建的,而是一路回车之后,要确定和a同组的,需要执行下 $ npm i -ws 来更新下分组
    • 这时候可以看到 workspaces/node_modules/@somegroup/下存在 a 和 cli 两个软链
    • 同时,可以删除 workspaces/node_modules/cli 这个软链
  • 这时候,想要在 cli 这个脚手架包中引用 a包来调试,需要 在 workspaces 目录下执行
    • $ npm i @somegroup/a -w cli
    • 这时候,会在 cli 脚手架目录中添加了 @somegroup/a 这个 dependencies
  • 新建 bin/cli.mjs 编写
    #!/usr/bin/env nodeimport * as a from '@somegroup/a'const { print } = a.default;
    print();
    
  • 最后,可以将 这个 cli 工具在workspaces下配置使用, 因为在 workspace/node_modules/.bin 下有这个cli的软链
  • 所以在 workspaces/package.json 中添加配置
    "scripts": {"cli": "cli"
    },
    
  • 这时候在 workspaces 下执行 $ npm run cli, 这样,我们的脚手架就可以直接使用了,如下图
  • 以上就是使用 workspace 来进行包的管理,这里生成了3个包,其中包a和包cli都在@somegroup组下

  • 这里演示了脚手架包cli如何使用包a,在不发布的场景下进行调试,并且对cli包本地的调试

  • 同时,可以参考之前的文章:https://blog.csdn.net/Tyro_java/article/details/136112045

  • 好,现在发布之前, 还需要处理一下b包,毕竟建立这个包是有用的,不在远程发布有问题的包

  • 将b包的name修改成 "name": "@somegroup/b", 目前这三个包都在 @somegroup 组中了

  • 在b中新建 index.js, 在b/package.json中同步"main": "index.js", 并添加 "type": "module"

  • 给b包安装 ora 依赖,在 workspaces 目录下执行 $ npm i ora -w b

  • 编写 b/index.js

    import ora from 'ora';export default function() {const spinner = ora().start('loading');setTimeout(() => {spinner.stop();}, 3000)
    }
    
  • 因为修改了 b 的package.json的name属性,需要同步下 $ npm i -ws

  • 并且注意删除下之前 workspaces/node_modules/b 这个叫b的软链

  • 好,现在b包作为工具库为 cli 脚手架提供方法,为cli安装b包, 回到 workspaces 目录下

  • 执行 $ npm i @somegroup/b -w cli, 修改 cli/bin/cli.js 文件

    #!/usr/bin/env nodeimport a from '@somegroup/a'
    import bLoading from '@somegroup/b'const { print } = a;print();console.log('----------');bLoading();
    
  • 这时候万事俱备了,就可以发布上线了, 在 worksapces 目录中

    • npm publish -ws 发布所有 workspace 包内容,这个是全部包发布的举例
    • npm publish -w a 发布a包,这个是单个包发布的举例
  • 注意,如果包存在发布报错,可能是因为权限问题,可修改对应包的package.json

    {"publishConfig": {"access": "public"}
    }
    
  • 这样就顺利发布成功了,注意,Lerna 使用时会帮助我们考虑到这一点,Lerna 会省事一些

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/709987.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloudNacos注册中心服务分级存储模型

文章目录 服务分级存储模型概述配置集群同集群优先的负载均衡 权重配置总结 之前对 Nacos注册中心入门 已经做了演示. 这篇文章对 Nacos 的服务分级存储模型做理论与实践. 服务分级存储模型概述 一个服务可以有多个实例&#xff0c;例如我们的 user-server&#xff0c;可以有:…

C#使用iText7给PDF文档添加书签

上一篇文章将SqlSugar官网文档中每个链接对应的网页生成独立PDF文档再合并为单个PDF文档&#xff0c;但是没有书签&#xff0c;八百多页的内容查找和跳转都不方便&#xff0c;本文学习和使用iText7给PDF文档添加多级书签。   添加多级书签分为两大步骤&#xff1a;1&#xff…

VR全景HDR拍摄教程

什么是HDR&#xff1f; HDR可以用在哪里&#xff1f; 书面解释&#xff1a;HDR&#xff08;高动态范围 High Dynamic Range&#xff09;摄影&#xff0c;是摄影领域广泛使用的一种技术。 是不是有点懵&#xff1f; 我们来看一个实际的拍摄现场环境&#xff0c;你就懂了 我们…

使用 Gradle 版本目录进行依赖管理 - Android

/ 前言 / 在软件开发中&#xff0c;依赖管理是一个至关重要的方面。合理的依赖版本控制有助于确保项目的稳定性、安全性和可维护性。 Gradle版本目录&#xff08;Version Catalogs&#xff09;是 Gradle 构建工具的一个强大功能&#xff0c;它为项目提供了一种集中管理依赖…

定时任务框架

定时任务的框架有哪些 ● Timer&#xff0c;JDK自带的&#xff0c;比较简单&#xff0c;使用的时候&#xff0c;定义一个TimerTask&#xff0c;实现run方法&#xff0c;然后定义一个Timer类&#xff0c;调用timer.schedule(timerTask,1000,3000); ○ 缺点&#xff1a;单线程、…

附加Numpy数组

参考&#xff1a;Append Numpy Array 引言 在数据科学和机器学习领域&#xff0c;处理大规模数据集是一项重要且常见的任务。为了高效地处理数据&#xff0c;numpy是一个非常强大的Python库。本文将详细介绍numpy中的一个重要操作&#xff0c;即如何附加&#xff08;append&a…

LeetCode:2867. 统计树中的合法路径数目(筛质数+ DFS Java)

目录 2867. 统计树中的合法路径数目 题目描述&#xff1a; 实现代码与思路&#xff1a; 筛质数 DFS 原理思路&#xff1a; 2867. 统计树中的合法路径数目 题目描述&#xff1a; 给你一棵 n 个节点的无向树&#xff0c;节点编号为 1 到 n 。给你一个整数 n 和一个长度为 …

西软云XMS operate XXE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

Jquery操作DOM对象

文章目录 目录 文章目录 本章目标 一.DOM操作分类 二.JQuery中的DOM操作 内容操作 属性值操作 节点操作 节点属性操作 节点遍历 总结 本章目标 使用Jquery操作网页元素使用JQuery操作文本与属性值内容使用JQuery操作DOM节点使用Jquery遍历DOM节点使用JQuery操作CSS-DOM 一…

WebServer -- 日志系统(下)

目录 &#x1f33c;整体思路 &#x1f382;基础API fputs 可变参数宏 __VA_ARGS__ fflush &#x1f6a9;流程图与日志类定义 流程图 日志类定义 &#x1f33c;功能实现 生成日志文件 && 判断写入方式 日志分级与分文件 &#x1f33c;整体思路 日志系统分两部…

无法调试MFC源码

VS无法调试MFC源码 起初 有时候就是这么无奈&#xff0c;MFC源码各种问题没有办法调试&#xff0c;可是又想看下代码如何调用&#xff0c;里面做了些什么&#xff0c;从哪儿调出&#xff0c;学习一下大神的思路什么的。整理一下有可能的原因。 检查生成代码设置 需要设置正…

04 Opencv图像操作

文章目录 读写像素修改像素值Vec3b与Vec3F灰度图像增强获取图像通道bitwise_not 算子对图像非操作 读写像素 读一个GRAY像素点的像素值&#xff08;CV_8UC1&#xff09; Scalar intensity img.at(y, x); 或者 Scalar intensity img.at(Point(x, y)); 读一个RGB像素点的像素值…

虚拟机看不到共享文件夹

johnjohn-virtual-machine:/mnt/hgfs$ cat /etc/issue Ubuntu 20.04.6 LTS \n \l 看下是否挂载 johnjohn-virtual-machine:/mnt/hgfs$ vmware-hgfsclient FPGAs_AdaptiveSoCs_Unified_2023.2_1013_2256 xilinx 取消挂载 johnjohn-virtual-machine:/mnt/hgfs$ sudo umount /mn…

kvm虚拟机修改网络模式

kvm修改网络模式可以直接使用virsh命令进行修改 一、查看主机 virsh list --all 二、查看需要修改主机的网络模式 virsh domiflist mysql 三、vim进行修改 cd /etc/libvirt/qemu/ vim mysql.xml 四、找到要修改的网卡部分 五、重新定义虚拟机 virsh define mysql_install.xml…

java工具类之解析地址

输出 代码实现 import java.util.regex.Matcher; import java.util.regex.Pattern;public class AddressResolutionUtil {/*** 解析地址* author ys* param address* return*/public static String addressResolution(String address){String regex"(?<province>…

Java的编程之旅32——继承与多态的联合使用

模拟USB设备接入电脑 1.首先建立一个名为“USB”的抽象类 public abstract class USB {public abstract void On();public abstract void Off(); }这是一个抽象类USB&#xff0c;表示一个USB设备。 该类有两个抽象方法On()和Off()&#xff0c;分别表示打开和关闭USB设备。 由…

javaee教程郑阿奇,一线互联网架构师筑基必备技能之Java篇

一、什么情况下会发生栈内存溢出&#xff1f; 1、栈是线程私有的&#xff0c;栈的生命周期和线程一样&#xff0c;每个方法在执行的时候就会创建一个栈帧&#xff0c;它包含局部变量表、操作数栈、动态链接、方法出口等信息&#xff0c;局部变量表又包括基本数据类型和对象的引…

【GameFramework框架内置模块】6、实体(Entity)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录&#xff1a; https://blog.csdn.net/q7…

K 个一组翻转链表 力扣

【玩转校招算法面试】第三天&#xff1a;链表中的节点每k个一组翻转&#xff08;动画演示、手写 Java 代码、详细注释、LeetCode 高频算法题&#xff09;_哔哩哔哩_bilibili 初始状态&#xff1a;1 -> 2 -> 3&#xff0c;pre null, cur 1保存当前节点的下一个节点&…

并查集基础,死去的回忆突然攻击我

并查集普及【模板】并查集 - 洛谷 #include<iostream> #include<cstring> #include<queue> #include<vector> #include<algorithm> using namespace std; #define int long long typedef pair<int,int> PII; #define xx first #define y…