npm: 指定符
从 1.28 版本开始,Deno 原生支持导入 npm 包。这可以通过使用 npm: 指定符来实现。例如,以下代码
import { emojify } from "npm:node-emoji@2";
console.log(emojify(":t-rex: :heart: NPM"));
可以使用以下命令运行
$ deno run main.js
🦖 ❤️ NPM
这样做时,不需要 npm install 并且不会创建 node_modules 文件夹。这些包也受与 Deno 中其他代码相同的 权限 限制。
npm 指定符具有以下格式
npm:<package-name>[@<version-requirement>][/<sub-path>]
有关热门库的示例,请参阅我们的 教程部分。
TypeScript 类型 跳转到标题
许多包自带类型,您可以导入这些类型并轻松地将它们与类型一起使用
import chalk from "npm:chalk@5";
但是,有些包没有自带类型,您可以使用 @deno-types 指令指定它们的类型。例如,使用 @types 包
// @deno-types="npm:@types/express@^4.17"
import express from "npm:express@^4.17";
模块解析 跳转到标题
官方 TypeScript 编译器 tsc 支持不同的 moduleResolution 设置。Deno 仅支持现代的 node16 解析。不幸的是,许多 NPM 包在 node16 模块解析下无法正确提供类型,这会导致 deno check 报告类型错误,而 tsc 不会报告这些错误。
如果来自 npm: 导入的默认导出似乎具有错误的类型(而正确的类型似乎在 .default 属性下可用),则很可能是该包在 node16 模块解析下为来自 ESM 的导入提供了错误的类型。您可以通过检查错误是否也发生在 tsc --module node16 和 package.json 中的 "type": "module" 或通过咨询 类型是否错误? 网站(特别是“node16 from ESM”行)来验证这一点。
如果您想使用不支持 TypeScript 的 node16 模块解析的包,您可以
- 在该包的问题跟踪器中打开一个关于该问题的问题。(也许可以贡献一个修复程序 😃(虽然目前不幸的是缺乏工具来让包同时支持 ESM 和 CJS,因为默认导出需要不同的语法,另请参阅 microsoft/TypeScript#54593))
- 使用 CDN,它会为 Deno 支持重新构建包,而不是使用
npm:标识符。 - 使用
// @ts-expect-error或// @ts-ignore忽略代码库中出现的类型错误。
包含 Node 类型 跳转到标题
Node 附带许多内置类型,例如 Buffer,这些类型可能在 npm 包的类型中被引用。要加载这些类型,您必须向 @types/node 包添加类型引用指令
/// <reference types="npm:@types/node" />
请注意,在大多数情况下,不指定版本是可以的,因为 Deno 会尝试将其与内部 Node 代码保持同步,但您始终可以根据需要覆盖使用的版本。
npm 可执行脚本 跳转到标题
具有 bin 条目的 npm 包可以使用以下格式的指定符从命令行执行,而无需 npm install
npm:<package-name>[@<version-requirement>][/<binary-name>]
例如
$ deno run --allow-read npm:cowsay@1.5.0 Hello there!
______________
< Hello there! >
--------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
$ deno run --allow-read npm:cowsay@1.5.0/cowthink What to eat?
______________
( What to eat? )
--------------
o ^__^
o (oo)\_______
(__)\ )\/\
||----w |
|| ||
--node-modules-dir 标志 跳转到标题
npm 指定符将 npm 包解析到一个中央全局 npm 缓存中。这在大多数情况下都能很好地工作,并且是理想的选择,因为它占用空间更少,并且不需要 node_modules 目录。也就是说,您可能会发现 npm 包希望从 node_modules 目录执行。为了提高兼容性并支持这些包,您可以使用 --node-modules-dir 标志。
例如,给定 main.ts
import chalk from "npm:chalk@5";
console.log(chalk.green("Hello"));
使用 --node-modules-dir 运行此脚本,例如...
deno run --node-modules-dir main.ts
...将在当前目录中创建一个与 npm 具有类似文件夹结构的 node_modules 文件夹。

请注意,在调用 deno run 时,所有这些操作都会自动完成,无需单独的安装命令。
或者,如果您希望完全禁用 node_modules 目录的创建,可以将此标志设置为 false(例如 --node-modules-dir=false)或在您的 deno.json 配置文件中添加 "nodeModulesDir": false 条目,使该设置应用于整个目录树。
如果您希望在执行之前修改 node_modules 目录的内容,可以使用 --node-modules-dir 运行 deno cache,修改内容,然后运行脚本。
例如
deno cache --node-modules-dir main.ts
deno run --allow-read=. --allow-write=. scripts/your_script_to_modify_node_modules_dir.ts
deno run --node-modules-dir main.ts