环境
node v16.10.0 npm v8.3.0
在使用npm
管理第三方模块时,这些模块通常会被安装在 node_modules
目录下。当我们需要把模块给其他小伙伴或者搭建npm
私服时,需要将node_modules
的所有模块生成N个packname-version.tgz
文件,方便其他小伙伴使用npm install packname-version.tgz
命令安装或者使用npm publish packname-version.tgz
命令发布到私服时,这个nodejs
脚本或许对你有一些帮助🎉。
下面是实现这一功能的脚本,具体实现过程如下:
1. 遍历目录,查找所有的package.json文件
首先,我们需要遍历node_modules
目录,查找所有的 package.json
文件,这里我们使用递归实现。
function findPackageJson(directory) {
const results = [];
const files = fs.readdirSync(directory);
for (const file of files) {
const filePath = path.join(directory, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
results.push(...findPackageJson(filePath));
} else if (file === "package.json") {
results.push(filePath);
}
}
return results;
}
2. 执行 npm pack 命令,生成 .tgz 文件
接下来,我们需要执行 npm pack
命令,生成一个压缩文件,这里我们使用 child_process
模块的 exec
方法来执行命令。
function packModule(moduleDir) {
return new Promise((resolve, reject) => {
exec("npm pack", { cwd: moduleDir }, (err, stdout, stderr) => {
if (err) {
reject(err);
} else {
const tgzFile = path.join(moduleDir, `${stdout.trim()}`);
resolve(tgzFile);
}
});
});
}
在执行完 npm pack
命令后,会在当前目录下生成一个以模块名为前缀的压缩文件,例如:lodash-4.17.21.tgz
。
3. 移动 .tgz 文件到 packs 目录
最后,我们需要将生成的压缩文件移动到指定的目录下,这里我们使用 fs
模块的 renameSync
方法实现。
function moveTgzFile(tgzFile) {
const fileName = path.basename(tgzFile);
const destFile = path.join(packsDir, fileName);
fs.renameSync(tgzFile, destFile);
console.log(`Moved ${fileName} to ${destFile}`);
}
将以上三个步骤结合起来,就可以实现将所有依赖包打包成压缩文件,并将其移动到指定目录下的功能了。
完整代码
// 根据 node modules下的依赖 利用npm pack 命令生成xxx.tgz依赖包 并放在packs目录下
const fs = require("fs");
const path = require("path");
const { exec } = require("child_process");
// C:\Users\Lenovo\Desktop\pack\node_modules
const modulesDir = path.join(__dirname, "node_modules");
const packsDir = path.join(__dirname, "packs");
// 遍历目录,查找所有的 package.json 文件
function findPackageJson(directory) {
const results = [];
const files = fs.readdirSync(directory);
for (const file of files) {
const filePath = path.join(directory, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
results.push(...findPackageJson(filePath));
} else if (file === "package.json") {
results.push(filePath);
}
}
return results;
}
// 执行 `npm pack` 命令,生成 `.tgz` 文件
function packModule(moduleDir) {
return new Promise((resolve, reject) => {
exec("npm pack", { cwd: moduleDir }, (err, stdout, stderr) => {
if (err) {
reject(err);
} else {
const tgzFile = path.join(moduleDir, `${stdout.trim()}`);
resolve(tgzFile);
}
});
});
}
// 移动 `.tgz` 文件到 `packs` 目录
function moveTgzFile(tgzFile) {
const fileName = path.basename(tgzFile);
const destFile = path.join(packsDir, fileName);
fs.renameSync(tgzFile, destFile);
console.log(`Moved ${fileName} to ${destFile}`);
}
// 查找所有的 package.json 文件,执行 `npm pack`,并移动生成的 `.tgz` 文件
findPackageJson(modulesDir).forEach((packageJsonFile) => {
const moduleDir = path.dirname(packageJsonFile);
packModule(moduleDir)
.then(moveTgzFile)
.catch((err) => console.error(`Error packing ${moduleDir}: ${err.message}`));
});
思考文章来源:https://www.toymoban.com/news/detail-769319.html
当node_modules
里的模块很多时,这个脚本的运行时间可能会很长(old cpu
🤣),所以还有很多优化空间,仔细观察node_modules
文件夹的目录结构会发现当目录名称包含@
符号时,这个目录下可能存在多个依赖包 ,普通目录一个依赖包。所以findPackageJson
方法可以做如下优化:文章来源地址https://www.toymoban.com/news/detail-769319.html
// 遍历目录 当目录下存在 package.json 文件时 退出当前循环
function findPackageJson(directory) {
const results = [];
const files = fs.readdirSync(directory);
for (const file of files) {
const filePath = path.join(directory, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
const packagePath = path.join(filePath, "package.json")
if (fs.existsSync(packagePath)) {
results.push(packagePath);
continue;
}
results.push(...findPackageJson(filePath));
}
}
return results;
}
到了这里,关于npm pack 命令生成离线npm模块/npm依赖包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!