npm

资料

其他包管理工具

  • cnpm
    • 不要使用cnpm替代npm,cnpm会有一些奇怪的问题。
  • pnpm
    • 由于npm对每个项目都会安装包的副本比较浪费空间
    • pnpm则是做链接的形式来安装包目录,节省空间。
  • yarn

常用命令

  • npm config set registry https://registry.npmmirror.com
    • 设置成淘宝的镜像
    • registry.npm.taobao.org 是已经被淘汰的老地址了
  • npm install 包名称
    • npm install
      • 安装本目录项目的所有依赖
    • -g 安装全局包
    • -save:安装本项目的包,默认包含
    • --save-dev 安装到开发依赖下面,build的时候不会被打包
    • 例如:
      • npm install vue 「不指定版本,会安装当前最新的vue版本」
      • npm install vue@3.5.0 「明确的安装3.5.0版本」
    • 包安装后会在node_modules下出现模块的目录
      • npm uninstall 模块名
        • 卸载模块后模块目录就删除了
        • 如果有scope目录,则scope目录会被保留
    • npm update 模块名
      • 更新为最新模块
  • npm list
    • -g 列出全局安装的模块,含版本号
    • 不加参数 列出本目录项目安装的模块,含版本号
    • npm list 模块名称 「显示模块的被依赖情况,含版本号」
  • npm ls 模块
    • 查看哪些模块依赖这个模块
  • npm cache clear 可以清空npm本地缓存,清理后可以重新安装「获取最新代码」
  • npm publish <package> 发布包到NPM网站,类似:git push
  • npm unpublis <package>@<version> 撤销已发布包的某个版本

全局包和本地包

  • 全局包和本地包是互相独立的
    • 全局包主要是为了执行命令使用,例如: npm create-vue
    • 本地包主要是为了项目引用编程使用
    • 全局包安装了,本地包没有安装,在项目用引用包也会报错的
  • 即使某个包已全局安装,项目仍需本地安装才能被代码引用
  • 本地安装的包 优先级高于全局包(如果两者版本不同)
  • 特殊情况:npm link
    • npm link my-global-package 「可以安装全局包到本地, 供本地项目使用」

package.json 配置文件

  • name
    • 包名称
    • 作用域(scoped)
      • 例如:@my-scope/my-library
      • 作用域必须以@开头
      • 带有作用域的包,在node_module下结构:node_modules/@my-scope/my-libray
      • 只是名字不同没有其他区别
      • 如果要发布到npm,则需要scope需要和自己的账户或者org匹配
      • 安装的时候:npm install @my-scope/my-library
      • 在开发中引用包:import myLibray from '@my-scope/my-library';
  • npm 的官方说明文档
  • node 官网文档说明
  • ⚠️:package.json 文件要npm官方文档和nodejs官方文档结合着来看,因为他们的侧重不同,不同配置写的详细程度也不同。nodejs写的要细致一些。
  • vite 官方文档对package.json的配置建议
    #此配置文件兼容了旧版「main」、早期社区约定「module, module「ESModule」模块导入方式的入口文件」和现代版本「exports」的配置
    {
        "name": "my-lib",
        "type": "module",
        "files": ["dist"],
        "main": "./dist/my-lib.umd.cjs",
        "module": "./dist/my-lib.js",
        "exports": {
            ".": {
            "import": "./dist/my-lib.js",
            "require": "./dist/my-lib.umd.cjs"
            }
        }
    }
    
  • package.json 用途说明
    • 用于管理项目
      • 主要是npm使用
      • 主要使用到的字段:
        • script 「可执行的命令」
        • dependencies 「运行/发布依赖的包」
        • devDependencies 「开发阶段依赖的包」
    • 用于打包库/模块
      • name 「包名称」
      • type 「导出的:模块类型: moduel「ESModuels」, commonjs 」
      • main 「导出的:nodejs 版本<= 10 支持, 主入口文件, .js (普通js文件) .mjs (moduel「ESModuel」文件) .cjs (commonjs 文件)」,是早期标准
      • exports 「导出的:现代推荐标准 nodejs 版本 > 10 支持, 优先级高于 main」
      • files 「软件包作为依赖项安装时要包含的文件夹/文件」
        • 此字段主要用于 npm 发布包的时候使用,与vite build 库没有关系。
        • 无论设置如何,始终包含某些文件:
          • package.json
          • README
          • LICENSE / LICENCE
          • “main” 字段中的文件
          • “bin” 字段中的文件
      • module 「指定module文件入库,早期社区约定」
      • peerDependencies 「运行需要,但又不到包进来,需要使用此包的项目自己安装」
  • moduels 字段
    • 是早期的社区是社区早期约定(由 Rollup、Webpack 等工具提出),用于指定 ESM 入口,但 并非 Node.js 官方标准。Node.js 官方更推荐使用 "exports" 字段来定义模块入口。在node.js 和npmjs的官网中都没有该字段的说明。
  • type 字段是nodejs自己使用的「只有nodejs支持」,不是npm制定的。
    • 说明文档在node官网中,npm官网中是没有的
    • type字段是从nodejs v12.17.0 以后开始支持的
    • type: module
      • js 文件使用ESModule「es6的标准」标准引入模块
    • type: commonjs 「默认值」
      • js 文件使用commonjs引入模块
    • 无论type为什么值,.mjs 文件被视为ES模块
    • 无论type为什么值,.cjs 文件被视为CommonJS模块
    • "exports" 中 "import" 和 "require" 的优先级高于 "type"。
      • 因为 import 和 require已经明确指明了js的模块加载方式
      • 所以及时设置 type: commonjs; import: index.js 也不会影响import文件的设置。
  • exports
    • nodejs 版本 >= 12.20 开始支持 ,main字段的替代方案
    • 如果使用现代方案,其实:main、type 和 module 字段都是不需要的。
  • peerDependencies(对等依赖):
    • 当用户安装带有 peerDependencies 的包时:
    • npm v7+:自动安装对等依赖(除非用户手动禁用或冲突)。
    • npm v6 及以下:仅警告用户需要手动安装对等依赖。
    • Yarn:默认不自动安装,需通过 yarn install --peer 显式启用。
    • 如果用户未安装或版本不匹配,会收到警告: npm WARN webpack-plugin-x@1.0.0 requires a peer of webpack@^5.0.0 but none is installed.
  • dependencies:运行时候的依赖
  • devDependencies:开发时候的依赖。
  • 依赖关系说明:
    • 运行时候的包,在开发的时候一定可以用。
    • 所以没有包的名字会同时出现在:dependencies和devDependencies中。
    • dependencies:发布的时候会被发布打包。
    • devDependencies:发布的时候不会被带着打包
    • 如果先安装运行时依赖包,再安装同一个包到开发时依赖,则:
      • dependencies:里面原来的包会被移除
      • devDependencies:里面会增加安装的包。

package.jsonpackage-lock.json的区别

  • 它们共同管理项目依赖,但职责不同
  • package.json
    • 声明依赖范围:定义项目所需的依赖(dependenciesdevDependencies)及其允许的版本范围(如 ^1.2.0)。
    • 项目元信息:包含项目名称、版本、脚本命令(scripts)、作者等元数据。
    • 特点:
      • 版本灵活性: 使用语义化版本(SemVer)规则(如 ^~),允许安装兼容的最新版本。
      • 手动维护: 开发者直接编辑该文件来添加/删除依赖。
    • 生成方式:
      • 通过 npm init 创建,或手动编写。
  • package-lock.json
    • 作用
      • 锁定依赖树:精确记录当前安装的每个依赖的确定版本及其子依赖的完整依赖树。
      • 保证一致性:确保团队协作或重新安装时,所有人得到完全相同的依赖版本。
    • 特点
      • 版本精确性:固定所有依赖的具体版本号(无模糊范围)。
      "lodash": {
          "version": "4.17.21",  // 精确版本
          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
      }
      
    • 自动生成:由 npm 自动创建和更新(无需手动编辑)。
    • 不可发布:不会被发布到 npm 仓库(仅用于本地开发)。
    • 生成方式
      • 通过 npm install 自动生成或更新。
  • 常见问题
    • Q1: 为什么需要提交 package-lock.json 到 Git?
      • 避免因依赖版本浮动导致团队环境不一致(“在我机器上是好的”问题)。
    • Q2: 两者冲突时以谁为准?
      • npm install 时优先以 package-lock.json 为准(除非手动指定 --no-save 或删除 lock 文件)。
    • Q3: 何时会更新 package-lock.json
      • 执行 npm installnpm update 或直接修改 package.json 后安装依赖时。
  • 总结
    • package.json:定义“我想要什么版本的依赖”(允许灵活更新)。
    • package-lock.json:记录“实际安装的精确版本”(确保一致性)。
      两者配合使用,既保留版本控制的灵活性,又保证开发环境的稳定性。

yarn

  • 主要为了解决老版本npm的一些缺陷, - 例如:运行缓慢,同一项目多人开发版本不一致等问题。
    • 安装yarn:npm install -g yarn
      • 查看版本: yarn --version
    • 常见命令:
      • yarn init
      • yarn install
        • 安装package.json中的所有依赖包,并将包及依赖关系保存进yarn.lock
      • yarn install --flat 安装一个包的单一版本
      • yarn install --force 强制下载所有包
      • yarn install --production 只安装dependencies里面的包
      • yarn install --no-lockfile 不读取或生成yarn.lock
      • yarn install --pure-lockfile 不生成yarn.lock
      • yarn add package 在当前项目添加一个包,会更新package.json 和yarn.lock文件
      • yarn add package@version
      • yarn add package@tag 安装某个tag(比如:beta,next和latest)
      • yarn add --dev/-D 安装后加到package.json 的 devDependencies
      • yarn add --peer/-P 安装后加到package.json 的 peerDependencies
      • yarn add --optional/-O 安装后加到package.json 的 optionalDependencies
  • 基本使用
  • 优点
  • 和npm的对比
    • 从npm 5.0 以后npm进行了改进,yarn已经没有明显优势了,可以直接使用npm