【NPM 笔记(一)】NPM 入门知识:命令、依赖与脚本核心

27 阅读7分钟

npm介绍

npm是前端项目和 Node.js 项目的包管理工具,从项目开发到更新维护都发挥着重要作用。

  • 下载依赖:下载、卸载、更新项目所需的第三方依赖包,并管理依赖版本(如锁定版本、处理冲突)。
  • 执行脚本:执行项目中预定义的脚本命令(如 package.jsonscripts 配置),方便项目启动、打包构建等操作。
  • 发布包:将自己开发的第三方依赖包发布到 npm仓库,供其他开发者使用和维护。

image-20240726233723015

npm命令

安装项目所有依赖包

# 方式一(完整写法)
npm install 

# 方式二(简写)
npm i

当执行 npm install时:

  • 存在 package-lock.json
    1. 严格按照其中锁定的精确版本安装依赖(如 vue@2.6.12
    2. 无视 package.json 中的版本范围符号(如 ^~
    3. 即使远程仓库有更新版本,只要 package-lock.json 未修改,就不会安装新版本
  • 不存在 package-lock.json
    1. 根据 package.json 中的版本范围安装最新可用版本(如 vue: "^2.6.12" 会安装vue@2.7.16
    2. 自动生成新的 package-lock.json,锁定当前安装的版本
    3. 不会修改 package.json 中的版本声明(仍保留 vue: "^2.6.12"

安装依赖包

当执行 npm install <package> 时,无论是否存在 package-lock.json,npm都会:

  1. 根据 package.json 中的版本范围安装最新可用版本。
  2. 更新 package.jsonpackage-lock.json 中的版本记录。

例如:若 package.json 中写着 vue: "^2.6.12",执行 npm install vue 会安装 vue@2.7.16(符合 vue: "^2.6.12" 的最新版本),并更新 package.jsonpackage-lock.json 中的版本声明。

# 方式一(完整写法)
npm install vue

# 方式二(简写)
npm i vue
安装开发环境的依赖包

开发者日常编写、调试、测试代码的本地环境

# 方式一(默认)
npm install vue

# 方式二(完整写法)
npm install vue --save

# 方式三(简写)
npm install vue -S

自动在 package.jsondependencies 字段添加依赖记录,用于生产环境。

{
    "dependencies": {
        "vue": "^2.7.16"
    }
}
安装生产环境的依赖包

应用最终部署并面向用户正式运行的环境

# 方式一(完整写法)
npm install webpack --save-dev

# 方式二(简写)
npm install webpack -D

自动在 package.jsondevDependencies 字段添加依赖记录,仅用于开发环境。

{
    "devDependencies": {
        "webpack": "^5.88.2"
    }
}
补充说明

dependenciesdevDependencies 的划分只是一种语义约定,并不强制决定哪些包最终会被打包到产物中。

element-plus 为例:它会在 devDependencies 中列出 vuevue-router 等库,而这些库实际上是 element-plus 运行时所必需的。

决定哪些包最终会被打包到产物中的核心因素:

  • 是否在项目代码中被直接引用(如通过 importrequire 引入)
  • 是否被构建工具通过 external 配置排除(若被排除,则不会打包进产物)

卸载依赖包

# 方式一
npm uninstall vue

# 方式二
npm r vue

# 方式三
npm remove vue
  1. 移除node_modules中依赖包
  2. package.jsondependencies字段 或 devDependencies字段移除依赖记录。

查看配置

npm config list

查看包的基本信息

npm info md5

查看当前项目的所有包

npm list

检查项目包是否过期

npm outdated

npm不足

占用空间

多个项目的node_modules中的依赖包是独立存储的,导致同一版本、同一名称的依赖包会在磁盘的不同位置重复出现,极大地浪费了磁盘存储空间。

幽灵依赖

{
    "type": "module",
    "dependencies": {
        "vue": "^3.5.18"
    }
}
import { nanoid } from 'nanoid'

console.log(nanoid());

node ./index

nanoid 本身并非项目在 package.json 中直接声明的依赖,而是 vue 内部依赖的包。但由于 npm 会将所有依赖(包括子依赖)尽可能 “提升” 到 node_modules 顶层目录(扁平化处理),使得项目代码中可以直接引入 nanoid 并使用,即便它未被显式声明。

这种情况的隐患在于:

  • vue 后续升级时移除了对 nanoid 的依赖,项目中直接使用 nanoid 的代码会突然报错(依赖断裂)。
  • 项目依赖关系不透明,开发者难以从 package.json 中清晰判断哪些包是 “真正被依赖” 的。

npm开发脚手架

创建全局模块软链接

npm link 是 npm提供的一个用于本地模块开发与调试的强大工具,其核心作用是在本地建立模块的软链接,允许你在不发布到 npm仓库的情况下,将本地开发的模块实时应用到其他项目中。

1.创建 a-p-dev 项目并配置 package.json

{
    "name": "a-p-dev",
    "bin": {
        "a-p-dev": "bin/index.js"
    },
    "main": "bin/index.js"
}
  1. 在项目目录中执行 npm link
npm link
  • 此时会在全局 node_modules 目录下创建一个指向当前项目目录的软链接。

  • 若项目的 package.json 中存在 bin 字段,npm会自动在 全局nodejs 目录创建可执行文件:

    • Windows:a-p-dev.cmda-p-dev.ps1(PowerShell 脚本)。
    • Linux/macOS:a-p-dev(符号链接)。

  1. 在任意目录的cmd行中执行 a-p-dev,即可触发本地项目中 bin/index.js 的执行。

补充说明

无论是全局 node_modules 目录下创建的模块目录,还是全局 nodejs 目录下生成的可执行文件(如 a-p-deva-p-dev.cmd 等),其本质都是软链接(符号链接)

这意味着:

  • 这些文件 / 目录并非原项目代码的复制,而是指向本地开发项目真实路径的 快捷方式
  • 当原项目代码(如 bin/index.js)发生改变时,无需重新执行 npm link,全局引用会实时同步最新代码

解除全局模块软链接

npm unlink a-p-dev -g
  • 删除全局 node_modules 目录下的软链接目录。
  • 删除全局 nodejs 目录下的可执行文件。

npm 执行命令

执行当前项目可执行文件

当使用 npm install 安装带有命令行工具的依赖包(如 lesseslint)时,这些工具会被安装到项目的 node_modules/.bin 目录中。

以下是三种常用的执行方式:

进入 .bin 目录执行(了解即可)

# 进入项目本地的 .bin 目录
cd ./node_modules/.bin

# 执行命令(例如查看 lessc 版本)
lessc -v

这种方式需要手动切换到 .bin 目录,适合临时验证文件是否存在,日常开发中较少直接使用。

npx指令

# 无需进入 .bin 目录,直接执行本地命令
npx lessc -v

npx

  • 核心特点
    • 自动路径查找npx 会优先检索项目 node_modules/.bin 目录,无需手动指定路径。
    • 临时安装能力:若本地未安装目标命令(如首次使用 create-react-app),npx 会临时下载并执行,执行结束后,自动清理临时文件,避免全局安装污染环境。
    • 版本隔离:确保使用的是当前项目依赖的版本,而非全局版本,减少版本冲突。

添加scripts脚本

{
  "scripts": {
    "less-version": "lessc -v"
  }
}
# 执行命令
npm run less-version

特点

  • 简化调用:将长命令或高频操作封装为简短脚本(如 npm run build),便于记忆和复用。
  • 自动路径解析npm run 会自动从 node_modules/.bin 中查找可执行文件,无需手动拼接路径。
  • 支持命令组合:可串联多个命令形成工作流(如 build: "lessc src/style.less dist/style.css && uglifyjs src/index.js -o dist/index.min.js")。

NPM发布第三方包

  1. 创建基础项目

  2. 注册 npm 账号

    浏览器打开 https://www.npmjs.com/signup 填好邮箱/用户名/密码。

  3. 切到官方镜像

    # 方式一(推荐,需提前安装 nrm)  
    nrm use npm  
    
    # 方式二(无 nrm 时直接配置)  
    npm config set registry https://registry.npmjs.org  
    
  4. 登录

    npm login    			 # 依次输入用户名、密码、邮箱、一次性验证码
    

    登录成功后 npm whoami 能看到用户名。

  5. 发布

    npm publish               # 根目录执行
    
  6. 测试

    npm i yeizi
    
    import yeizi from 'yeizi'
    yeizi()   // 就算失败,我也想知道,自己倒在距离终点多远的地方。
    

避坑指南

  • *镜像源必须切换:发布包前务必将 npm 镜像切回官方源,否则会发布到非官方仓库(如淘宝源)导致失败。

  • 版本号手动维护:更新包功能后,需手动修改 package.json 中的 version 字段,否则无法重复发布同版本包。

  • 包名冲突检查:发布前可在 npm 官网搜索包名,确保包名未被占用,避免发布报错。

疑难问题

npm create vite实际做了什么?

  1. 尝试执行 npx @npmcli/create-vite(官方脚手架前缀)。
  2. 由于 @npmcli/create-vite 不存在,回退到 npx create-vite
# 创建项目并选择模板(交互式)
npm create vite my-app

# 直接指定模板(非交互式)
npm create vite my-app -- --template react

注意:-- 的核心作用是 “划清界限”:让前半部分的命令只处理自己的选项,后半部分的参数原封不动地传递给被调用的程序 / 脚本,避免歧义或错误解析。在需要向嵌套命令传递参数时,几乎都需要用到 --