npm pack 命令生成离线npm模块/npm依赖包

这篇具有很好参考价值的文章主要介绍了npm pack 命令生成离线npm模块/npm依赖包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

环境

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}`));
});

思考

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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端主流框架:项目运行命令 npm 详解

            作为一位资深前端开发,我对npm(Node Package Manager)的使用有着深入的了解。npm是Node.js的包管理器,用于安装、管理和删除各种前端库和工具。现在,让我们深入了解npm在Vue、React、Angular和Vue 3项目中的一些基本使用方法和配置。 npm提供了一系列命令,用于管理项

    2024年02月19日
    浏览(36)
  • npm常用命令 + 前端常用的包管理工具 以及 npm淘宝镜像配置等

    下载地址 官网: https://nodejs.org/en. 中文网站: https://nodejs.org/zh-cn. 安装之后,使用 node -v 命令查看安装的版本,如下: 关于windows上的安装可以参考下面的文章: vue2入门——菜鸟级1篇. 前端常用的包管理工具有:npm、cnpm、yarn,更多请继续…… 前端常用的包管理工具有:n

    2024年02月11日
    浏览(48)
  • 离线环境conda虚拟环境备份迁移--conda pack问题

    1.第一步:创建虚拟环境 conda create -n pyenv --clone base  或者 conda create -n pyenv python==3.8.5 --offline 命令执行结束,在路径/xxxx/anaconda/envs 下看到pyenv 或者 conda info --envs 查看罗列虚拟环境 2.第二步:打包环境 conda pack -n pyenv -o /xxxxx/pyenv.tar.gz 报错: Collecting packages... CondaPackError:  F

    2024年02月13日
    浏览(32)
  • maven install命令:将包安装在本地仓库,供本地的其它工程或者模块依赖

    有时候,自己本地的maven工程依赖于本地的其它工程,或者manven工程中的一个模块依赖于另外的模块,可以执行maven的install命令,将被依赖的包安装在maven本地仓库。 maven的install插件的介绍可以参考:https://maven.apache.org/plugins/maven-install-plugin/ maven的install插件有三个goals: ins

    2024年02月14日
    浏览(48)
  • 前端命令npm 、 cnpm、 pnpm、yarn 、 npx、nvm的区别

    大名鼎鼎的 npm (Node Package Manager)是随同NodeJS一起安装的包管理工具,NPM本身也是Node.js的一个模块。 npm的含义有两层: npm服务器,npm服务器网址为https://www.npmjs.org,npm是 Node 包的标准发布平台,用于 Node 包的发布、传播; npm包管理器,指在命令行窗口或终端使用npm命令来管理

    2024年02月11日
    浏览(51)
  • 前端构建工具 代码优化压缩 模块管理 依赖管理 资源处理转换 自动化任务 流程优化 高级特性 Webpack Parcel Rollup Gulp 静态资源

    前端构建在前端开发中具有重要的意义,主要有以下几个方面: 代码优化和压缩:前端构建工具可以对前端代码进行优化和压缩,例如去除注释、空格,合并和缩小文件大小等。这可以减少文件的加载时间和传输大小,提高网页加载速度,优化用户体验 模块管理和依赖管理

    2024年02月09日
    浏览(39)
  • 解决报错:Not implemented: HTMLCanvasElement.prototype.getContext (xxx installing the canvas npm pack

    这个是在js逆向中使用jsdom模拟浏览器环境,结果还是报错了:  网上很多说法是安装canvas: npm install canvas,其实并不正确  解决办法:加入以下代码: window.HTMLCanvasElement.prototype.getContext = () = {   // return whatever getContext has to return }; 问题解决:  

    2024年02月20日
    浏览(39)
  • RuoYi-Vue-generator 代码生成模块 动态 多数据源切换 前端+后台

    需求场景: 若依框架的30张数据表 和 业务使用的数据表,同数据源,但分开的两个库,原生若依只支持主库的代码生成,故自己修改添加代码来实现 若依多数据源的使用 修改页面ruoyi-uisrcviewstoolgenimportTable.vue el-form 中新增 el-form-item 添加 data 添加方法 ruoyi-uisrcapitool

    2024年02月04日
    浏览(41)
  • npm安装指定版本包,npm按版本安装;npm删除依赖,卸载依赖

    例如安装element-ui的2.15.8版本 在package.json中可以看到: 注:已有版本的情况下需要先删除依赖,不能直接在package.json中改版本号,因为package-lock.json中仍然是修改前的版本号。 1、全局安装 2、本地安装 3、信息写入

    2024年02月12日
    浏览(52)
  • 前端js,uniapp使用printease连接打印机打印,打印命令生成

    接下来我们将使用printease实现前端js,uniapp打印。 此外,连接打印机的方式有很多种,这里并不会涉及到,该库只是提供了一种打印机指令的生成方式,你可以将生成的指令发送到打印机,打印机会执行一次印刷过程。 这个教程是关于tspl指令的,如果你使用的其他指令,可

    2024年02月13日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包