ASP.NET Visual Studio [不是代码] 2019 中的 5 个(核心)网站,带有 TypeScript 和 Node(或 ESM)模块?
ASP.NET 5 (Core) Website with TypeScript and Node (or ESM) modules in Visual Studio [not Code] 2019?
所以我按照 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";
,但我需要以某种方式告诉 TypeScript ethers
键入来自 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
“东西”(namespace/module)。感谢 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();
}
}
所以我按照 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
“东西”(namespace/module)。感谢 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();
}
}