提问者:小点点

如何在Deno中使用npm模块?


德诺超级酷。 早上看到了,现在想迁移到德诺。 我试图将现有的nodejs脚本移动到Deno。 任何一个可以帮助我在如何使用npm模块在Deno。 我需要esprima模块。 这个程序包有https://github.com/denoland/deno_third_party/Tree/master/node_modules,但我不知道如何使用它。


共2个答案

匿名用户

Deno提供了一个节点兼容性库,允许使用一些不使用非多填充Node.jsAPI的NPM包。 您可以使用https://deno.land/std/node/module.ts要求

以下是Deno 1.0.0上的代码

import { createRequire } from "https://deno.land/std/node/module.ts";

const require = createRequire(import.meta.url);
const esprima = require("esprima");

const program = 'const answer = 42';
console.log(esprima.tokenize(program))

上述代码将使用node_modules/中的esprima

要运行它,您需要--允许读标志

deno run --allow-read esprima.js

您可以将其限制为node_modules

deno run --allow-read=node_modules esprima.js

输出:

[
 { type: "Keyword", value: "const" },
 { type: "Identifier", value: "answer" },
 { type: "Punctuator", value: "=" },
 { type: "Numeric", value: "42" }
]

注意:std/使用的许多API仍然不稳定,因此您可能需要使用--stastable标志来运行它。

虽然由于整个项目已经是用TypeScript编写的,而且它没有使用任何依赖项,所以他们将其改编为Deno将非常容易。 他们只需在导入上使用.ts扩展即可。 您还可以派生项目并进行更改。

// import { CommentHandler } from './comment-handler';
import { CommentHandler } from './comment-handler.ts';
// ...

一旦他们做到了,你就可以做到:

// Ideally they would issue a tagged release and you'll use that instead of master
import esprima from 'https://raw.githubusercontent.com/jquery/esprima/master/src/esprima.ts';

const program = 'const answer = 42';
console.log(esprima.tokenize(program))

匿名用户

通常,Deno中的npm包存在两个问题:

  • 未给出ES模块(ESM)一致性。
    • import_from“lodash”这样的裸导入不起作用-没有“魔术”node_modules解析
    • 所有导入说明符都需要包含文件扩展名-.ts.js
    • CommonJS模块系统在DENO
    • 中不可用

    第三方模块部分是发现兼容包的最快方法。

    还可以看看CDN提供商,它们可以将npm包自动转换为ES模块(ESM):

    • 鼠兔CDN
    • jspm.io
    • unpkg.com,带有?module查询参数

    Pika CDN可以提供自动转换的包,例如在package.json中设置了“模块”入口点。 对于TypeScript用户:它获取.d.ts类型定义以及.js文件(通过Deno使用的x-typescript-typesHTTP头)。

    unpkg.com对其?module标志的描述如下:“将JavaScript模块中的所有‘裸’导入说明符扩展到unpkg URL.这个特性非常具有实验性”。

    import esprima from "https://cdn.pika.dev/esprima@^4.0.1"; // Option 1: Pika
    import esprima from "https://dev.jspm.io/esprima"; // Option 2: jspm 
    // your program
    const tokens = esprima.tokenize("const foo = 'bar'"); // works
    

    jspm在这里是一个不错的选择--在这个特定的情况下,Pika TS类型不适合我。

    您还可以尝试直接从存储库源(例如ESM分支)导入ESM兼容版本。 但对于Esprima,由于代码中缺少文件扩展名,它无法工作。

    Snowpack和jspm代表了一种更手动的方法来转换CommonJS ESM。 rollup插件@rollup/plugin-commonjs(由Snowpack内部使用)甚至是一个更低级的工具。

    Deno提供了一个节点兼容层,参见Marcos Casagrande的回答。 但是,并不是所有本机Node.js内置都得到完全支持。

    由于Esprima不依赖于节点内置,您可以使用更简单的CDN选项。