0

我使用 npm 和 agulpfile.js基本上将 npm 包导出到“wwwroot”下的“lib”文件夹;这是一种享受,每当我更新特定的 npm 包时,如果它在我的gulpfile.js监视列表中,它就会将内容推送到“lib”文件夹。

我遇到的问题是,我曾经使用手动提取的 ocktokit-rest 副本来查询公共 api 以获取一些 repo 数据。最近这已经停止工作,我假设 GitHub 已经更新了他们的 api,这对我的旧版本 ocktokit-rest 有一些重大更改。因此,考虑到这一点,我使用 npm package.json 安装了 @Ocktokit/rest 版本 18.0.9。然后创建以下目录:

~/lib/@octokit/rest/

根据文档,我需要引用其中的一个index.js文件。所以因为 Razor 不喜欢在路径中使用 @ 符号,所以我在我的_layout.cshtml

<script src="@Url.Content("~/lib/@octokit/rest/dist-src/index.js")" type="module"></script>

我添加了,type="module"因为我最初在index.js文件中的 import 语句中遇到了一些问题。

这是index.js上述路线的文件内容:

import { Octokit as Core } from "@octokit/core";
import { requestLog } from "@octokit/plugin-request-log";
import { paginateRest } from "@octokit/plugin-paginate-rest";
import { restEndpointMethods } from "@octokit/plugin-rest-endpoint-methods";
import { VERSION } from "./version";
export const Octokit = Core.plugin(requestLog, restEndpointMethods, paginateRest).defaults({
    userAgent: `octokit-rest.js/${VERSION}`,
});

这会在 chrome 调试器中引发以下错误:

未捕获的类型错误:无法解析模块说明符“@octokit/core”。相对引用必须以“/”、“./”或“../”开头。

我并不特别喜欢调整@octokit/ 引用以支持 '../../' 的想法,因为每次我的gulpfile.jsnpm push 任务运行时,我都必须手动更改此文件。然而,为了调试,我经历并调整index.js为如下所示:

import { Octokit as Core } from "../../core";
import { requestLog } from "../../plugin-request-log";
import { paginateRest } from "../../plugin-paginate-rest";
import { restEndpointMethods } from "../../plugin-rest-endpoint-methods";
import { VERSION } from "./version";
export const Octokit = Core.plugin(requestLog, restEndpointMethods, paginateRest).defaults({
    userAgent: `octokit-rest.js/${VERSION}`,
});

当我这样做时,每次导入都会收到类似的错误消息,如下所示:

index.js:4 GET https://localhost:44364/lib/@octokit/plugin-rest-endpoint-methods net::ERR_ABORTED 404

现在上面的 URL 指向目录而不是特定文件,如果我将上面的内容运行到单个文件,我可以看到它在浏览器中加载并显示文件。所以如果我输入:

https://localhost:44364/lib/@octokit/plugin-rest-endpoint-methods/dist-src/endpoints-to-methods.js

我可以看到浏览器中显示的 js 文件,所以我知道它可以被路径到。现在理想情况下,我希望能够在我编写的另一个自定义 js 中使用这个包,它遍历我的 repos 并创建带有所有信息的漂亮小卡片,所以我基本上只是想像这样使用它:

var octokit = new Octokit({ userAgent: 'agentName' });

但显然上面是在抱怨 Octokit 的存在。

所以我想我的问题是,到底是什么?我显然在这里遗漏了一些东西,所以如果有人对我需要寻找或研究的方向有任何想法,我将非常感激。

这可能与 octokit 包根本无关,更有可能是我只是不明白如何将这些类型的 JavaScript 库正确导入到我的 asp .net 核心解决方案中

4

1 回答 1

1

添加 Octokit 的几个部分您遇到了困难:处理@符号、导入它的范围以及您尝试使用用于构建工具的文件这一事实。

@在 Razor 页面中

当您在 Razor 页面上下文中的标记中编写 JavaScript 内联代码<script>,您需要使用. 例如,如果你引用 Octokit 路径,你会写.@@@@@octokit/rest

范围

使用时type=module,您的代码具有模块作用域,使您无法引用Octokit模块外部的变量。为了突破模块范围,您可以将Octokit变量附加到window对象:

window.Octokit = new Octokit({ userAgent: 'agentName' });

然后稍后,您在其他脚本块中的代码可以像往常一样访问 Octokit:

const { data } = await Octokit.request("/user");

构建 Octokit

您导入的文件不适合浏览器直接使用。它希望您将其导入 JavaScript 构建工具,而不是直接从浏览器将其作为模块导入。

index.js您尝试导入客户端的文件旨在与一些 JavaScript 构建工具(如 Webpack)一起使用。为了让它在 gulp 中以您希望的方式工作,您需要修改您的gulpfile.js以包含某种插件,该插件会将@octocat/rest其导入并输出到浏览器可用的文件中。

要使用 Webpack 执行此操作,您需要为 gulp 安装 Webpack 插件: npm install --save-dev webpack-stream gulp-rename

gulpfile.js然后,在您的调用旁边创建一个文件,该文件index.js导入库并对其执行一些操作:

import { Octokit } from "@octokit/rest"

window.Octokit = new Octokit({ userAgent: 'agentName' });

现在,修改你的通过 webpack 插件gulpfile.js获取和管道:index.js

const gulp = require('gulp');
const webpack = require('webpack-stream');
const rename = require('gulp-rename');

gulp.task('default', () =>
    gulp.src(['index.js'])
        .pipe(webpack())
        .pipe(rename("index.js"))
        .pipe(gulp.dest('lib/octokit/rest/'))
);

运行后gulp,你应该有一个输出文件,它已经解决了所有必要的依赖关系@octokit/rest

替代解决方案

为了省去这个特定包的麻烦,你可以从他们的 CDN 加载 Octokit吗?CDN 为您处理所有构建和包解析。您的代码可能是:

<script type="module">
    import { Octokit } from "https://cdn.skypack.dev/@@octokit/rest";
    window.Octokit = new Octokit({ userAgent: 'agentName' });
</script>

(请注意,这@@将转义@Razor 页面上的标志。)

大多数包都提供了一个 CDN 选项来加载他们的库客户端,而不必乱用构建工具。即使他们没有正式提供 CDN,像jsdelivrunpkg这样的网站仍然可以提供导入这些文件的方法。


将来某个时候,看起来浏览器可能会支持import-maps。然后,您将能够通过浏览器处理包解析,并在您的 Razor 页面上执行以下操作:

<script type="importmap">
{
    "imports": {
        "/@@octokit": "/lib/@@octokit/"
    }
}
</script>
<script type="module">
    import { Octokit } from '@@octokit/rest';
    var octokit = new Octokit({ userAgent: 'agentName' });
</script>

看起来这可能适用于像system-js这样的 polyfill ,您可以在其中添加s.js加载器并替换importmapsystemjs-importmap.

于 2020-11-13T02:05:33.353 回答