# 使用 npm install

> 将 dayjs、lodash 等 npm 包安装到 Proxyman 的 Application Support 文件夹，并在 Proxyman Scripting 中通过 require() 调用。

## 在 Proxyman Scripting 中使用 npm 包 {#use-npm-packages-in-proxyman-scripting}

Proxyman Scripting 支持通过 `require()` 加载安装在 Proxyman Application Support 文件夹中的兼容 npm 包。这样，脚本就能复用常用的 JavaScript 工具库，而无需手动重写通用逻辑。

此功能沿用 Proxyman 已用于内置库和用户插件的 `require()` 关键字。现有的导入方式，例如 `@libs`、`@addons`、`@users`、JSON 文件、文本文件和本地文件，仍可正常使用。

### 安装 npm 包 {#install-a-package}

打开“终端”，将包安装到 Proxyman 的 Application Support 文件夹中：

* 安装 `dayjs`

```bash
$ cd "$HOME/Library/Application Support/com.proxyman.NSProxy"
$ npm install --prefix . dayjs --ignore-scripts --no-audit --no-fund
```

安装完成后，包应位于以下路径：

```
~/Library/Application Support/com.proxyman.NSProxy/node_modules
```

### 在脚本中使用 npm 包 {#use-a-package-in-a-script}

使用包名调用 `require()`：

```javascript
const dayjs = require("dayjs");

async function onRequest(context, url, request) {
  const formattedDate = dayjs("2026-05-05T13:00:00Z").format("YYYY-MM-DD");
  request.headers["X-Proxyman-Dayjs"] = formattedDate;
  return request;
}
```

### 示例 {#examples}

#### 使用 `dayjs` 格式化日期 {#format-a-date-with-dayjs}

安装：

```bash
cd "$HOME/Library/Application Support/com.proxyman.NSProxy" && npm install --prefix . dayjs --ignore-scripts --no-audit --no-fund
```

脚本：

```javascript
const dayjs = require("dayjs");

async function onRequest(context, url, request) {
  request.headers["X-Request-Date"] = dayjs().format("YYYY-MM-DD");
  return request;
}
```

#### 使用 `lodash` 规范化文本 {#normalize-text-with-lodash}

安装：

```bash
cd "$HOME/Library/Application Support/com.proxyman.NSProxy" && npm install --prefix . lodash --ignore-scripts --no-audit --no-fund
```

脚本：

```javascript
const _ = require("lodash");

async function onRequest(context, url, request) {
  const label = _.kebabCase("Hello Proxyman Scripts");
  request.headers["X-Proxyman-Label"] = label;
  return request;
}
```

#### 使用 `validator` 校验输入 {#validate-input-with-validator}

安装：

```bash
cd "$HOME/Library/Application Support/com.proxyman.NSProxy" && npm install --prefix . validator --ignore-scripts --no-audit --no-fund
```

脚本：

```javascript
const validator = require("validator");

async function onRequest(context, url, request) {
  const email = new URL(url).searchParams.get("email") || "";
  request.headers["X-Email-Is-Valid"] = validator.isEmail(email) ? "true" : "false";
  return request;
}
```

#### 使用 `slugify` 生成 slug {#create-slugs-with-slugify}

安装：

```bash
cd "$HOME/Library/Application Support/com.proxyman.NSProxy" && npm install --prefix . slugify --ignore-scripts --no-audit --no-fund
```

脚本：

```javascript
const slugify = require("slugify");

async function onRequest(context, url, request) {
  const title = new URL(url).searchParams.get("title") || "Hello Proxyman";
  request.headers["X-Proxyman-Slug"] = slugify(title, { lower: true });
  return request;
}
```

#### 使用 `js-base64` 编码数据 {#encode-data-with-js-base64}

安装：

```bash
cd "$HOME/Library/Application Support/com.proxyman.NSProxy" && npm install --prefix . js-base64 --ignore-scripts --no-audit --no-fund
```

脚本：

```javascript
const { Base64 } = require("js-base64");

async function onResponse(context, url, request, response) {
  response.headers["X-Proxyman-Encoded"] = Base64.encode("Proxyman");
  return response;
}
```

#### 使用 `he` 解码 HTML 实体 {#decode-html-entities-with-he}

安装：

```bash
cd "$HOME/Library/Application Support/com.proxyman.NSProxy" && npm install --prefix . he --ignore-scripts --no-audit --no-fund
```

脚本：

```javascript
const he = require("he");

async function onResponse(context, url, request, response) {
  response.headers["X-Decoded-Title"] = he.decode("Proxyman &amp; Scripting");
  return response;
}
```

### 兼容性 {#compatibility}

Proxyman 使用 JavaScriptCore 运行脚本，而不是 Node.js。npm 包在满足以下条件时兼容性最好：采用纯 JavaScript 编写，并兼容 CommonJS。

支持的内容：

* 通过 `require("package-name")` 加载的 CommonJS 包
* `package.json` 中的入口点，例如 `main` 和简单的 `exports`
* 包内部使用的相对导入，例如 `require("./helper")`
* 包所需的 JSON 文件

不支持的内容：

* Node.js 内置模块，例如 `fs`、`path`、`crypto`、`http` 或 `child_process`
* 原生 `.node` 插件
* 需要完整 Node.js 运行时的包
* 无法通过 CommonJS `require()` 加载的纯 ESM 包

### Node.js 原生库 {#nodejs-native-libraries}

Proxyman Scripting 并不在 Node.js 运行时中运行。它只将 Node/npm 用作包安装工具，然后使用 JavaScriptCore 加载兼容的 JavaScript 文件。

因此，以下 Node.js 原生库不受支持：

* `require("fs")`、`require("path")`、`require("crypto")` 以及其他 Node.js 内置模块已被屏蔽。
* `require("node:fs")` 以及 `require("fs/promises")` 等内置子路径已被屏蔽。
* 编译为 `.node` 文件的原生 C/C++ 插件已被屏蔽。
* 调用 `process.dlopen`、文件系统 API、网络 socket 或子进程等 Node 专用 API 的包将无法正常工作。

以下这类包通常无法在 Proxyman Scripting 中使用：

* `sharp`
* `sqlite3`
* `bcrypt`
* `canvas`
* `puppeteer`
* 依赖 `fs`、`path`、`crypto`、`http`、`https`、`net` 或 `child_process` 的包

请改用纯 JavaScript 包，或提供 CommonJS 浏览器兼容构建的包。

### 故障排查 {#troubleshooting}

如果 `require("dayjs")` 或其他包返回 `undefined`，请检查该包是否已安装到预期的文件夹中：

```bash
ls "$HOME/Library/Application Support/com.proxyman.NSProxy/node_modules"
```

如果 `node_modules` 不存在，请使用 `--prefix .` 重新安装：

```bash
cd "$HOME/Library/Application Support/com.proxyman.NSProxy" && npm install --prefix . dayjs --ignore-scripts --no-audit --no-fund
```

`--prefix .` 选项非常重要。否则，npm 可能会向上查找父级的 `package.json`，并将包安装到 Proxyman 文件夹之外。
