【问题标题】:Using noty in Aurelia/Typescript application在 Aurelia/Typescript 应用程序中使用 noty
【发布时间】:2019-07-01 16:05:42
【问题描述】:

我一直在尝试将 NOTY 与 Aurelia/Typescript 应用程序一起使用。使用 NPM 安装包并使用 requireJS 将其拉入应用程序。

无论我尝试什么,我都无法让它工作。为了在我需要参考的文件中导入它,我尝试了以下两种方法


尝试#1

import * as Noty from 'noty';

这似乎创建了正确的引用,我可以在代码中看到这一点。当我尝试使用它时,我没有收到任何构建错误,并且一切正常。

但是当我运行这段代码时,我得到一个错误,指出 - "Noty is not a constructor"


尝试 2

import Noty from 'noty'

这种方法抱怨没有默认导出成员。

我尝试的另一个变体是 import { Noty } from 'noty'; 这给了我类似的响应


不确定我遗漏了什么,但非常感谢任何实现这一点的建议。 TIA


更新#1

在 aurelia.json 文件中添加

Noty 包未加载

PS:如果需要查看 index.d.ts 文件,请添加指向 NOTY 的链接。

【问题讨论】:

  • 您是否为Noty.d.ts 文件)添加了类型定义?
  • @adiga:你是这个意思吗? { "name": "noty", "path": "../node_modules/noty", "main": "index" }
  • 您是否在 aurelia 模板或基本 HTML 文件中包含了对 NOTY 脚本的引用?你确定 requireJS 正在成功加载 NOTY 脚本文件吗?
  • @JoyalToTheWorld - 新手 - 你能提供更多信息吗?我相信我没有。我正在进一步调试,发现该模块在运行时未定义。
  • @Ron 也许你可以用你的 requireJS 配置更新你的帖子。这应该负责加载您的脚本,您需要将“NOTY”包名称映射到磁盘上脚本的位置,类似于您在上面回复 adiga 时发布的内容。此外,您可以检查开发工具,看看是否有任何失败的请求,将请求中的路径与您在磁盘上实际看到的路径进行比较。希望对您有所帮助。

标签: typescript aurelia noty


【解决方案1】:

听起来你的 requireJS 包映射指向了错误的文件(可能是 index.d.ts 文件)。

我刚刚查看了“noty”NPM 包,看起来你的 requireJS 映射应该是这样的:

{ "name": "noty", "path": "../node_modules/noty/lib", "main": "noty.min" }

TypeScript 关心 *.d.ts 文件,但 requireJS 不是 TypeScript,它负责将文件加载到浏览器中,因此它只关心 Javascript 文件。

顺便说一句,您没有立即意识到网络平台的疯狂是可以原谅的。

【讨论】:

  • 感谢您将此作为答案 - 我尝试了上述方法,但仍然没有运气
  • 好的,看来我们正在取得进展 - 我查看了他们的文档并通过使用 Caps 'N' 命名模块来稍微改变您的建议。现在我看到它试图在我的/src 文件夹中找到noty.js 文件并为该文件返回404
  • 所以您的方法 #1 是正确的。看起来 TS 很高兴,它可以识别包名称并提供输入。这意味着问题出在加载包的某个地方。我想确认上面的代码在 aurelia.json 文件的“依赖项”部分中,您的 aurelia.json 文件也应该在 /aurelia_project 下,它是 /node_modules 的兄弟。
  • 前面的都成立。
  • 在这种情况下,您似乎正在使用 Aurelia CLI,我猜这是在强制执行某种无法生成正确输出的捆绑过程。如果没有有关您的配置的更多信息,将很难提供帮助。我遇到了this,如果不出意外,它可能会帮助您找到破解/解决方法。
【解决方案2】:

noty 库有一个命名的 AMD 定义 define('Noty',...),而不是普通的匿名定义。它应该可以工作,但似乎我最近的 PR 在命名 AMD 模块上为 cli-bundler 创建了回归,或者可能在命名 AMD 模块上创建了一个新错误。

我会修复那个回归。 我更新了 https://github.com/aurelia/cli/pull/1084

现在要解决,

  1. 在您的项目中创建另一个文件patch/noty.js,其内容为:
define('noty',['Noty'],function(m){return m;});

此补丁创建从 'noty' 到 'Noty' 的别名。

  1. 添加到 aurelia.json 前置,必须在 requirejs 之后
  2. 默认主lib/noty.js还有一个问题:
ERROR [Bundle] Error: An error occurred while trying to read the map file at /Users/huocp/playground/nt/node_modules/noty/lib/es6-promise.map

它尝试加载 es6-promise.map 但没有这样的文件。

更新:错误不会停止捆绑。

{
    "name": "vendor-bundle.js",
    "prepend": [
      "node_modules/requirejs/require.js",
// add this line after requirejs
      "patch/noty.js"
    ],
    "dependencies": [
      "aurelia-bootstrapper",
      "aurelia-loader-default",
      "aurelia-pal-browser",
      {
        "name": "aurelia-testing",
        "env": "dev"
      },
      "text",
// optionally override noty main path, only if you want to get rid of the annoying es6-promise.map error
      {
        "name": "noty",
        "path": "../node_modules/noty",
        "main": "lib/noty.min"
      }

    ]
}

然后这个导入有效,我测试了。

import * as Noty from 'noty';

顺便说一句,忘记* as,使用微软推荐的esModuleInterop编译器选项。 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html

【讨论】:

    【解决方案3】:

    您遇到的问题可能来自 NOTY 导出其主要功能的方式,我猜这是用 commonjs 方式完成的:

    module.exports = NOTY;
    

    要在您的代码中正确导入它,您应该使用导入模块语法:

    从'noty'导入*作为NOTY;

    对于许多仍然保持传统方式的导出样式的其他库来说也是如此。

    更新:

    基于他们的类型定义导出:https://github.com/needim/noty/blob/master/index.d.ts#L2

    declare module 'noty' {
      exports = Noty;
    }
    

    这意味着你应该总是像你的尝试 1 那样做。但这就是它的实际发货方式https://github.com/needim/noty/blob/master/lib/noty.js#L9-L18

    (function webpackUniversalModuleDefinition(root, factory) {
      if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
      else if(typeof define === 'function' && define.amd)
        ...
      else if(typeof exports === 'object')
        exports["Noty"] = factory();
    ...
    

    注意最后一部分exports["Noty"] = factory()。我怀疑这是捡到的,而不是第一个。这意味着它等于命名导出Noty

    因此,导致您出现问题的可能是该导出内容之间的不匹配。我建议你这样做:

    import * as $NOTY from 'noty';
    
    // wrong: const NOTY = $NOTY as any as typeof $NOTY;
    // wrong: const NOTY = $NOTY.Noty as any as typeof $NOTY;
    // or 
    // wrong: const NOTY = new (options: $NOTY.OptionsOrSomeThing): $NOTY;
    const NOTY = ($NOTY as any).Noty as new (options: $NOTY.OptionsOrSomeThing): $NOTY;
    
    // do your code here with NOTY
    new NOTY();
    

    【讨论】:

    • 我尝试了上述方法,您可以在 Attempt#1 中看到 - 这似乎可以正确导入内容,但是当我尝试使用构造函数时,它不喜欢它并引发错误。有什么建议吗?
    • 我已经更新了答案,你可以看看试试吗?
    • 谢谢,这看起来很有希望,但没有骰子 - 仍然会弹出相同的“Noty is not a constructor”错误。
    • 为您添加了赏金以寻求帮助!
    • 我确实尝试了最新的更新,但仍然遇到错误 - 我会在使用计算机时提供更多详细信息。如果您觉得我们可以在这方面取得进展,我愿意花更多的时间和精力 :)
    猜你喜欢
    • 1970-01-01
    • 2020-07-09
    • 2017-07-09
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 2015-12-13
    • 2016-11-14
    • 1970-01-01
    相关资源
    最近更新 更多