Usar una biblioteca JS con browser con Angular 2

Quiero utilizar libquassel ( https://github.com/magne4000/node-libquassel ) en mi proyecto Angular 2. La biblioteca está navegada, por lo que en teoría debería funcionar, pero no estoy seguro de cómo importarla en mi proyecto.

Intenté agregar a mis typings.d.ts

 declare module 'libquassel'; 

y luego importar la biblioteca con

 import * as Quassel from 'libquassel'; 

pero yo obtengo

 EXCEPTION: net.Socket is not a function 

cuando trato de ejecutar mi código, que creo que es otra biblioteca que navega integrada en el file client/libquassel.js .

¿Cómo puedo usar esta biblioteca?

Editar : responderé todas las preguntas aquí:

  • Mi configuration es un proyecto plain angular cli. No hay cosas sofisticadas, solo hay un ng new proj1 y luego npm install libquassel --save .
  • Mi index.html no tiene nada más que ng new no haya colocado ahí.
  • Intenté importar la biblioteca con import * as Quassel from 'libquassel' y var Quassel = require('quassel') (y permutaciones de los var Quassel = require('quassel') ), sin suerte (los errores que varían de la unknown function 'require' a can't find module lib|quassel ).
  • Pasos para reproducir mi proyecto:

     ng new test cd test npm install libquassel --save ng gs quassel 

A continuación, agregue QuasselService a la matriz de providers en app.module.ts . Esta sería una buena demostración de mi problema, que es cómo importar libquassel en mi QuasselService .

Actualizar (corregirlo, esta vez de verdad)

Hay una muy buena razón por la cual no funciona en tu código: porque te mentí. Así que aquí está mi verdadero truco en caso de que aún no lo hayas "diferido".

Todavía tengo que solicitar libquassel 2 veces, pero la primera vez no se realiza mediante la llamada a require que es inútil, sino que se agrega a angular-cli.json a la sección de scripts :

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

Esto es importante porque "client / libquassel.js" declara su propio require pero no lo exporta explícitamente, así que si lo hace

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

Los requisitos personalizados de libquassel quedan bloqueados dentro del espacio de nombres anónimo y no se puede acceder a ellos. Por otro lado, al agregarlo a la sección de scripts , deja que libquassel.js contamine el espacio de nombres global (es decir, la window ) con su require y así lo haga funcionar.

Entonces los pasos reales para hacerlo funcionar son:

  1. Agregue client / libquassel.js a la section de scripts de angular-cli.json
  2. Use require adicionales para cargar realmente el module Quassel
 let Quassel = window['require']('quassel'); // note that usingg require('quassel') leads to comstacktion error let quasselObj = new Quassel(...); 

Aquí está mi bash. Parece que necesita require "quassel" 2 veces: la primera vez para cargar el JS de "../node_modules/libquassel/client/libquassel.js" y la segunda vez para permitir que el reemplazado require de ese JS resolver realmente el "quassel" . Aquí hay un truco que parece funcionar para mí en 'main.ts':

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

Necesitaba un truco más para no fallar con un error de compilation: particularmente tenía que usar la window['require'] lugar de solo require para la segunda llamada, ya que es una llamada para el require interno como se define dentro del client/libquassel.js y Node / Angular-cli solo no puede manejarlo.

Tenga en count que después de esa configuration, mi aplicación aún falló con un error de time de ejecución en algunos AJAX porque browsified libquassel.js parece requerir un proxy configurado en el lado del server en URL como /api/vm/net/connect y esto es probablemente el server -la parte de net-browsify debería funcionar, pero no intenté configurarlo.

Responder a los comentarios

Parece que usa la versión anterior de Angular-CLI y si actualiza todo debería funcionar bien.

Esto es lo que ng --version me dice en mi máquina original

 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 

Cuando intenté copyr mi proyecto original en una máquina diferente, también obtuve un error de compilation sobre require pero cuando actualicé Angular-CLI para

 @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 

compiló y trabajó de la misma manera. Lo que hice es solo seguir la instrucción

El package "angular-cli" ha quedado en desuso y se ha cambiado el nombre a "@ angular / cli".

Por favor, siga los siguientes pasos para evitar problemas:
"npm uninstall –save-dev angular-cli"
"npm install –save-dev @ angular / cli @ latest"

y luego se actualizó angular-cli.json siguiendo las instrucciones de ng serve

Funciona de maravilla :

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

Al libquassel la carpeta de libquassel en node_module, se dio count de que no hay index.js en el directory raíz.

Cuando no hay index.js , no puedes hacer esto:

  require( 'libquassel' ); 

Simplemente porque el nodo no sabe qué hacer por ti, por lo que necesitarías especificar la ruta exacta, que no es tan mala en este caso.

Además, tenga en count que es mejor mover declare var require; a su file typings ubicado debajo de la carpeta src, porque es posible que deba declararlo nuevamente, por lo que es mejor que esté allí.

EDITAR: Esto es lo que encontré después de intentar crear una instancia de Quassel como fuelle:

 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 ); 

Y aquí está mi logging de la console:

enter image description here Pero una vez dicho esto, me di count de que hay un problema dentro de libquassel.js, como a continuación:

en la línea 10, están haciendo esto:

  var net = require('net'); 

Y mirando su package .json, no existe nada como net y net-browserify-alt ;

Entonces, si cambian esa import a:

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

Todo funcionará.

Habiendo dicho eso, obviamente no quieres editar tu node_module, pero estoy realmente sorprendido de cómo funciona esto realmente fuera de angular y de package web, porque claramente mencionaron un node_module incorrecto que si googleas, solo hay un package llamado net que eché un vistazo y está vacío y muerto!

** ********** ACTUALIZACIÓN: ********** **

Qué se debe hacer exactamente:

1- ejecutar ng eject

que generará un webpack.conf.js dentro de su directory raíz.

2- dentro de esa propiedad find resolve y agrega:

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

por lo que su resolución probablemente se verá así:

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

3- importar y usarlo:

 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 ); 

NOTA :

Echando un vistazo a la configuration del package web, parece que el package web le gusta anular dos modules:

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

No sé exactamente por qué, pero esta list está en la configuration de la carpeta web y parece estar haciendo que net sea ​​undefiend (vacío) y es por eso que tuvimos que crear un alias.

Angular-cli usa el package web

Deberá agregar el file JS a las aplicaciones [0] .scripts en su file angular-cli.json, que WebPack agrupa luego como si estuviera cargado con una label.

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

Si lo hace, puede getlo agregando declare var Quassel :any; en su src / typings.d.ts o componente.

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

El problema key es que la librería libquassel libquassel contiene dentro de ella una function global require . Eso entra en conflicto con la function de require estándar.

Hay muchas maneras de manejar esto, pero una solución sería copyr /libquassel/client/libquassel.js (y la versión minificada) en su directory /src/app/ .

Luego ejecute una búsqueda y reemplace en estos files para cambiar TODAS las _quasselRequire_ de require a _quasselRequire_

Haría esto tanto para libquassel.js como para libquassel.min.js .

Para utilizar esto, harías algo como esto en 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'; } } 

Esto por sí mismo da como resultado el error:

POST http: // localhost: 4200 / api / vm / net / connect 404 (no encontrado)

y

Error: Evento 'error' no capturado, no especificado. en el nuevo error (nativo) en Quassel.n.emit ( http: // localhost: 4200 / main.bundle.js: 570: 4210 ) [angular] en Socket. ( http: // localhost: 4200 / main.bundle.js: 810: 19931 ) [angular] en Socket.EventEmitter.emit ( http: // localhost: 4200 / main.bundle.js: 573: 1079 ) [angular] …

Pero, como yo lo entiendo, esto es bastante normal dado que no tengo configurado Express, etc.

Nota: el nombre _quasselRequire_ puede ser cualquier cosa que sea apropiada para usted.