javascript - component - Usando una librería JS con navegador con Angular 2
import js in component angular (4)
Angular-Cli utiliza webpack
deberá agregar el archivo JS a las aplicaciones [0] .scripts en su archivo angular-cli.json, que WebPack luego agrupa como si estuviera cargado con una etiqueta.
apps:[
{
...
"scripts": [
"../node_modules/libquassel/client/libquassel.js"
],
Si lo hace, puede obtenerlo 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();
Quiero usar 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 muy seguro de cómo importarla en mi proyecto.
Intenté agregar a mis typings.d.ts
declare module ''libquassel'';
y luego importando la biblioteca con
import * as Quassel from ''libquassel'';
pero me sale
EXCEPTION: net.Socket is not a function
cuando intento ejecutar mi código, que creo que es otra biblioteca que browserify incrustado en el archivo client/libquassel.js
.
¿Cómo puedo usar esta biblioteca?
Edit : voy a responder a todas las preguntas aquí:
- Mi configuración es un proyecto simple angular-cli. No hay cosas de lujo, solo
ng new proj1
y luegonpm install libquassel --save
. - Mi
index.html
no tiene nada más queng new
no haya colocado allí. - Intenté importar la biblioteca con
import * as Quassel from ''libquassel''
yvar Quassel = require(''quassel'')
(y permutaciones de esos), sin suerte (errores que varían deunknown function ''require''
paracan''t find module lib|quassel
). Pasos para reprozar mi proyecto:
ng new test cd test npm install libquassel --save ng g s quassel
Luego, 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
.
El problema clave es que la biblioteca libquassel libquassel
contiene dentro de ella una función de require
global. Que los conflictos con el estándar require
función.
Hay muchas maneras de manejar esto, pero una solución sería copiar /libquassel/client/libquassel.js
(y la versión minificada) a su directorio /src/app/
.
Luego ejecute una búsqueda y reemplace estos archivos para cambiar TODAS las ocurrencias de require
a _quasselRequire_
Haría esto tanto para libquassel.js
como para libquassel.min.js
.
Para utilizar esto, haría 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 resulta en el error:
POST http://localhost:4200/api/vm/net/connect 404 (No encontrado)
y
Error: No se detectó, no se especificó el evento ''error''. at new 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 lo entiendo, esto es bastante normal dado que no tengo Express, etc. configurado.
Nota: el nombre _quasselRequire_
puede ser cualquier cosa que sea apropiada para usted.
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 cuenta de que no hay index.js
en el directorio raíz.
Cuando no hay index.js
, no puedes hacer esto:
require( ''libquassel'' );
Simplemente porque node no sabe qué hacer para usted, por lo que debería especificar la ruta exacta, que no es tan mala en este caso.
Además, tenga en cuenta que es mejor mover declare var require;
a su archivo de escritura ubicado debajo de la carpeta src, ya que es posible que deba declararlo nuevamente, así que es mejor que esté allí.
EDITAR: Esto es lo que encontré después de intentar crear una instancia de Quassel como a continuación:
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 registro de consola:
Pero dicho esto, me di cuenta 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 hay tal cosa como net
y hay net-browserify-alt
;
Así que si cambian esa importación a:
var net = require(''net-browserify-alt''),
Todo funcionará.
Habiendo dicho eso, obviamente no quieres editar tu nodo_módulo, pero estoy realmente sorprendido de cómo esto realmente funciona incluso fuera de angular y webpack, porque claramente han mencionado un nodo_módulo incorrecto que si buscas en Google, solo hay un paquete llamado net
que tuve un vistazo y está vacío y dummy !!!!
** ********** ACTUALIZACIÓN: ********** **
Lo que se necesita hacer exactamente:
1- ejecutar ng eject
que generará un webpack.conf.js
dentro de su directorio raíz.
2- dentro de ese hallazgo resolve
propiedad y agrega:
"alias":{
''net'':''net-browserify-alt''
},
por lo que su resolución probablemente se verá como:
"resolve": {
"extensions": [
".ts",
".js"
],
"alias":{
''net'':''net-browserify-alt''
},
"modules": [
"./node_modules"
]
},
3- Importarlo 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 :
Mirando la configuración de webpack, parece que a webpack le gusta anular un par de módulos:
"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 lista está en la configuración del paquete web y parece estar haciendo que net
sea undefiend (vacío) y es por eso que tuvimos que crear un alias.
Actualizar (arreglarlo, esta vez de verdad)
Hay una muy buena razón por la que no funciona en tu código: porque te mentí. Así que aquí está mi trampa real en caso de que todavía no la hayas "difamado".
Todavía necesito require
libquassel 2 veces, pero la primera vez no se hace si la llamada require
algo 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'');
El requisito personalizado de libquassel se queda atascado dentro del espacio de nombres anónimo y no se puede acceder a él. Añadiéndolo a la sección de scripts
, por otro lado, permite a libquassel.js contaminar el espacio de nombres global (es decir, la window
) con su require
y así hacerlo funcionar.
Así que los pasos reales para que funcione son:
- Agregue client / libquassel.js a la
section
de scripts deangular-cli.json
- Use un
require
adicional para cargar el móduloQuassel
let Quassel = window[''require''](''quassel''); // note that usingg require(''quassel'') leads to compilation error
let quasselObj = new Quassel(...);
Aquí está mi intento. Parece que necesitas require
"quassel" 2 veces: la primera vez para cargar el JS desde "../node_modules/libquassel/client/libquassel.js" y la segunda vez para dejar que lo anulado require
que JS realmente resuelva "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 compilation error
let quasselObj = new Quassel(...);
Necesitaba un truco más para no fallar con un error de compilación: particularmente tuve que usar la window[''require'']
lugar de solo require
para la segunda llamada, ya que es una llamada para el require
interno según se define en client/libquassel.js
y Nodo / Angular-cli solo no puede manejarlo.
Tenga en cuenta que después de esa configuración, mi aplicación todavía falló con un error de tiempo de ejecución en algunos AJAX porque libquassel.js libquassel.js
parece requerir un proxy configurado en el lado del servidor en la URL como /api/vm/net/connect
y esto es probablemente lo que el servidor - Al lado de net-browsify debería hacerlo pero no intenté configurarlo.
Respuesta a los comentarios
Parece que usa la versión antigua 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é copiar mi proyecto original en una máquina diferente, también obtuve un error de compilación acerca de 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 funcionó igual. Lo que hice es solo seguir las instrucciones.
El paquete "angular-cli" ha quedado obsoleto y se le 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 actualice angular-cli.json
siguiendo las instrucciones de ng serve