注意事项:
Deno有一个
dependency inspector
工具:
deno info [URL]
将检查ES模块及其所有依赖项。
此工具将模块的所有依赖项打印到
stdout
,输出包括模块的远程原点及其在本地存储设备上的缓存路径。
它还有一个(当前不稳定)参数
--json
它将以JSON格式打印依赖项(如果这是您的目标,则更容易通过编程进行解析)。
你可以
create a subprocess
在使用上述命令和参数的程序中,然后解析其输出,以便以编程方式确定模块的缓存位置。(还要注意,子流程API
is changing
以及当前不稳定的API
Deno.spawn
和
Deno.spawnChild
将替换
the current one
)
以下是一个依赖项比您问题中的模块少的模块的输出示例:
% deno info https://deno.land/std@0.154.0/testing/asserts.ts
local: /Users/deno/.deno/deps/https/deno.land/ce1734220fb8c205d2de1b52a59b20401c59d0707abcc9765dbeb60c25483df9
type: TypeScript
dependencies: 3 unique (total 46.65KB)
https://deno.land/std@0.154.0/testing/asserts.ts (23.22KB)
âââ https://deno.land/std@0.154.0/fmt/colors.ts (11.62KB)
ââ⬠https://deno.land/std@0.154.0/testing/_diff.ts (11.11KB)
â âââ https://deno.land/std@0.154.0/fmt/colors.ts *
âââ https://deno.land/std@0.154.0/testing/_format.ts (705B)
使用时的输出
--json
自变量:
% deno info --json https://deno.land/std@0.154.0/testing/asserts.ts
{
"roots": [
"https://deno.land/std@0.154.0/testing/asserts.ts"
],
"modules": [
{
"kind": "esm",
"local": "/Users/deno/.deno/deps/https/deno.land/02d8068ecd90393c6bf5c8f69b02882b789681b5c638c210545b2d71e604b585",
"emit": null,
"map": null,
"size": 11904,
"mediaType": "TypeScript",
"specifier": "https://deno.land/std@0.154.0/fmt/colors.ts"
},
{
"dependencies": [
{
"specifier": "../fmt/colors.ts",
"code": {
"specifier": "https://deno.land/std@0.154.0/fmt/colors.ts",
"span": {
"start": {
"line": 11,
"character": 7
},
"end": {
"line": 11,
"character": 25
}
}
}
}
],
"kind": "esm",
"local": "/Users/deno/.deno/deps/https/deno.land/62cb97c1d18d022406d28b201c22805c58600e9a6d837b0fc4b71621ed21e30d",
"emit": null,
"map": null,
"size": 11380,
"mediaType": "TypeScript",
"specifier": "https://deno.land/std@0.154.0/testing/_diff.ts"
},
{
"kind": "esm",
"local": "/Users/deno/.deno/deps/https/deno.land/3f50b09108fe404c8274e994b417a0802863842e740c1d7ca43c119c0ee0f14b",
"emit": null,
"map": null,
"size": 705,
"mediaType": "TypeScript",
"specifier": "https://deno.land/std@0.154.0/testing/_format.ts"
},
{
"dependencies": [
{
"specifier": "../fmt/colors.ts",
"code": {
"specifier": "https://deno.land/std@0.154.0/fmt/colors.ts",
"span": {
"start": {
"line": 10,
"character": 32
},
"end": {
"line": 10,
"character": 50
}
}
}
},
{
"specifier": "./_diff.ts",
"code": {
"specifier": "https://deno.land/std@0.154.0/testing/_diff.ts",
"span": {
"start": {
"line": 11,
"character": 44
},
"end": {
"line": 11,
"character": 56
}
}
}
},
{
"specifier": "./_format.ts",
"code": {
"specifier": "https://deno.land/std@0.154.0/testing/_format.ts",
"span": {
"start": {
"line": 12,
"character": 23
},
"end": {
"line": 12,
"character": 37
}
}
}
}
],
"kind": "esm",
"local": "/Users/deno/.deno/deps/https/deno.land/ce1734220fb8c205d2de1b52a59b20401c59d0707abcc9765dbeb60c25483df9",
"emit": null,
"map": null,
"size": 23776,
"mediaType": "TypeScript",
"specifier": "https://deno.land/std@0.154.0/testing/asserts.ts"
}
],
"redirects": {}
}
但是,如果您的最终目标是将模块(来自远程源)缓存到本地存储设备并从该位置导入,而不是使用Deno的内置缓存,我建议使用内置工具:
deno vendor
从…起
its manual page
:
deno vendor <specifiers>...
将指定模块的所有远程依赖项下载到本地
vendor
文件夹
更新:下面是一个示例脚本,演示了我上面描述的方法:
so-73596066.ts
:
/// <reference lib="deno.unstable" />
import { assertExists } from "https://deno.land/std@0.154.0/testing/asserts.ts";
/*
`deno info --json` is unstable, and I didn't find any mention of schema for its
output in the docs, but here's a (conservative) partial type for the bits
that are relevant to this example, derived from looking at just a couple
of outputs from Deno v1.25.1:
*/
type ModuleInfo =
& Record<"kind" | "local" | "mediaType" | "specifier", string>
& Record<"emit" | "map", string | null>
& {
dependencies?: unknown[];
size: number;
};
type DependencyInspectorResult = {
modules: ModuleInfo[];
roots: string[];
};
/**
* Creates a formatted error message and allows for improved error handling by
* discriminating error instances
*/
class ProcessError extends Error {
override name = "ProcessError";
constructor(status: Deno.ChildStatus, stdErr?: string) {
let msg = `The process exited with status code ${status.code}`;
if (stdErr) msg += `. stderr:\n${stdErr}`;
super(msg);
}
}
/**
* Parses output from `deno info --json`. The resulting command will look like:
* `deno info --json [...denoInfoArgs] specifier`
* @param specifier local/remote path/URL
* @param denoInfoArgs optional, additional arguments to be used with `deno info --json`
*/
async function getCachedModuleInfo(
specifier: string | URL,
denoInfoArgs?: string[],
): Promise<ModuleInfo> {
const decoder = new TextDecoder();
const specifierStr = String(specifier);
const args = ["info", "--json"];
if (denoInfoArgs?.length) args.push(...denoInfoArgs);
args.push(specifierStr);
const { stderr, stdout, ...status } = await Deno.spawn("deno", { args });
if (!status.success) {
const stdErr = decoder.decode(stderr).trim();
throw new ProcessError(status, stdErr);
}
const result = JSON.parse(
decoder.decode(stdout),
) as DependencyInspectorResult;
const moduleInfo = result.modules.find((info) =>
info.specifier === specifierStr
);
assertExists(moduleInfo, "Module not found in output");
return moduleInfo;
}
/**
* `console.log` truncates long strings and deep object properties by default.
* This overrides that behavior.
*/
function print(value: unknown): void {
const inspectOpts: Deno.InspectOptions = {
colors: true,
depth: Infinity,
strAbbreviateSize: Infinity,
};
const formattedOutput = Deno.inspect(value, inspectOpts);
console.log(formattedOutput);
}
async function main() {
const moduleInfo = await getCachedModuleInfo(
"https://deno.land/std@0.154.0/testing/asserts.ts",
);
const { local, specifier } = moduleInfo;
print({ specifier, local });
}
if (import.meta.main) main();
% deno --version
deno 1.25.1 (release, x86_64-apple-darwin)
v8 10.6.194.5
typescript 4.7.4
% deno run --allow-run=deno --unstable so-73596066.ts
{
specifier: "https://deno.land/std@0.154.0/testing/asserts.ts",
local: "/Users/deno/.deno/deps/https/deno.land/ce1734220fb8c205d2de1b52a59b20401c59d0707abcc9765dbeb60c25483df9"
}