On this page
运行 npm 生命周期脚本
npm 包可以声明诸如 preinstall 和 postinstall 之类的生命周期脚本,这些脚本会在安装期间运行任意代码,是众所周知的供应链攻击向量。与 npm 不同,Deno 默认不会运行这些脚本,除非你显式批准它们。带有原生 addon 的包(例如 npm:better-sqlite3)需要它们的构建脚本才能正常工作,因此本教程将演示如何批准这些脚本。
安装需要构建脚本的包 Jump to heading
在一个带有 package.json 的项目中,安装一个声明了生命周期脚本的包:
$ deno install npm:better-sqlite3
...
╭ 警告
│
│ 忽略了以下包的构建脚本:
│ npm:better-sqlite3@12.10.0
│
│ 运行 "deno approve-scripts" 以执行构建脚本。
╰─
该包已安装,但其 install 脚本被跳过,因此缺少原生绑定,包在运行时会失败。
批准脚本 Jump to heading
deno approve-scripts 用于查看并运行待批准的脚本。无参数运行时会出现交互式提示,列出所有未批准脚本的包;也可以直接指定包名:
$ deno approve-scripts npm:better-sqlite3
已批准 npm:better-sqlite3
初始化 better-sqlite3@12.10.0:正在运行 'install' 脚本
将批准结果持久化到 deno.json Jump to heading
为了让批准成为项目配置的一部分,从而使每位贡献者和 CI 运行都获得相同的行为,请将这些包列入 allowScripts 字段:
{
"allowScripts": ["npm:better-sqlite3"]
}
现在,直接执行 deno install 就会为列出的包运行构建脚本,无需任何额外标志。另一种一次性做法是直接向 deno install 传递 --allow-scripts=npm:better-sqlite3。
只有当包在本地 node_modules 目录中完成设置时,生命周期脚本才会执行。带有 package.json 的项目会自动获得该目录;仅使用 deno.json 的项目则需要设置 "nodeModulesDir": "auto"。
在工作区中,allowScripts 必须定义在工作区根目录,以确保所有包遵循一致的安全策略。
更多详情请参阅
deno approve-scripts 参考文档 以及
deno install 文档中的
原生 Node.js addons 部分。