2017-03-17 106 views
17

我想在我的Angular 2项目中使用libquassel(https://github.com/magne4000/node-libquassel)。图书馆被浏览了,所以理论上它应该可以工作,但我不确定如何将它导入到我的项目中。在Angular 2中使用浏览过的JS库

我尝试添加到我的typings.d.ts

declare module 'libquassel'; 

,然后用

import * as Quassel from 'libquassel'; 

导入库,但我得到

EXCEPTION: net.Socket is not a function 

,当我尝试运行我的代码,这是我相信是另一个浏览嵌入在client/libquassel.js文件中的库。

我该如何使用这个库?

编辑:我会在这里回答你所有的问题:

  • 我的设置是一个普通的角CLI项目。没有花哨的东西,只是ng new proj1,然后npm install libquassel --save
  • index.html没有其他任何ng new没有放置在那里。
  • 我试图用import * as Quassel from 'libquassel'var Quassel = require('quassel')(和那些排列)导入库,没有任何运气(错误从unknown function 'require'can't find module lib|quassel)。
  • 步骤瑞普我的项目:

    ng new test 
    cd test 
    npm install libquassel --save 
    ng g s quassel 
    

然后在app.module.ts添加QuasselServiceproviders阵列。 这将是我的问题的一个很好的演示,这是如何在我的QuasselService导入libquassel

+0

你能给出更多关于你的设置的细节吗?你的index.html是什么样的?你使用角度cli?你如何导入这个模块? – echonax

+0

@echonax检查我的编辑。您也可以重现我的项目,因为这只是一个简单的角色项目。 – alexandernst

+0

用你配置文件更新你的文章 – Aravind

回答

4

更新(解决它,这次是动真格)

有一个很好的理由,为什么它不会在你的代码工作:因为我骗了你。所以这里是我真正的作弊,以防你自己没有“扩散”它。

我还需要require libquassel 2倍,但第一次由呼叫没有做require这是无用的,但将它添加到angular-cli.jsonscripts部分:

"scripts": [ 
    "../node_modules/libquassel/client/libquassel.js" 
    ], 

这是因为重要的“客户端/ libquassel.js”宣布了自己的require,但并没有明确出口它,所以如果你

require('libquassel/client/libquassel.js'); 

libquassel的定制require留给小号隐藏在匿名命名空间内,您无法访问它。另一方面,将它添加到scripts部分,让libquassel.js污染全局名称空间(即window)及其require,从而使其工作。

所以实际步骤,使其工作有:

  1. 添加客户端/ libquassel.js到脚本的angular-cli.jsonsection
  2. 使用额外require实际加载Quassel模块
let Quassel = window['require']('quassel'); // note that usingg require('quassel') leads to compilation error 
let quasselObj = new Quassel(...); 

这是我的尝试。看起来你需要require“quassel”2次:第一次从“../node_modules/libquassel/client/libquassel.js”加载JS,第二次让来自该JS的重写的require实际上解决了“quassel” 。下面是我戴好像在“main.ts”工作一招:我需要一个更伎俩不失败,编译错误

require('../node_modules/libquassel/client/libquassel.js'); 
let Quassel = window['require']('quassel'); // note that using require('quassel') leads to compilation error 
let quasselObj = new Quassel(...); 

:特别是我不得不使用window['require'],而不是仅仅为require第二个呼叫,因为它是client/libquassel.js中定义的内部require的呼叫,而Node/Angular-cli本身无法处理它。

注意,安装后,我的应用程序仍然失败,运行时错误在一些AJAX因为browsified libquassel.js似乎需要一个代理设立在像/api/vm/net/connect URL服务器端,这可能是net-browsify什么样的服务器端应该做,但我没有尝试设置它。

答到的意见

它看起来像您使用旧版本的角CLI的,如果你升级应当一切正常。

这里是ng --version告诉我,我的原机

angular-cli: 1.0.0-beta.28.3 
node: 6.10.0 
os: win32 x64 
@angular/common: 2.4.10 
@angular/compiler: 2.4.10 
@angular/core: 2.4.10 
@angular/forms: 2.4.10 
@angular/http: 2.4.10 
@angular/platform-browser: 2.4.10 
@angular/platform-browser-dynamic: 2.4.10 
@angular/router: 3.4.10 
@angular/compiler-cli: 2.4.10 

当我想我原来的项目复制到另一台机器我也得到一个编译错误约require但是当我更新的角CLI来

@angular/cli: 1.0.0 
node: 6.10.0 
os: darwin x64 
@angular/common: 2.4.10 
@angular/compiler: 2.4.10 
@angular/core: 2.4.10 
@angular/forms: 2.4.10 
@angular/http: 2.4.10 
@angular/platform-browser: 2.4.10 
@angular/platform-browser-dynamic: 2.4.10 
@angular/router: 3.4.10 
@angular/cli: 1.0.0 
@angular/compiler-cli: 2.4.10 

它编译和工作是一样的。是我所做的只是跟着指令

The package "angular-cli" has been deprecated and renamed to "@angular/cli".

Please take the following steps to avoid issues:
"npm uninstall --save-dev angular-cli"
"npm install --save-dev @angular/[email protected]"

,然后更新angular-cli.jsonng serve

+0

这看起来不错!不要担心您收到的AJAX错误,这是因为您需要特制的expressjs服务器侦听。 – alexandernst

+0

我终于在家了,我正在测试你的代码,但是我得到了这个:'src/app/quassel-client.service.ts(6,1):找不到'require'的名字。 – alexandernst

+0

@alexandernst,我现在不在我的代码中,但你在哪里得到它?对于'require('../ node_modules/libquassel/client/libquassel.js')这行是编译错误还是'let quassel = window ['require']('quassel')的运行时错误? '? – SergGr

0

角CLI使用的WebPack

,你将需要JS文件添加到应用程序[0]在您的角cli.json文件,然后的WebPack捆绑,如果它装载有一个标签.scripts中。

apps:[ 
{ 
    ... 
    "scripts": [ 
    "../node_modules/libquassel/client/libquassel.js" 
    ], 

如果你这样做,你可以用它在你的src/typings.d.ts或组件添加declare var Quassel :any;得到。

let quassel = new Quassel("localhost", 4242, {}, function(next) { 
    next("user", "password"); 
}); 
quassel.connect(); 
+1

我得到'EXCEPTION:Quassel没有定义'。让我解释一下(这篇文章第五次),这不是一个普通的JS库,它导出了一些东西,而是一个Browserify库,它应该是'require'd,这就是为什么你的解决方案没有工作(实际上这就是为什么我给这个问题分配了500点恩惠的原因,因为这非常棘手)。如果我将这个库加载到脚本标签中,我可以通过'var Quassel = require(“quassel”)'来访问它。 – alexandernst

1

就像一个魅力的说明:

declare var require; 
const Quassel = require('libquassel/lib/libquassel.js'); 
console.log('Quassel', Quassel); 

望着libquassel的在node_module文件夹,意识到根目录中没有index.js

在没有index.js,你不能做到这一点:

require('libquassel'); 

很简单,因为节点不知道拉什么在给你,所以你需要指定的确切路径,在这种情况下这并不坏。

另外,请注意,最好将declare var require;移动到位于src文件夹下的打印文件中,因为您可能需要重新声明它,所以最好在那里。

编辑: 这是我试图实例化Quassel像波纹管后发现:

const Quassel = require('libquassel/lib/libquassel.js'); 
console.log('Quassel', Quassel); 
var quassel = new Quassel("quassel.domain.tld", 
    4242, 
    { backloglimit : 10 }, 
    function (next) { 
     next("user", "password"); 
    }); 
console.log('quassel', quassel); 

这里是我的控制台日志:

enter image description here 不过话说回来,我意识到有是libquassel.js中的一个问题,如下所示:

在第10行,他们这样做:

var net = require('net'); 

而看着他们的package.json,没有这样的事情netnet-browserify-alt;

所以,如果他们改变进口:

var net = require('net-browserify-alt'), 

一切都会解决的。

话虽如此,显然你不想编辑你的node_module,但我真的很惊讶,即使在angular和webpack之外,它真的可以工作,因为显然他们提到了一个错误的node_module,如果你google ,只有一个名为net的包,我看了一下,它是空的和假的!

** ********** UPDATE:********** **

究竟需要采取哪些措施:

1-运行ng eject

这将在根目录内生成webpack.conf.js

2-里面那个找resolve财产,并添加:

"alias":{ 
    'net':'net-browserify-alt' 
    }, 

所以你的决心可能会是这样的:

"resolve": { 
    "extensions": [ 
     ".ts", 
     ".js" 
    ], 
     "alias":{ 
     'net':'net-browserify-alt' 
     }, 
    "modules": [ 
     "./node_modules" 
    ] 
    }, 

3-进口并使用它:

declare var require; 
const Quassel = require('libquassel/lib/libquassel.js'); 
console.log('Quassel', Quassel); 
var quassel = new Quassel("quassel.domain.tld", 
    4242, 
    { backloglimit : 10 }, 
    function (next) { 
     next("user", "password"); 
    }); 
console.log('quassel', quassel); 

注:

在看看的WebPack配置,恍如的WebPack喜欢重写几个模块,:

"node": { 
    "fs": "empty", 
    "global": true, 
    "crypto": "empty", 
    "tls": "empty", 
    "net": "empty", 
    "process": true, 
    "module": false, 
    "clearImmediate": false, 
    "setImmediate": false 
    } 

我完全不知道为什么,但这个名单是在配置的WebPack,似乎是使net成为undefiend(空),这就是为什么我们必须创建一个别名。

+0

通过要求节点版本('lib/libquassel.js')而不是浏览过的版本('client/libquassel.js'),我不太确定typescript的编译器/ webpack /任何能够正确替换' net'与'net-browserify'。也就是说,你是否真的试图在执行'require(“..... client/libquassel.js”)后实例化'Quassel'?我的意思是,你能够真正运行'var foo = new Quassel();'? – alexandernst

+3

'net'是一个内部node.js模块(https://nodejs.org/api/net.html) – Alexus

+0

@Alexus,欢呼声,不知道 – Milad

0

关键问题是浏览过的libquassel库中包含一个全局require函数。与标准require函数冲突。

处理此问题的方法有很多,但一种解决方案是将/libquassel/client/libquassel.js(和缩小版本)复制到您的/src/app/目录中。

然后运行搜索,并以这些文件替换改变require所有出现_quasselRequire_

你会做这两个libquassel.jslibquassel.min.js

要利用这一点,你会做quassel.service.ts是这样的:

import { Injectable } from '@angular/core'; 
import * as dummyQuassel1 from './libquassel.js' 

var dummyQuassel2 = dummyQuassel1; // something just to force the import 

declare var _quasselRequire_ :any; 

@Injectable() 
export class QuasselService { 

    constructor() { 

    // set up in the constructor as a demo 

    let Quassel = _quasselRequire_('quassel'); 
    console.log('Quassel', Quassel); 

    var quassel = new Quassel( 
     "quassel.domain.tld", 
     4242, 
     { backloglimit : 10 }, 
     function (next) { 
      next("user", "password"); 
     } 
    ); 

    console.log('quassel', quassel); 

    quassel.on('network.init', function(networkId) { 
     console.log("before net"); 
     var network = quassel.getNetworks().get(networkId); 
     console.log("after net"); 
     // ... 
    }); 

    console.log("before connect"); 
    quassel.connect(); 
    console.log("after connect"); 
    } 

    getQuassel() { 
     return 'My Quassel service'; 
    } 
} 

这本身导致错误:

POST http://localhost:4200/api/vm/net/connect 404 (Not Found)

Error: Uncaught, unspecified 'error' event. at new Error (native) at Quassel.n.emit (http://localhost:4200/main.bundle.js:570:4210) [angular] at Socket. (http://localhost:4200/main.bundle.js:810:19931) [angular] at Socket.EventEmitter.emit (http://localhost:4200/main.bundle.js:573:1079) [angular] ...

但据我了解这是相当正常的,因为我没有表达等设置。

注意:名称_quasselRequire_可以是任何适合您的东西。

+0

正如你可能知道你还需要添加属性' “allowJs”:true' to'compilerOptions' in'tsconfig.app.json' –

+0

如果你要这样做,你可能需要编写一个脚本来做到这一点,因为大部分时间你安装你的依赖关系,你不要碰他们。 从升级的角度来看,这也是不好的,如果你甚至想要升级包装,那你就搞砸了 – Milad

+0

你为什么要拧? –