在 Aurelia/Typescript 应用程序中使用 noty

Posted

技术标签:

【中文标题】在 Aurelia/Typescript 应用程序中使用 noty【英文标题】:Using noty in Aurelia/Typescript application 【发布时间】: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 时发布的内容。此外,您可以检查开发工具,看看是否有任何失败的请求,将请求中的路径与您在磁盘上实际看到的路径进行比较。希望对您有所帮助。 【参考方案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

现在要解决,

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

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

    添加到 aurelia.json 前置,必须在 requirejs 之后。 默认主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”错误。 为您添加了赏金以寻求帮助! 我确实尝试了最新的更新,但仍然遇到错误 - 我会在使用计算机时提供更多详细信息。如果您觉得我们可以在这方面取得进展,我愿意花更多的时间和精力 :)

以上是关于在 Aurelia/Typescript 应用程序中使用 noty的主要内容,如果未能解决你的问题,请参考以下文章

从Aurelia依赖注入容器中显式请求新实例

在 swift 中,如何在应用程序委托中实现一个变量,以便在应用程序的任何地方检索它?

MFP 应用程序在应用程序未运行时在推送通知期间点击时崩溃

在特定时间后终止在后台运行的应用程序?

mac 应用程序安装文件夹在哪

我应该在应用程序中还是在应用程序服务器中定义数据源?