本页内容

完整性检查和锁定文件

简介 跳转到标题

假设你的模块依赖于远程模块 https://some.url/a.ts。当你第一次编译你的模块时,a.ts 会被检索、编译并缓存。它将保持这种状态,直到你在新机器(例如生产环境)上运行你的模块或重新加载缓存(例如通过 deno cache --reload)。但是,如果远程 URL https://some.url/a.ts 中的内容发生更改会怎样?这会导致你的生产模块运行的依赖代码与你的本地模块不同。Deno 的解决方案是使用完整性检查和锁定文件来避免这种情况。

缓存和锁定文件 跳转到标题

Deno 可以使用一个小的 JSON 文件来存储和检查模块的子资源完整性。要选择使用锁定文件,可以:

  1. 在当前目录或祖先目录中创建一个 deno.json 文件,这将自动在 deno.lock 中创建一个累加的锁定文件。
  2. 使用 --lock=deno.lock 来启用并指定锁定文件检查。要更新或创建锁定文件,请使用 --lock=deno.lock --lock-write--lock=deno.lock 告诉 Deno 要使用哪个锁定文件,而 --lock-write 用于将依赖项哈希输出到锁定文件(--lock-write 必须与 --lock 结合使用)。

deno.lock 可能看起来像这样,它存储了文件相对于依赖项的哈希值

{
  "https://deno.land/[email protected]/textproto/mod.ts": "3118d7a42c03c242c5a49c2ad91c8396110e14acca1324e7aaefd31a999b71a4",
  "https://deno.land/[email protected]/io/util.ts": "ae133d310a0fdcf298cea7bc09a599c49acb616d34e148e263bcb02976f80dee",
  "https://deno.land/[email protected]/async/delay.ts": "35957d585a6e3dd87706858fb1d6b551cb278271b03f52c5a2cb70e65e00c26a",
   ...
}

自动生成的锁定文件 跳转到标题

如上所述,当解析到 Deno 配置文件(例如 deno.json)时,将自动生成一个累加的锁定文件。默认情况下,此锁定文件的路径将为 deno.lock。你可以通过更新 deno.json 来指定此路径

{
  "lock": "./lock.file"
}

或者通过指定以下内容来禁用自动创建和验证锁定文件

{
  "lock": false
}

使用 --lock--lock-write 标志 跳转到标题

典型的流程如下所示

src/deps.ts

// Add a new dependency to "src/deps.ts", used somewhere else.
export { xyz } from "https://unpkg.com/[email protected]/lib.ts";

然后

# Create/update the lock file "deno.lock".
deno cache --lock=deno.lock --lock-write src/deps.ts

# Include it when committing to source control.
git add -u deno.lock
git commit -m "feat: Add support for xyz using xyz-lib"
git push

另一个机器上的协作者 - 在一个新克隆的项目树中

# Download the project's dependencies into the machine's cache, integrity
# checking each resource.
deno cache --reload --lock=deno.lock src/deps.ts

# Done! You can proceed safely.
deno test --allow-read src

运行时验证 跳转到标题

与上面的缓存类似,你也可以在使用 deno run 子命令时使用锁定文件,在运行时验证任何已锁定模块的完整性。请记住,这只会针对之前添加到锁定文件中的依赖项进行验证。

你还可以通过使用 --cached-only 标志来进一步要求远程依赖项已缓存。

deno run --lock=deno.lock --cached-only mod.ts

如果 mod.ts 的依赖项树中存在任何尚未缓存的依赖项,这将失败。