我在安装来自cdn网址的正确js时遇到问题,在浏览了10篇文章或帖子后,我找不到一个好方法。
我要在我的角度项目中使用的js文件是http://player.twitch.tv/js/embed/v1.js。目前,我在index.html中只有一个脚本标记,用于加载它。
在组件文件中,我有this.player = new Twitch.Player("video-player", options);
之类的代码,但是当我运行npm start
时,出现错误错误TS2304:找不到名称'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);
答案 0 :(得分:1)
最终更新 因此,在做了一些研究并更好地了解正在发生的事情(在某种程度上)之后,我想提出一个可能更有意义的更新。在某种程度上,原始和更新都有一些虚假信息。
更新中的一件事是错误的,我的声明是关于VS Code处理&#39; import&#39;指示不同。正确的语句是SystemJS,TypeScript编译器会处理&#39; import&#39;指示不同。在SystemJS的基本情况下(当它加载JS文件时)它甚至看不到这些import语句,它确实看到了import语句的产物(基于在tsconfig.json中如何配置Typescript)文件)。
所以在这个问题上唯一的#34;链接&#34;在&#34; import&#34;中的TypeScript和SystemJS之间陈述是&#34; twitch-api&#34;。 TypeScript会将.ts文件转换为.js文件,SystemJS将在加载页面时读取该文件,它将在其配置设置中查找名为&#34; twitch-api&#34;的软件包。这就是为什么如果您注释掉&#34; Twitch&#34;反对让网站启动,然后取消注释&#34; Twitch&#34;对象,SystemJS已经将该软件包加载到您的站点中,因此它可以正常工作。
对于TypeScript编译器,当编译器遇到import语句时,它有自己的rules集(查找&#39; TypeScript如何解析模块&#39;部分)。基于此,我们看到TypeScript忽略了SystemJS,它只查看文件夹结构中的特定位置。
由于导入是非相对类型,因此它会在您的node_modules中查找与&#34; twitch-api&#34;的匹配,它还会查找扩展名为[&#39; .ts& #39;,&#39; .tsx&#39;&#39; .d.ts&#39]。有趣的是这是一个URL,文件夹结构中没有文件。在正常情况下,TypeScript需要这样才能正确构建JS文件。不幸的是,Twitch没有提供.ts / .tsx / .d.ts文件,DefinitelyTyped也没有为Twitch提供.d.ts文件。
所以我解决这个问题的方法是为Twitch创建我自己的.d.ts文件(不完整,而且Twitch实际上做的不正确)。所以在我的&#34; node_modules&#34;文件夹我创建了一个名为&#34; twitch-api&#34;的文件夹。然后创建文件&#34; index.d.ts&#34;,在该文件中我将此定义放入(再次清楚,这不是定义代码,因为我不知道是什么方法&#34; Twitch.Player(&#34;视频播放器&#34;,选项);&#34;实际上返回但它仍然有效,因为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对象的任何其他方法或属性。
最后,我不确定为什么你能够通过使用&#34; Twitch声明一个变量来解决这个问题:任何&#34;工作。我认为这是因为&#34; import&#39; twitch-api&#39;&#34;导致TypeScript编译器不执行它通常会执行的某些检查。这意味着它只需要知道什么&#34; Twitch&#34;是不是看起来很深。这是我最好的猜测。
<强>更新强> 所以我的第一个猜测是完全错误的,我开始根据你的设置使用pluker,很明显这是其他的东西。我将plunker分成new个,如果我知道如何正确实例化Twitch.Player,那么它就可以在示例中使用。
当它在运行时执行更改后,它应该是显而易见的。您看到的错误是在Typescript编译器中。我不知道你正在使用什么IDE,但我使用的是VS代码而且我遇到了这些因为&#34; import&#34;声明与Plunker中的声明不同。
我认为你几乎就在那里,但你需要两者的结合。第一个例子失败的原因是&#34; twitch-api&#34;不是来自导入命令的已识别包。
我认为你的第二次尝试失败的原因是你如何实现地图和包对象。这是一个plunker,显示了如何使用外部URL实现配置。这是config.js文件的摘录。我不确定你何时需要使用&#34; main&#34;如果文件没有命名,我认为你必须使用它&#34; index&#34;或者它不遵循包裹的名称?
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' }
};
答案 1 :(得分:0)
在我看来,您正在尝试在Angular / Typescript项目中使用Twitch交互式播放器。
我最近遇到了同样的问题,这就是为什么我决定为Twitch交互式嵌入播放器实现Typescript包装器的原因。这与Angular 100%兼容,因此,如果您仍然需要实现此目的的方法,请签出该存储库。我知道我迟到了几年,但我将把它留给其他人。
希望它能帮助^ ^