如何解决ASP.NET 5核心网站在 Visual Studio [not Code] 2019 中带有 TypeScript 和 Node或 ESM模块?
所以我按照 this guide 在 ASP.NET 5 网站项目(使用 Razor Page)中设置了 TypeScript。我想使用 Node 模块进行 TypeScript 类型化,而不是仅仅作为 any
导入。
现在我想添加一个 Node 模块,比如 EthersJS,所以我有:
"dependencies": {
"ethers": "^5.4.1"
}
此代码无法编译:
import { ethers } from "ethers";
export class EthService {
pro: ethers.providers.BaseProvider;
constructor() {
const pro = this.pro = new ethers.providers.WebSocketProvider("");
}
async getBlockNumberAsync() {
return await this.pro.getBlockNumber();
}
}
除非我将 "moduleResolution": "Node"
添加到 tsconfig.json
。显然,这实际上不会在浏览器中运行。
我应该如何设置它以便以某种方式编译 Node 模块?我认为如果我能做到以下任何一项,问题就可以解决:
-
使 TypeScript/Gulp/MSBuild 将
import { ethers } from "ethers";
更改为正确的路径(我可以将编译的 lib 文件手动复制到 wwwroot)。 -
手动将导入路径设置为
import { ethers } from "path/to/compiled/ethers.js";
,但我需要以某种方式告诉 TypeScriptethers
类型来自ethers
节点模块。
更新:我认为第三种可能性也很好,如果我可以像这样声明导入(我只会将 ESM 文件添加到全局范围内):
declare import { ethers } from "ethers";
以上选项是否可行?或者有什么办法吗?谢谢。
注意:我知道有 Triple-Slash Directives 并且它可能会解决我的问题,但我还不太了解它们的作用。
当前的gulpfile.js
:
/// <binding AfterBuild='default' Clean='clean' />
/*
This file is the main entry point for defining Gulp tasks and using Gulp plugins.
Click here to learn more. http://go.microsoft.com/fwlink/?LinkId=518007
*/
var gulp = require("gulp");
var del = require("del");
var paths = {
scripts: ["Scripts/**/*.js","Scripts/**/*.ts","Scripts/**/*.map"],};
gulp.task("clean",function () {
return del(["wwwroot/Scripts/**/*"]);
});
gulp.task("default",function () {
gulp.src(paths.scripts).pipe(gulp.dest("wwwroot/Scripts"));
});
tsconfig.json:
{
"compilerOptions": {
"noImplicitAny": true,"noEmitOnError": true,"removeComments": false,"sourceMap": true,"target": "ESNext","module": "ESNext","moduleResolution": "Node"
},"exclude": [
"wwwroot","node_modules"
],"compileOnSave": true
}
解决方法
我可以通过使用独立的 ethers.js
脚本文件将 ethers
命名空间暴露给全局范围来解决这个问题:
<script defer src="/libs/ethers.umd.min.js" asp-append-version="true"></script>
现在您需要告诉 TypeScript 在全局范围内有一个 ethers
“东西”(命名空间/模块)。感谢 this article,我找到了解决方案。创建一个 .d.ts
文件(任何文件都可以,我将其命名为 globals.d.ts
):
import { ethers as eth } from "ethers";
declare global {
// @ts-ignore: export typing
export { eth as ethers };
}
现在您可以在任何地方使用 ethers
而无需任何声明。例如我的整个 EthService.ts
文件:
export class EthService {
pro: ethers.providers.WebSocketProvider;
init(server: string) {
this.pro = new ethers.providers.WebSocketProvider(server);
}
async getBlockNoAsync() {
return await this.pro.getBlockNumber();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。