原因: npm和yarn都会有又大又慢的node_modules,最大的问题是 扁平化的node_modules,扁平化虽然解决了依赖地狱问题,但是它也带来了新的问题
1、幽灵依赖,eg:当安装了一个A包,这个A包自己依赖了B包,因为扁平化B包也会被提升到node_modules的根目录,产生的问题就是,你的package.json 里没有声明B包,但是可以引入B包且能正常使用,(万一一天A包升级,不在引入B包,项目就有可能崩溃,甚至不知道B是从哪里来的)
2、磁盘空间的巨大浪费 如果你的电脑上有10个项目,这10个项目都依赖A包,那么再npm和yarn的模式下,你的磁盘上就会存10份A包,造成磁盘的浪费
3、安装速度的瓶颈 虽然npm和yarn都有缓存机制,但是在安装依赖时他们仍然需要大量的I/O操作,去复制和移动这些文件,项目越大安装速度越慢
pnpm的解决方法
1、彻底告别幽灵依赖
在pnpm的node_modules中,你只会看到再package.json中声明的哪些依赖。
项目中A包,它自己所依赖的B包,会被存放在node_modules/.pnpm/ 这个特殊的目录中,
然后通过符号链接(Symbolic Link) 的方式,连接到A包的node_modules中。这就意味着你在项目中想访问B包根本访问不到
2、磁盘的节约
pnpm会再电脑上创建一个全局内容可寻址存储区(content-addressable store),通常在用户主目录下的 .pnpm-store 里
电脑上所有项目的所有依赖,都只会在这个全局仓库里,实实在在的只存一份
当你的项目中需要依赖A包的时候,pnpm不会去复制一份到node_modules,而是通过硬链接(Hard Link) 从全局仓库链接一份过来,硬链接几乎不占用磁盘空间,所以无论有多少个项目依赖了A包,都只会有一份A包,省磁盘空间
3、极速的安装体验
大部分依赖是通过链接的方式实现,而不是复制,所以pnpm在安装依赖时,大大减少了I/O操作,安装速度飞一般的感觉
Monorepo,即“单个仓库多项目管理”,是一种项目代码管理方式,它将多个项目或模块的代码集中管理在一个仓库中。这种方式有助于简化代码共享、版本控制、构建和部署等方面的复杂性,并提供更好的可重用性和协作性
利用pnpm workspace功能,实现一个高效的多项目管理方案
一、根目录下 创建 pnpm-workspace.yaml
packages:
# 指定根目录直接子目录中的包
# - 'main'
# # packages/ 直接子目录中的所有包
# - 'packages/*'
# components/ 子目录中的所有包
- 'src/modules/**'
# 排除测试目录中的包
# - '!**/test/**'pnpm
2、npm run installProject 中 installProject文件
(1)移除符号链接(软链)步骤
(2) 移除解压 node_modules.zip 的步骤
(3)保留配置文件的修改
- 缺少安装:pnpm add -w @vue/babel-helper-vue-jsx-merge-props element-resize-detector
- client 下需要装一个http-errors pnpm add http-errors --filter kikyo-bff
- app3 下缺少 pnpm add core-js@3.25.5 --filter kikyo-custom-app3
- ###client 下缺少一个client 文件夹 (待排查)
- ###kikyo-release下缺少一个 client.json (待排查)
- ###client 下 www.js 没有复制进去(待排查)
- 3、需要重新跑一次pnpm i
4、vue ui 项目管理器(需要各个模块编译之后才能访问)
问题:代码更改后,vue ui 没有自动编译
文件的复制
//sourceFilePath:源文件的完整路径(如 /data/image.jpg)
//destinationFolderPath:目标文件夹路径(如 /backups)
//callBack:复制完成后的回调函数(可选)
function copyFileUtils(sourceFilePath, destinationFolderPath,callBack) {
// 确保目标文件夹存在
if (!fs.existsSync(destinationFolderPath)) {
fs.mkdirSync(destinationFolderPath, { recursive: true });
}
const destinationFilePath = path.join(destinationFolderPath, path.basename(sourceFilePath));
// **作用**:拼接目标文件的完整路径。
//`path.basename(sourceFilePath)`:提取源文件名(如 `image.jpg`)。
// `path.join(...)`:将目标文件夹路径和文件名合并(如 `/backups/image.jpg`)。
//### 文件的复制
fs.copyFile(sourceFilePath, destinationFilePath, (err) => {
if (err) {
console.error('文件复制失败:', err);
} else {
console.log('文件复制成功!');
if(callBack){
callBack()
}
}
});
}
//从当前文件所在目录(`__dirname`)出发,向上回退两级目录(`../../`),再进入 `src/modules/client`。
copyFileUtils(path.join(__dirname, '../../src/modules/client/settings/develop/www.js'), path.join(__dirname, '../../src/modules/client'), () => {
console.log('client模块核心代理www.js已就绪')
})
fs.existsSync(path)
fs.existsSync(path): 验证文件是否存在。path为要验证的文件路径
fs.mkdirSync
fs.mkdirSync(path,{recursive:true}) 创建目标文件夹
recursive: true 表示递归创建多层目录(类似 mkdir -p)。
path.basename
返回最后一部分path.basename(path, [,suffix])
path - 路径
suffix - 要删除的后缀,(可选)
path.join 拼接路径
const path = require('path')
path.join('/a', 'b', 'c', './', 'd') // /a/b/c/d
path.join('/a', 'b', 'c', '../', 'd') // /a/b/d
path.join('/a', 'b/c', 'd') // /a/b/c/d
__dirname
__dirname 是指获取当前文件在当前项目中的准确路径
fs.readFileSync
jenkins配置
原版备份
nodejs
export MAVEN_HOME=/app/soft/apache-maven-3.6.3 export NODE_HOME=/app/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/nodejs-14.18.3/ #export NODE_HOME=/app/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/nodejs-16.19.0/ export PATH=PATH
cd isDeleteClientFile" = "YES" ] ; then rm -rf ./client fi
npm config set registry=nexusdev.fsfund.com/repository/…
npm install npm run installProjectProduction npm run vcProjectProduction NODE_ENV=production #npm run {module} NODE_ENV=production #npm run start m={module} NODE_ENV=production config=${config}
解决WORKSPACE下执行
#cd /app/jenkins/workspace/kikyo-chat-client-docker/client #export http_proxy=squidtest.fsfund.com:3128 #export https_proxy=squidtest.fsfund.com:3128
当pnpm 已安装
nodejs
export MAVEN_HOME=/app/soft/apache-maven-3.6.3 export NODE_HOME=/app/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/nodejs-14.18.3/ #export NODE_HOME=/app/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/nodejs-16.19.0/ export PATH=PATH
cd isDeleteClientFile" = "YES" ]; then rm -rf ./client fi
设置 pnpm 的 registry
pnpm config set registry nexusdev.fsfund.com/repository/…
安装项目依赖
pnpm install
运行生产环境的项目安装脚本
pnpm run installProjectProduction
运行生产环境的构建脚本
pnpm run vcProjectProduction NODE_ENV=production #pnpm run {module} NODE_ENV=production #pnpm run start m={module} NODE_ENV=production config=${config}
解决WORKSPACE下执行
cd $WORKSPACE/client
export http_proxy=squidtest.fsfund.com:3128
export https_proxy=squidtest.fsfund.com:3128
当pnpm 未安装 This version of pnpm requires at least Node.js v18.12
nodejs
export MAVEN_HOME=/app/soft/apache-maven-3.6.3 export NODE_HOME=/app/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/nodejs-18.18.0/ #export NODE_HOME=/app/jenkins/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/nodejs-16.19.0/ export PATH=PATH
cd isDeleteClientFile" = "YES" ]; then rm -rf ./client fi
检查 pnpm 是否已安装
if ! command -v pnpm &> /dev/null; then echo "pnpm 未安装。正在安装 pnpm..." npm install -g pnpm else echo "pnpm 已安装,版本: $(pnpm --version)" fi
设置 pnpm 的 registry
pnpm config set registry=nexusdev.fsfund.com/repository/…
使用 pnpm 进行构建
pnpm install pnpm run installProjectProduction pnpm run vcProjectProduction NODE_ENV=production #pnpm run {module} NODE_ENV=production #pnpm run start m={module} NODE_ENV=production config=${config}
解决WORKSPACE下执行
#cd /app/jenkins/workspace/kikyo-chat-client-docker/client #export http_proxy=squidtest.fsfund.com:3128 #export https_proxy=squidtest.fsfund.com:3128