【问题标题】:angular2 TS import cdn js with system JSangular2 TS 用系统 JS 导入 cdn js
【发布时间】:2016-07-15 16:43:59
【问题描述】:

我在正确安装来自 cdn url 的 js 时遇到问题,在浏览了 10 多篇文章或帖子后,我找不到一个好方法。

我要安装以在我的 Angular 项目中使用的 js 文件是 http://player.twitch.tv/js/embed/v1.js。目前,我的 index.html 中只有一个脚本标签来加载它。

在一个组件文件中,我有 this.player = new Twitch.Player("video-player", options); 之类的代码,但是当我运行 npm start 时,我得到一个错误错误 TS2304: Cannot find name 'Twitch'。

奇怪的是,如果我注释掉使用“Twitch”的行,我可以启动我的服务器,然后我在服务器运行时取消注释掉这些行,然后应用程序可以正常工作,利用 Twitch 播放器库没有任何问题。

我相信我需要将它安装在 system.config.js 文件中,但我找不到如何为来自 cdn 的 js 执行此操作(这不能通过 npm 获得)。我已经为多个 npm 包做了这个,但是从 cdn 我有点迷路了。

我不能 100% 确定我是否需要在 systemjs 中执行此操作,所以如果这不正确,请忽略本文的其余部分并让我知道您的建议 - 我只需要 js 文件中的 Twitch在我的应用程序中被识别和使用。

我找到了几种不同的方法来尝试这个。一个是load the module directly from the url

// index.html
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
  System.import('app').catch(function(err){ console.error(err); });
  System.import('http://player.twitch.tv/js/embed/v1.js');
</script>

// main.js
import {bootstrap}    from '@angular/platform-browser-dynamic';
import {AppComponent} from './app.component';
import "angular2-materialize";
import "twitch-api";

使用这种方法,我不确定如何将其加载到我的应用程序中。 import "twitch-api" 不像使用 npm 包(如 angular2-materialize)那样工作,因为它没有映射到 system.config.js 文件中。不确定这种方式是否可行。

另一种方式是load it in the system.config.js file。使用这种方法,我将带有 url 的地图对象添加到 js 文件中。我想可能整个 system.config.js 文件都是相关的,所以我将其全部粘贴在下面。

在 main.ts 中,我执行与上面添加 import "twitch-api"; 相同的操作。完成这些更改后,我在尝试启动服务器 TS2304: Cannot find name 'Twitch' 时仍然收到相同的错误消息。

var map = {
    'app':                        'app', // 'dist',
    'rxjs':                       'node_modules/rxjs',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    '@angular':                   'node_modules/@angular',
    "materialize-css":            "node-modules/materialize-css",
    "materialize":                "node_modules/angular2-materialize",
    "angular2-materialize":       "node_modules/angular2-materialize",
    "angular2-localstorage":      "node_modules/angular2-localstorage",
    "twitch-api":                 "http://player.twitch.tv/js/embed/v1.js"
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.js',  defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { defaultExtension: 'js' },
    "materialize-css":            { main: "dist/js/materialize" },
    "materialize": { main: "dist/materialize-directive", defaultExtension: "js" },
    "angular2-localstorage": {main: "index.js", defaultExtension: 'js'},
    "twitch-api": {}
  };
  var packageNames = [
    '@angular/common',
    '@angular/compiler',
    '@angular/core',
    '@angular/http',
    '@angular/platform-browser',
    '@angular/platform-browser-dynamic',
    '@angular/router',
    '@angular/router-deprecated',
    '@angular/testing',
    '@angular/upgrade',
    ''
  ];
  // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
  packageNames.forEach(function(pkgName) {
    packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
  });
  var config = {
    map: map,
    packages: packages
  }
  System.config(config);

【问题讨论】:

    标签: angular systemjs


    【解决方案1】:

    最终更新 因此,在做了更多的研究并对正在发生的事情有了更好的了解(在一定程度上)之后,我想进行一个可能更有意义的更新。在某种程度上,原始和更新都包含一些虚假信息。

    更新中的一个错误是我关于 VS Code 以不同方式处理“导入”指令的声明。正确的语句是 SystemJS,TypeScript 编译器对“import”指令的处理方式不同。在 SystemJS 的基本情况下(当它加载 JS 文件时)它甚至看不到这些 import 语句,它确实看到了 import 语句的产物(基于 tsconfig.json 文件中 Typescript 的配置方式)。

    所以在这个问题中,“import”语句中 TypeScript 和 SystemJS 之间的唯一“链接”是“twitch-api”。 TypeScript 会将 .ts 文件转译成 .js 文件,SystemJS 会在页面加载时读取该文件,并会在其配置设置中查找名为“twitch-api”的包。这就是为什么如果您注释掉使用“Twitch”对象来启动网站,然后取消注释“Twitch”对象,您的网站会正常工作,SystemJS 已经将该包加载到您的网站中,所以它可以正常工作。

    对于 TypeScript 编译器,当编译器遇到 import 语句时,它有自己的一组 rules(查找“TypeScript 如何解析模块”部分)。基于此,我们看到 TypeScript 忽略了 SystemJS,它只查看文件夹结构中的特定位置。

    由于导入是非相对类型,它会在你的 node_modules 中查找与“twitch-api”的匹配项,它还会查找扩展名为 ['.ts','.tsx',' 的文件.d.ts']。有趣的是这是一个 URL,文件夹结构中没有文件。在正常情况下,TypeScript 需要这个才能正确构建 JS 文件。不幸的是,Twitch 不提供 .ts/.tsx/.d.ts 文件,DefinitelyTyped 不提供 Twitch 的 .d.ts 文件。

    所以我解决这个问题的方法是为 Twitch 创建我自己的 .d.ts 文件(不完整,它与 Twitch 实际所做的不正确)。因此,在我的“node_modules”文件夹中,我创建了一个名为“twitch-api”的文件夹,然后创建了文件“index.d.ts”,在该文件中我将这个定义放入(再次明确,这不是定义代码,因为我不知道“Twitch.Player("video-player", options);" 方法实际上返回了什么,但它仍然有效,因为 SystemJS 没有使用定义文件。)

    export class Twitch{
        static Player(type:string,options:{}):void;    
    }
    
    export class Player{
        constructor(type:string,options:{});
    }
    

    一旦这两件事都到位,我就可以使用完整的导入语句,例如

    import {Twitch,Player} from 'twitch-api'
    

    在您的情况下,您可能需要在定义文件中添加更多用于 Twitch/Player 对象的其他方法或属性。

    最后,我不确定您为什么能够通过使用“Twitch: any”声明一个变量来解决这个问题。我认为这是因为“import 'twitch-api'”导致 TypeScript 编译器不进行通常会进行的某些检查。这意味着它只需要知道“Twitch”是什么并且不会深入研究。这是我的最佳猜测。


    更新 所以我的第一个猜测是完全错误的,我根据你的设置开始玩 pluker,很明显这是另外一回事。我将 plunker 分叉成 new 一个,如果我知道如何正确实例化 Twitch.Player,它将在示例中工作。

    当它在运行时执行更改后会起作用时,这应该是显而易见的。您看到的错误在 Typescript 编译器中。我不知道您使用的是什么 IDE,但我使用的是 VS 代码,我遇到了这些问题,因为“import”语句的工作方式与 Plunker 中的不同。


    我想你快到了,但你需要一种两者的结合。第一个示例失败的原因是“twitch-api”不是导入命令可识别的包。

    我认为您第二次尝试失败的原因是您如何实现地图和包对象。这是一个plunker,它展示了如何使用外部 URL 实现您的配置。这是 config.js 文件的摘录。我不确定何时需要使用“main”属性的所有规则,我认为如果文件未命名为“index”或者它不遵循包的名称,则必须使用它?

    var  map = {
    'app':                        'src', // 'dist',
    'rxjs':                       'https://npmcdn.com/rxjs@5.0.0-beta.6',
    'ng2-toastr':                 'https://npmcdn.com/ng2-toastr@0.3.0'
    };
    
    var packages = {
    'app':                        { main: 'app.ts',  defaultExtension: 'ts' },
    'rxjs':                       { defaultExtension: 'js' },
    'ng2-toastr':                 { main: 'bundles/ng2-toastr.js', defaultExtension: 'js' }
    };
    

    【讨论】:

    • 嘿,谢谢你把它放在一起。这个答案并不完全“正确”,但您提到这是一个 TS 编译错误,这给了我足够的能力,让我能够更好地进行谷歌搜索。我需要声明Twitch: any;,然后一切正常。我确信有更好的方法可以做到这一点,但它现在有效!谢谢。
    【解决方案2】:

    在我看来,您正在尝试在 Angular/Typescript 项目中使用 Twitch 交互式播放器。

    我最近遇到了同样的问题,这就是为什么我决定为 Twitch 交互式嵌入播放器实现一个 Typescript 包装器。这与 Angular 100% 兼容,所以如果你仍然需要一种方法来实现这一点,请查看这个存储库。我知道我迟到了几年,但我会把这个留给其他人。

    希望对你有所帮助^^

    https://github.com/frozencure/twitch-player

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-28
      • 1970-01-01
      • 1970-01-01
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      相关资源
      最近更新 更多