Soy nuevo en nodejs y browserify. Empecé con este enlace .
Tengo el archivo main.js que contiene este código
var unique = require('uniq');
var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
this.LogData =function(){
console.log(unique(data));
};
Ahora instalo el módulo uniq con npm:
npm install uniq
Luego agrupo todos los módulos requeridos comenzando en main.js en un solo archivo llamado bundle.js con el comando browserify:
browserify main.js -o bundle.js
El archivo generado se ve así:
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var unique = require('uniq');
var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
this.LogData =function(){
console.log(unique(data));
};
},{"uniq":2}],2:[function(require,module,exports){
"use strict"
function unique_pred(list, compare) {
var ptr = 1
, len = list.length
, a=list[0], b=list[0]
for(var i=1; i<len; ++i) {
b = a
a = list[i]
if(compare(a, b)) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique_eq(list) {
var ptr = 1
, len = list.length
, a=list[0], b = list[0]
for(var i=1; i<len; ++i, b=a) {
b = a
a = list[i]
if(a !== b) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique(list, compare, sorted) {
if(list.length === 0) {
return []
}
if(compare) {
if(!sorted) {
list.sort(compare)
}
return unique_pred(list, compare)
}
if(!sorted) {
list.sort()
}
return unique_eq(list)
}
module.exports = unique
},{}]},{},[1])
Después de incluir el archivo bundle.js en mi página index.htm, ¿cómo llamo a la función logData?
node.js
npm
browserify
SharpCoder
fuente
fuente
Respuestas:
De forma predeterminada, browserify no le permite acceder a los módulos desde fuera del código explorado; si desea llamar al código en un módulo explorado, se supone que debe explorar su código junto con el módulo. Consulte http://browserify.org/ para ver ejemplos de eso.
Por supuesto, también puede hacer que su método sea accesible desde afuera de esta manera:
window.LogData =function(){ console.log(unique(data)); };
Entonces podría llamar
LogData()
desde cualquier otro lugar de la página.fuente
onclick="someFunction()"
. ¡¿No puede estar argumentando que ese es un caso de uso poco común?!La parte clave de agrupar módulos independientes con Browserify es la
--s
opción. Expone todo lo que exporta desde su módulo utilizando nodosmodule.exports
como una variable global. Luego, el archivo se puede incluir en una<script>
etiqueta.Solo necesita hacer esto si por alguna razón necesita que esa variable global esté expuesta. En mi caso, el cliente necesitaba un módulo independiente que pudiera incluirse en las páginas web sin necesidad de preocuparse por este negocio de Browserify.
Aquí hay un ejemplo donde usamos la
--s
opción con un argumento demodule
:browserify index.js --s module > dist/module.js
Esto expondrá nuestro módulo como una variable global llamada
module
.Fuente .
Actualización: Gracias a @fotinakis. Asegúrate de pasar
--standalone your-module-name
. Si olvida que--standalone
toma un argumento, Browserify podría generar silenciosamente un módulo vacío ya que no pudo encontrarlo.Espero que esto te ahorre algo de tiempo.
fuente
La respuesta de @Matas Vaitkevicius con la opción independiente de Browserify es correcta (la respuesta de @ thejh usando la variable global de ventana también funciona, pero como otros han señalado, contamina el espacio de nombres global, por lo que no es ideal). Quería agregar un poco más de detalles sobre cómo usar la opción independiente.
En la secuencia de comandos de origen que desea empaquetar, asegúrese de exponer las funciones que desea llamar a través de module.exports. En el script del cliente, puede llamar a estas funciones expuestas mediante <bundle-name>. <func-name> . He aquí un ejemplo:
Mi archivo fuente src / script.js tendrá esto:
module.exports = {myFunc: func};
Mi comando browserify se verá así:
browserify src/script.js --standalone myBundle > dist/bundle.js
Y mi script de cliente dist / client.js cargará el script incluido
<script src="bundle.js"></script>
y luego llamará a la función expuesta de esta manera:
<script>myBundle.myFunc();</script>
No es necesario solicitar el nombre del paquete en el script del cliente antes de llamar a las funciones expuestas, por ejemplo,
no es necesario y no funcionará.<script src="bundle.js"></script><script>var bundled = require("myBundle"); bundled.myFunc();</script>
De hecho, al igual que todas las funciones incluidas en browserify sin el modo independiente, la función require no estará disponible fuera del script incluido . Browserify le permite utilizar algunas funciones de Node en el lado del cliente, pero solo en el propio script incluido ; no está destinado a crear un módulo independiente que pueda importar y usar en cualquier lugar del lado del cliente, por lo que tenemos que hacer todo este problema adicional solo para llamar a una sola función fuera de su contexto incluido.
fuente
myBundle
se adjunta al objeto de la ventana, enwindow.myBundle.myFunc()
lugar de window.myFunc ()Acabo de leer las respuestas y parece que nadie mencionó el uso del alcance de la variable global. Lo cual es útil si desea utilizar el mismo código en node.js y en el navegador.
class Test { constructor() { } } global.TestClass = Test;
Entonces puede acceder a TestClass en cualquier lugar.
<script src="bundle.js"></script> <script> var test = new TestClass(); // Enjoy! </script>
Nota: TestClass estará disponible en todas partes. Que es lo mismo que usar la variable de ventana.
Además, puede crear un decorador que exponga una clase al ámbito global. Lo cual es realmente bueno, pero dificulta el seguimiento de dónde se define una variable.
fuente
global
produce el mismo efecto que agregar awindow
, que ya estaba cubierto por jh. Esta respuesta no agrega información nueva.return {}
pero suelte la llave de apertura hasta la siguiente línea.Leer README.md de browserify sobre el
--standalone
parámetro o google "browserify umd"fuente
Para tener su función disponible tanto desde HTML como desde el nodo del lado del servidor:
main.js:
var unique = require('uniq'); function myFunction() { var data = [1, 2, 2, 4, 3]; return unique(data).toString(); } console.log ( myFunction() ); // When browserified - we can't call myFunction() from the HTML, so we'll externalize myExtFunction() // On the server-side "window" is undef. so we hide it. if (typeof window !== 'undefined') { window.myExtFunction = function() { return myFunction(); } }
main.html:
<html> <head> <script type='text/javascript' src="bundle.js"></script> <head> <body> Result: <span id="demo"></span> <script>document.getElementById("demo").innerHTML = myExtFunction();</script> </body> </html>
Correr:
y debería obtener los mismos resultados al abrir main.html en un navegador que al ejecutar
fuente
Ejemplo mínimo ejecutable
Esto es básicamente lo mismo que: https://stackoverflow.com/a/43215928/895245 pero con archivos concretos que le permitirán ejecutarlo y reproducirlo fácilmente usted mismo.
Este código también está disponible en: https://github.com/cirosantilli/browserify-hello-world
index.js
const uniq = require('uniq'); function myfunc() { return uniq([1, 2, 2, 3]).join(' '); } exports.myfunc = myfunc;
index.html
<!doctype html> <html lang=en> <head> <meta charset=utf-8> <title>Browserify hello world</title> </head> <body> <div id="container"> </body> </div> <script src="out.js"></script> <script> document.getElementById('container').innerHTML = browserify_hello_world.myfunc(); </script> </html>
Uso de Node.js:
#!/usr/bin/env node const browserify_hello_world = require('./index.js'); console.log(browserify_hello_world.myfunc());
Generar
out.js
para uso del navegador:Tanto el navegador como la línea de comandos muestran el resultado esperado:
1 2 3
Probado con Browserify 16.5.0, Node.js v10.15.1, Chromium 78, Ubuntu 19.10.
fuente
exports.myfunc.= myfunc
parte de esto fue absolutamente crítica y se perdió en otras respuestas.es realmente simple: todo este concepto se trata de envolver
1. alternativa - objetar "esto"
para este propósito, asumiré que tiene "solo 1 secuencia de comandos para toda la aplicación {{app_name}}" y "1 función {{function_name}}"
agregar la función {{function_name}} para objetar "esto"
function {{function_name}}(param) {} -> this.{{function_name}} = function(param) {}
luego debe nombrar ese objeto para que esté disponible; lo hará agregue el parámetro "independiente con nombre" como otros aconsejaron
por lo que si usa "watchify" con "browserify", use este
var b = browserify({ ... standalone: '{{app_name}}' });
o línea de comando
entonces puedes llamar a tu función desde el navegador
{{app_name}}.{{function_name}}(param); window.{{app_name}}.{{function_name}}(param);
2. alternativa - objeto "ventana"
agregar la función {{function_name}} al objeto "ventana"
function {{function_name}}(param) {} -> window.{{function_name}} = function(param) {}
entonces puedes llamar a tu función desde el navegador
{{function_name}}(param); window.{{function_name}}(param);
-
tal vez ayude a alguien
fuente
Tienes pocas opciones:
Deje que el plugin browserify-bridge exporte automáticamente los módulos a un módulo de entrada generado. Esto es útil para proyectos de SDK o situaciones en las que no tiene que mantenerse al día manualmente con lo que se exporta.
Siga un patrón de pseudo-espacio de nombres para la exposición acumulada:
Primero, organice su biblioteca de esta manera, aprovechando las búsquedas de índices en carpetas:
Con este patrón, define una entrada como esta:
exports.Helpers = require('./helpers'); exports.Providers = require('./providers'); ...
En sus subcarpetas, puede incluir un manifiesto similar de los módulos disponibles en ese contexto:
exports.SomeHelper = require('./someHelper');
Este patrón se escala realmente bien y permite un seguimiento contextual (carpeta por carpeta) de lo que se debe incluir en la API acumulada.
fuente
window.LogData =function(data){ return unique(data); };
Llame a la función simplemente por
LogData(data)
Esta es solo una pequeña modificación a la respuesta de thejh, pero es importante
fuente
Para fines de depuración, agregué esta línea a mi code.js:
window.e = function(data) {eval(data);};
Entonces podría ejecutar cualquier cosa incluso fuera del paquete.
e("anything();");
fuente