npm包管理工具

/ 开发工具

包管理工具

包管理工具是用于自动化软件包(库、框架等)的安装、更新、配置和删除的程序。它们极大地简化了依赖项管理和项目构建的过程。以下是几种流行的JavaScript/Node.js包管理工具的介绍:

npm (Node Package Manager)

Yarn

cnpm

npm init 是 Node.js 包管理工具 npm 提供的一个命令,用于初始化一个新的 Node.js 项目。它会引导用户通过一系列提示来创建一个 package.json 文件,该文件是项目的配置文件,定义了项目的元数据、依赖关系和其他设置。

使用 npm init

要使用 npm init 初始化一个新的 Node.js 项目,请按照以下步骤操作:

  1. 打开命令行界面:可以是 CMD(Windows)、Terminal(macOS/Linux)或任何你喜欢的终端模拟器。

  2. 导航到你的项目目录

    1
    cd path/to/your/project
  3. 运行 npm init 命令

    1
    npm init
  4. 回答提示的问题:当你执行 npm init 后,npm 将开始询问关于你项目的几个问题,比如名称、版本、描述、入口点(通常是 index.js)、测试命令、Git 仓库、关键字、作者和许可证信息。你可以根据需要填写这些信息,或者按回车键接受默认值。

  5. 完成初始化:回答完所有问题后,npm 将为你生成一个 package.json 文件,包含了你提供的信息。

快速初始化

如果你想要快速初始化一个 package.json 文件,并且不想逐一回答每个问题,你可以使用 -y--yes 标志:

1
npm init -y

这将使用当前目录名作为包名,其他字段采用默认值,并立即创建 package.json 文件而无需交互。

编辑 package.json

一旦 package.json 文件被创建,你可以随时编辑它以添加更多的脚本、修改依赖项或更新项目信息。例如,你可以添加启动命令:

1
2
3
"scripts": {
"start": "node index.js"
}

然后可以通过 npm start 来运行这个命令。

注意事项

使用 npm 搜索包是一个非常直接的过程,可以帮助你找到需要的库或工具。以下是关于如何使用 npm search 命令以及一些最佳实践和技巧来高效地搜索 npm 注册表中的包。

使用 npm search 命令

  1. 基本搜索
    你可以直接在命令行中输入 npm search <query> 来查找与查询相关的包。例如,如果你想查找与“express”有关的包,你可以运行:

    1
    npm search express
  2. 细化搜索结果
    默认情况下,npm search 可能会返回大量的结果。为了获得更精确的结果,可以尝试添加更多描述性的关键词,或者使用通配符(如星号 *)来匹配部分字符串。例如:

    1
    npm search express middleware
  3. 分页浏览
    如果搜索结果较多,npm search 通常会以分页的形式展示结果。你可以按空格键或向下箭头键滚动浏览页面,按 q 键退出分页模式。

  4. 在线搜索
    有时候通过命令行搜索可能不够直观,尤其是在寻找特定功能时。这时你可以访问 npm 官方网站(https://www.npmjs.com/) 的搜索界面进行更加详细的搜索。网页版提供了更好的过滤选项和排序功能。

注意事项

使用 npm 安装包

1. 本地安装(默认)

这是最常用的安装方式,它会将包安装到当前项目的 node_modules 文件夹中,并且通常会自动更新 package.json 中的依赖列表。

1
npm install <package-name>

或者简写为:

1
npm i <package-name>

示例:安装 Express 框架

1
npm install express

2. 全局安装

如果你希望安装一个可以在任何地方使用的命令行工具(如 Yeoman 或 Gulp),你可以选择全局安装。这会将包安装到一个全局位置,通常是 /usr/local/lib/node_modules

1
npm install -g <package-name>

示例:全局安装 Babel CLI

1
npm install -g @babel/cli

3. 安装特定版本

你可以通过指定版本号来安装某个特定版本的包。这对于确保兼容性或回滚到旧版本非常有用。

1
npm install <package-name>@<version>

示例:安装版本 4.0.0 的 Lodash

1
npm install lodash@4.0.0

4. 安装最新版本

如果你想确保安装的是最新的稳定版,可以使用 latest 标签。

1
npm install <package-name>@latest

5. 安装开发依赖

对于那些只在开发环境中使用的工具(例如测试框架、构建工具等),你应该将它们标记为开发依赖。这样可以区分生产环境和开发环境的依赖项。

1
npm install --save-dev <package-name>

或者使用 -D 简写形式:

1
npm install -D <package-name>

示例:安装 Mocha 测试框架作为开发依赖

1
npm install --save-dev mocha

6. 安装可选依赖

有些包可能包含可选依赖,这些依赖不是必须的,但提供了额外的功能。你可以通过以下命令来安装这些可选依赖:

1
npm install --optional <package-name>

7. 安装私有包

如果需要安装私有包,你需要先登录 npm 注册表:

1
npm login

然后按照正常的安装流程进行安装。

8. 从 GitHub 或其他源安装

你也可以直接从 Git 仓库安装包,比如 GitHub 上的项目。只需要提供完整的 Git URL 即可。

1
npm install git+https://github.com/user/repo.git

或者使用 SSH 形式的 URL:

1
npm install git+ssh://git@github.com:user/repo.git

9. 安装时忽略某些依赖

有时候你可能想要跳过一些特定类型的依赖(如可选依赖或同行依赖)。可以使用 --no-optional--ignore-scripts 参数来实现这一点。

1
npm install --no-optional

10. 安装后清理缓存

如果你遇到问题,或者想节省磁盘空间,可以定期清理 npm 缓存:

1
npm cache clean --force

注意事项

使用 require 导入 npm 模块

在 Node.js 中,require 不仅可以用来导入安装的 npm 模块,还可以用来加载本地文件和模块。对于本地文件或模块,你需要提供相对于当前模块文件的路径。以下是添加路径的方法以及如何使用这些路径来 require 本地文件或模块。

使用相对路径

当你要导入同一个项目中的其他 JavaScript 文件时,你可以使用相对路径。相对路径是以点 (.) 开头,表示从当前文件所在目录开始计算:

示例:导入同一目录下的模块

假设你有一个名为 utils.js 的文件位于项目的根目录下,并且你想在另一个同级文件中导入它:

1
2
3
4
5
6
7
8
9
10
// utils.js
module.exports = {
greet: function() {
return "Hello, world!";
}
};

// app.js
const utils = require('./utils');
console.log(utils.greet()); // 输出: Hello, world!

示例:导入子目录中的模块

如果你要导入一个位于子目录中的模块,比如 lib/helpers.js

1
2
3
4
5
6
7
8
9
10
// lib/helpers.js
module.exports = {
add: function(a, b) {
return a + b;
}
};

// app.js
const helpers = require('./lib/helpers');
console.log(helpers.add(2, 3)); // 输出: 5

使用绝对路径(不推荐)

虽然可以通过绝对路径来引用模块,但这通常不是最佳实践,因为它会使代码难以移植到不同的环境中。然而,在某些特殊情况下,你可能仍然需要这样做。例如:

1
const moduleFromFileSystem = require('/absolute/path/to/module');

注意:绝对路径依赖于操作系统的文件结构,因此它可能会降低代码的可移植性。此外,如果路径中有空格或其他特殊字符,可能需要进行适当的转义。

使用 Node.js 模块解析算法

Node.js 会根据一定的规则来查找模块的位置。当你使用 require 时,它首先会在内置模块中查找,然后检查是否是核心模块。如果不是,它将继续按以下顺序搜索:

  1. 本地模块:按照提供的相对或绝对路径查找文件。
  2. node_modules 文件夹:如果路径指向的是 node_modules 文件夹内的包,则 Node.js 将尝试找到该包并加载其主模块。
  3. 父目录的 node_modules:如果在当前目录找不到,则继续向上一层目录查找,直到根目录为止。

创建自定义模块并导出

如果你想创建自己的模块并在项目中复用,你可以通过 module.exportsexports 来暴露函数、对象等。例如:

1
2
3
4
5
6
7
8
9
// myModule.js
function sayHello(name) {
return `Hello, ${name}!`;
}

module.exports = sayHello;

// 或者
// exports.sayHello = sayHello;

然后在其他地方导入并使用:

1
2
const sayHello = require('./myModule');
console.log(sayHello('Alice')); // 输出: Hello, Alice!

环境依赖和生产依赖

在 Node.js 项目中,依赖项可以分为两类:开发依赖(Development Dependencies)生产依赖(Production Dependencies)

开发依赖(Development Dependencies)

开发依赖是指那些仅在开发环境中使用的工具或库。这些包通常用于构建、测试、文档生成等任务,在生产环境中并不需要它们。将这些依赖标记为开发依赖可以帮助减小生产环境中的安装体积,并确保只有必要的代码被部署到生产服务器上。

示例

安装开发依赖

你可以使用 --save-dev-D 标志来安装开发依赖:

1
2
3
4
5
6
npm install --save-dev <package-name>
# 或者简写为
npm install -D <package-name>

# 使用 Yarn
yarn add <package-name> --dev

这会将依赖添加到 package.json 文件的 devDependencies 字段中。

生产依赖(Production Dependencies)

生产依赖是指应用程序在运行时真正需要的所有模块。这些依赖是必不可少的,因为它们直接参与了应用的功能实现。确保所有生产依赖都已正确安装对于保证应用程序能够正常工作至关重要。

示例

安装生产依赖

默认情况下,当你使用 npm installyarn add 时不加任何标志,所安装的包会被视为生产依赖:

1
2
3
4
npm install <package-name>

# 使用 Yarn
yarn add <package-name>

这会将依赖添加到 package.json 文件的 dependencies 字段中。

区分两种依赖的重要性

  1. 减少部署大小:通过明确区分开发和生产依赖,可以在部署时只安装必要的生产依赖,从而减小部署包的大小,节省磁盘空间和带宽。
  2. 提高安全性:某些开发工具可能包含潜在的安全风险,如果它们不在生产环境中存在,则可以降低攻击面。
  3. 优化性能:不必要的开发工具可能会增加启动时间和内存占用,特别是在容器化环境中。
  4. 简化 CI/CD 流程:持续集成/持续部署(CI/CD)流程可以针对不同的环境分别处理开发和生产依赖,确保每次构建都是干净且一致的。

管理依赖的最佳实践

类型 命令 补充
生产依赖 npm i-S uniq
npm i-save uniq
-S等效于-save,-S是默认选项
包信息保存在package.json中dependencies属性
开发依赖 npm i-D less
npm i-save-dev less
-D等效于-save-dev
包信息保存在package.json中devDependencies属性

全局安装npm

全局安装 npm 包允许你在任何地方访问该包提供的命令行工具或功能,而不需要在每个项目中单独安装。这对于诸如构建工具、CLI 工具(如 npm 自身、yarncreate-react-app)等非常有用。以下是关于如何进行全局安装以及一些相关注意事项的详细介绍。

全局安装命令

要全局安装一个 npm 包,你需要使用 -g 选项:

1
npm install -g <package-name>

例如,如果你想全局安装 Babel CLI:

1
npm install -g @babel/cli

检查全局安装路径

有时你可能想知道全局包被安装到了哪里。你可以通过以下命令查看全局模块的安装路径:

1
npm root -g

或者,如果你想查看所有已全局安装的包及其版本:

1
npm list -g --depth=0

全局安装时的权限问题

在某些操作系统上(特别是 macOS 和 Linux),全局安装可能会遇到权限问题,因为默认情况下全局安装位置通常需要管理员权限。为了解决这个问题,有几种方法:

  1. 使用 sudo:这是最简单的方法,但不推荐长期使用,因为它会给 npm 提供超级用户权限,存在安全风险。

    1
    sudo npm install -g <package-name>
  2. 更改 npm 的默认目录:你可以配置 npm 使用一个不需要特殊权限的目录来存储全局包。这可以通过创建一个新的文件夹并将其设置为全局前缀来实现。

    1
    2
    mkdir ~/.npm-global
    npm config set prefix '~/.npm-global'

    然后将这个新路径添加到你的环境变量中(例如,在 .bashrc.zshrc 文件中):

    1
    export PATH=~/.npm-global/bin:$PATH
  3. 使用 nvm (Node Version Manager):nvm 可以帮助管理多个 Node.js 版本,并且它会自动处理全局包的安装路径,避免了权限问题。

  4. 使用 npx:对于只需要偶尔运行一次的命令行工具,可以考虑使用 npx 来临时执行它们,而无需全局安装。npx 会自动从 npm 注册表下载并运行指定的命令。

    1
    npx <package-name>

更新全局包

要更新所有全局安装的包到最新版本,可以使用以下命令:

1
npm update -g

如果你想更新特定的全局包:

1
npm install -g <package-name>@latest

卸载全局包

如果不再需要某个全局包,可以使用以下命令卸载它:

1
npm uninstall -g <package-name>

注意事项

修改windows执行策略

在Windows操作系统中,执行策略(Execution Policy)是PowerShell的一项安全特性,它控制着可以运行的脚本类型。修改执行策略通常需要管理员权限。

要更改PowerShell的执行策略,请按照以下步骤操作:

  1. 以管理员身份打开PowerShell:

    • Win + X 键,然后选择“Windows PowerShell (管理员)”或者“终端(管理员)”,这取决于你的Windows版本。
    • 或者你可以在开始菜单中搜索“PowerShell”,然后右键点击它并选择“以管理员身份运行”。
  2. 查看当前的执行策略:
    输入命令 Get-ExecutionPolicy 并按下回车键。这将显示当前设置的执行策略。

  3. 修改执行策略:
    输入命令 Set-ExecutionPolicy 然后加上你想要设置的策略名称。例如,如果你想要设置为RemoteSigned策略(允许本地脚本无限制运行,但远程脚本必须有数字签名),你可以输入:

    1
    Set-ExecutionPolicy RemoteSigned
  4. 确认更改:
    系统可能会提示你确认是否真的要进行更改。根据提示输入 YA 来确认。

以下是几个常见的执行策略选项:

请注意,在企业环境中修改执行策略可能受到组策略(Group Policy)的限制,所以如果是在工作或学校计算机上尝试更改此设置,可能需要联系系统管理员来帮助更改这些设置。此外,放宽执行策略可能会带来安全风险,因此请谨慎选择适当的策略级别。

PATH 环境变量

1. 基本概念

2. 查找机制

3. 用户与系统级别的区别

4. 安全性考量

5. 修改的影响范围

6. 修改方法

通过图形界面
  1. Windows 系统属性对话框
    • 右键点击“此电脑”或“我的电脑”,选择“属性”。
    • 点击左侧的“高级系统设置”链接。
    • 在“系统属性”对话框中,点击“高级”选项卡下的“环境变量”按钮。
    • 在“环境变量”对话框中找到“系统变量”部分中的 Path 或者在“用户变量”中找到对应的 Path
    • 选择 Path 并点击“编辑”。然后点击“新建”并输入新的路径。
    • 确认所有对话框以保存更改。
使用命令行工具
  1. CMD (仅限当前命令行会话)

    • 打开命令提示符窗口。

    • 使用 set 命令可以在当前命令提示符窗口中临时添加路径到 PATH

      1
      set PATH=%PATH%;C:\New\Path
  2. PowerShell (仅限当前会话)

    • 打开 PowerShell 窗口。

    • 使用 $env:PATH 变量可以为当前 PowerShell 会话添加路径。

      1
      $env:PATH += ";C:\New\Path"
  3. CMD (永久修改)

    • 打开命令提示符(以管理员身份运行)。

    • 使用 setx 命令来更新 PATH

      1
      setx PATH "%PATH%;C:\New\Path"

      注意:使用 setx 修改环境变量会影响所有新启动的进程,但不会影响正在运行的进程。

  4. PowerShell (永久修改)

    • 打开 PowerShell(以管理员身份运行)。

    • 使用 Set-ItemProperty 来修改用户级别的 PATH,或者使用 [System.Environment]::SetEnvironmentVariable 来修改系统级别的 PATH

      1
      [System.Environment]::SetEnvironmentVariable("PATH", "$([System.Environment]::GetEnvironmentVariable('PATH', 'Machine'));C:\New\Path", "Machine")

      这个命令会将新的路径追加到现有的机器(系统级别)PATH 中。对于用户级别的 PATH,将 "Machine" 替换为 "User"

7. 实际应用案例

8. 注意事项

npm安装包及其依赖

当使用 npm(Node Package Manager)安装一个包时,npm 会根据该包的 package.json 文件中的依赖声明来解析并安装所有直接和间接依赖。以下是关于 npm 安装包及其依赖的一些关键点:

1. dependenciesdevDependencies

2. 依赖树

当你安装一个包时,npm 会递归地检查该包的所有依赖,并为每个依赖重复这个过程,直到构建出完整的依赖树。这棵树可以非常复杂,因为它不仅包含直接依赖,还包括那些依赖的依赖(即间接依赖或子依赖)。

3. package-lock.json

4. node_modules 文件夹

5. 安装所有依赖

要安装项目的所有依赖(包括直接和间接依赖),只需在项目根目录下执行以下命令:

1
npm install

这将读取 package.json 文件,并按照其中列出的依赖项进行安装。

6. 安装特定版本的依赖

你可以指定安装特定版本的依赖,或者使用符号如 ^~ 来允许小版本更新:

1
npm install <package-name>@<version>

7. 审查依赖的安全性

定期审查你的依赖是否存在已知漏洞是一个好习惯。你可以使用如下命令来检查当前项目的依赖是否有安全问题:

1
npm audit

8. 更新依赖

随着时间和新版本的发布,你可能想要更新你的依赖到最新版本。可以使用如下命令来更新所有依赖到最新版本(注意这可能会引入不兼容的变化):

1
npm update

对于个别依赖,你可以指定包名来进行更新。

9. 清理无用的依赖

有时候,你可能会移除一些不再使用的依赖,但它们仍然存在于 package.json 中。你可以使用如下命令来清理这些冗余的依赖:

1
npm prune

10. 安装全局依赖

某些工具可能需要全局安装,例如命令行工具:

1
npm install -g <package-name>

npm start

npm start 是 npm(Node Package Manager)提供的一个非常常用且方便的命令,它用于启动应用程序。当你在项目的根目录下运行 npm start 时,npm 会查找 package.json 文件中的 scripts 字段,并执行与 "start" 关联的命令。

默认行为

如果 package.json 中没有定义 "start" 脚本,npm start 会默认尝试执行 node server.js。这意味着如果你的项目包含一个名为 server.js 的文件,而且这个文件是你的应用入口点,那么 npm start 将直接运行它。

自定义 start 脚本

大多数现代 JavaScript/Node.js 项目都会自定义 start 脚本来适应特定的应用需求。你可以在 package.json 文件中明确指定启动命令,例如:

1
2
3
4
5
6
7
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"start": "node ./bin/www"
}
}

在这个例子中,当运行 npm start 时,npm 会执行 node ./bin/www 来启动应用程序。这使得开发者可以根据项目的具体结构和需要来配置最适合的启动方式。

常见的 start 脚本示例

使用 npm start 启动应用的好处

总之,npm start 是一种强大而灵活的方式,可以用来启动基于 Node.js 的应用程序。通过合理地配置 package.json 文件中的 scripts 部分,你可以极大地提升开发体验和应用维护的便捷性。

npm run

npm run 是 npm(Node Package Manager)提供的一个命令,用于执行在 package.json 文件的 scripts 字段中定义的自定义脚本。它允许开发者创建和运行各种任务,如启动服务器、构建项目、运行测试等。以下是关于 npm run 的详细说明:

基本用法

要执行一个自定义脚本,你需要知道该脚本的名字,并通过以下命令来调用它:

1
npm run <script-name>

例如,如果你有一个名为 build 的脚本,你可以这样运行它:

1
npm run build

查看可用脚本

如果你想查看当前项目中所有可用的脚本,可以使用以下命令:

1
npm run

这将列出所有的自定义脚本以及它们对应的命令。

预处理和后处理脚本

npm 支持预处理 (pre<name>) 和后处理 (post<name>) 脚本。这些脚本会在指定的脚本之前或之后自动执行。例如,如果你有如下脚本定义:

1
2
3
4
5
6
7
{
"scripts": {
"prestart": "echo 'Starting the server...'",
"start": "node server.js",
"poststart": "echo 'Server has started.'"
}
}

当你运行 npm start 时,npm 会依次执行 prestart, start, 和 poststart 脚本。

传递参数给脚本

你可以通过 -- 来传递额外的参数给底层命令。例如:

1
2
3
4
5
{
"scripts": {
"serve": "http-server ./dist -p"
}
}

然后你可以这样运行它并指定端口号:

1
npm run serve -- 8080

这相当于运行 http-server ./dist -p 8080

环境变量

你可以在脚本中设置环境变量,这对于配置开发环境、生产环境等非常有用。例如:

1
2
3
4
5
6
{
"scripts": {
"start": "NODE_ENV=production node server.js",
"dev": "NODE_ENV=development nodemon server.js"
}
}

对于跨平台兼容性,建议使用 cross-env 包来设置环境变量:

1
npm install --save-dev cross-env

然后在 scripts 中使用它:

1
2
3
4
5
6
{
"scripts": {
"start": "cross-env NODE_ENV=production node server.js",
"dev": "cross-env NODE_ENV=development nodemon server.js"
}
}

并行与串行执行多个脚本

有时你可能需要同时运行多个脚本,或者按顺序依次运行它们。可以使用 & 或者 && 来实现这一点:

为了更好地管理多个脚本的并发执行,还可以考虑使用像 concurrently 这样的工具。