我想在我的Angular 2项目中使用libquassel(https://github.com/magne4000/node-libquassel)。该库是浏览器化的,所以理论上它应该可以工作,但我不确定如何在我的项目中导入它。
我尝试添加到typings.d.ts
declare module 'libquassel';
然后使用
导入库import * as Quassel from 'libquassel';
但我得到
EXCEPTION: net.Socket is not a function
当我尝试运行我的代码时,我认为这是另一个浏览嵌入client/libquassel.js
文件的库。
我该如何使用这个库?
修改:我将在此回答所有问题:
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
然后将QuasselService
添加到providers
中的app.module.ts
数组中。
这将是我的问题的一个很好的演示,即如何在我的libquassel
中导入QuasselService
。
答案 0 :(得分:5)
更新(修复此问题,这次是真实的)
有一个很好的理由说明它在你的代码中不起作用:因为我欺骗了你。所以这是我真正的欺骗,以防你没有"差异"它自己呢。
我仍然需要require
libquassel 2次,但第一次不是通过调用require
来完成的,这是无用的,但是将其添加到angular-cli.json
scripts
部分:
"scripts": [
"../node_modules/libquassel/client/libquassel.js"
],
这很重要,因为" client / libquassel.js"声明它自己的require
但是如果你做
require('libquassel/client/libquassel.js');
libquassel的自定义require
被卡在匿名命名空间内,您无法访问它。另一方面,将它添加到scripts
部分,让libquassel.js用其window
污染全局命名空间(即require
),从而使其工作。
所以实现它的实际步骤是:
section
angular-cli.json
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
来进行第二次调用,因为它是对内部{{1}的调用如require
中定义的那样,Node / Angular-cli无法处理它。
请注意,在该设置之后,我的应用程序仍然因某些AJAX中的运行时错误而失败,因为browsified client/libquassel.js
似乎需要在服务器端设置代理,如libquassel.js
这样的网址,这可能是net-browsify应该做什么服务器端,但我没有尝试设置它。
回复评论
看起来你使用旧版本的Angular-CLI,如果升级,一切都应该可以正常工作。
以下是/api/vm/net/connect
在原始机器上告诉我的内容
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
的编译错误,但当我将Angular-CLI更新为
require
它编译和工作相同。我所做的只是遵循指令
包" angular-cli"已被弃用并重命名为" @ angular / cli"。
请采取以下措施以避免问题:
" npm卸载--save-dev angular-cli"
" npm install --save-dev @ angular / cli @ latest"
然后按照@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
angular-cli.json
答案 1 :(得分:1)
像魅力一样:
declare var require;
const Quassel = require( 'libquassel/lib/libquassel.js' );
console.log( 'Quassel', Quassel );
查看node_module中的libquassel
文件夹,发现根目录中没有index.js
。
如果没有index.js
,则无法执行此操作:
require( 'libquassel' );
仅仅因为节点不知道要为您提供什么,所以您需要指定确切的路径,在这种情况下并不是那么糟糕。
另外,请注意,将declare var require;
移动到位于src文件夹下的打字文件会更好,因为您可能需要再次声明它,因此最好在那里。< / p>
编辑: 这是我在尝试实例化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 );
这是我的控制台日志:
但话虽如此,我意识到libquassel.js中存在一个问题,如下所示:
在第10行,他们正在这样做:
var net = require('net');
看着他们的package.json,没有net
这样的东西,而且net-browserify-alt
;
因此,如果他们将导入更改为:
var net = require('net-browserify-alt'),
一切都会奏效。
话虽如此,显然你不想编辑你的node_module,但我真的很惊讶甚至在angular和webpack之外它是如何工作的,因为很明显他们提到了错误node_module,如果你谷歌,只有一个名为net
的包我看了,它是空的和假的!!!!
** **********更新:********** **
究竟需要做什么:
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
成为不公平(空),这就是我们必须创建别名的原因
答案 2 :(得分:0)
Angular-cli使用webpack
您需要将JS文件添加到angular-cli.json文件中的apps [0] .scripts中,然后将WebPack捆绑,就好像它已加载了标记一样。
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();
答案 3 :(得分:0)
关键问题是浏览器化libquassel
库中包含全局require
函数。这与标准require
函数冲突。
处理此问题的方法有很多,但一种解决方案是将/libquassel/client/libquassel.js
(和缩小版本)复制到/src/app/
目录。
然后在这些文件中运行搜索并替换以将所有require
更改为_quasselRequire_
您可以对libquassel.js
和libquassel.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(未找到)
和
错误:未捕获,未指定的“错误”事件。 在新错误(本机) 在Quassel.n.emit(http://localhost:4200/main.bundle.js:570:4210)[有角度的] 在Socket。 (http://localhost:4200/main.bundle.js:810:19931)[有角度的] 在Socket.EventEmitter.emit(http://localhost:4200/main.bundle.js:573:1079)[angular] ...
但据我所知,这是相当正常的,因为我没有设置Express等。
注意:名称_quasselRequire_
可以是适合您的任何内容。