【问题标题】:Which npm packages will and will not work on Angular 2? How do I tell?哪些 npm 包可以在 Angular 2 上工作,哪些不能工作?我该怎么说?
【发布时间】:2017-08-19 04:18:21
【问题描述】:

是否需要修改 NPM 包以与 Angular 2 兼容(例如,添加类型,为它们制作指令)或者任何现有的包都可以工作?如果它们不是全部兼容,我怎么知道什么是兼容的,什么是不兼容的?

例如,假设我要导入这个包 (https://github.com/pvorb/node-md5)。我知道 Angular 2 有一个 ts-md5 包来做 md5 - 我只是以这个包为例。

我该如何让它发挥作用?

我已经安装了它

npm install md5 --save
npm install @types/md5 --save

但我似乎无法导入它

import {md5} from 'md5';

我尝试运行后收到此错误消息

模块 '"/Users/xxx/Source/tempProjects/ngUnderscore/node_modules/@types/md5/index"' 解析为非模块实体,无法使用此导入 构造。

我不确定这条消息是什么意思。这是否意味着在其当前状态下,该软件包不兼容,或者我试图错误地使用该软件包?

【问题讨论】:

标签: javascript typescript npm ecmascript-6 commonjs


【解决方案1】:

他们通常会说它适用于哪个 Angular,有时你会为两者或每个都有一个包。

如果您使用的是 Angular 1x 包并且没有 Angular2 兼容性,那么您可以使用 ngUpgrade

但是如果您使用的是通用插件,那么必须有 angular 2 解决方案。

如果你想反过来,那你可能走错路了。

【讨论】:

    【解决方案2】:

    我设法使用 declare 和 require 而不是 import 使其工作(导入不适用于此非模块库)

    declare const require: any;
    const md5 = require('md5');
    

    如果您不想像这样解决导入问题,可以尝试使用名为 ts-md5 的 Typescript MD5 实现。然后像下面这样导入应该可以工作。 (引用自this question

    import { Md5 } from 'ts-md5/dist/md5'
    

    如果没有TS实现,可以搜索DefinitelyTyped中的类型,然后通过npm i --save-dev @types/{package-name}简单安装包

    【讨论】:

    • 感谢您使用它。我想我正在寻找更多的答案。有大量的 NPM 库——其中一些没有得到积极维护,其中一些没有 TS 声明文件,其中一些不是模块化的——如果我想在 Angular 项目中使用它,标准方法是什么让我让它在 Angular 2 中工作?我可以一直使用 declare const require: any 方法吗?
    • 您可以对任何 JS 库/文件使用声明和要求解决方法。还有一些方法可以在不需要它的情况下使用 3rd 方 javascript。例如,您可以将其链接到 index.html 或使用 webpack(或任何其他构建工具)将其包含在包中。然后你只需要声明使用的 lib/module 或创建自定义类型来阻止编译器抛出错误。
    【解决方案3】:

    该库是否适用于您的项目取决于许多因素:您的 Angular 版本、您的 TypeScript 版本等。

    这就是说,很明显我们应该检查库的文档并查看有哪些依赖项及其版本,当然库应该是其自身的 Angular 2 版本。按照你的例子,有几个 md5 库,但如果你使用 TypeScript,你可能应该考虑这个:https://www.npmjs.com/package/ts-md5

    如果我们已经涵盖了所有内容,但由于某种类型的不兼容仍然有一些东西无法正常工作,例如:

    我的 Angular 版本是 2,我刚刚安装的库适用于 Angular 4。我的代码充满了 <template>,库使用 <ng-template>... 我该怎么办?

    您可以在 github 中分叉该库并修改您需要的任何内容以确保它与您的项目兼容。步骤:

    1. fork 库存储库并修改您需要的内容
    2. 订阅主库存储库,以便根据更改进行更新
    3. packages.json 中使用您的库的分叉版本,例如:

    "ng2-datetime": "https://github.com/my_user/ng2-datetime/tarball/my_forked_version_name",

    1. 如果您认为您的修改可能适合其他用户... 提出拉取请求! :D

    【讨论】:

      【解决方案4】:

      这更像是一个 TypeScript 问题,因为 md5 不是 Angular 包。 关键是让导入正确,以等效于 require() 函数。

      import * as md5 from "md5";
      

      直接在 TypeScript 文件中使用:

      console.log(md5('message'));
      

      要在模板上使用这个,最好在方法实现中使用,也可以直接暴露。将其作为属性添加到组件上:

      md5: any = md5;
      

      然后在模板上:

      {{md5('message')}}
      

      【讨论】:

      • 值得注意的是,使用语法 import * as ns from 'module' 来获取 CommonJS 模块的 module.exports 值是一种非标准的、特定于 TypeScript 的方法,在 NodeJS 提出的 ES 模块互操作中不起作用.
      【解决方案5】:

      您遇到的问题与 Angular 无关。导入 CommonJS 包时 TypeScript 存在的问题。

      经验法则(我的建议)是在导入 CommonJS 时避免使用互操作功能(即import * as X from 'x'),而改用“旧”语法(即import X = require('x'))。

      CommonJS 以module.exports = function() {...} 的形式导出函数时,import * as X from 'x' 不起作用。

      这包括包导出 ES6 类但使用 Babel 转译为 ES5 的情况。

      你可能会看到一些包确实使用这种语法,但那是因为类型中有一个 hack:

      declare module 'x' {
         function foo(): void
         namespace foo {}  // <-- the hack
         exports = foo
      }
      

      互操作不是一个好主意还有其他原因,包括 TypeScript (import * X from 'x') 和 Babel (import X from 'x') 之间的语法不一致。

      您可以在此处了解更多信息并点击以下链接: https://github.com/unional/typescript-guidelines/blob/master/pages/default/modules.md#import-keyword

      更新:随着 TypeScript@2.7 的发布,您现在可以直接使用 import EditableElement from 'Transformer'

      在您的tsconfig.json 中打开esModuleInterop

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-06
        • 1970-01-01
        • 1970-01-01
        • 2011-10-20
        • 2012-08-22
        相关资源
        最近更新 更多