Browserify: cómo llamar a la función incluida en un archivo generado a través de browserify en el navegador

Soy nuevo en nodejs y browserify. Comencé 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 agrupé todos los módulos requeridos comenzando en main.js en un único 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 puedo llamar a la función logData?

De manera predeterminada, browserify no le permite acceder a los módulos desde fuera del código de browserified. Si desea llamar a un código en un módulo de browserified, se supone que debe buscar su código junto con el módulo. Vea http://browserify.org/ para ejemplos de eso.

Por supuesto, también puede hacer que su método sea accesible de forma explícita de esta manera:

 window.LogData =function(){ console.log(unique(data)); }; 

Luego puedes llamar a LogData() desde cualquier otro lugar de la página.

La parte clave de agrupar módulos independientes con Browserify es la opción --s . Expone todo lo que exporta desde su módulo utilizando el módulo module.exports como una variable global. El archivo se puede incluir en una etiqueta .

Solo necesita hacer esto si, por algún motivo, necesita que se exponga esa variable global. En mi caso, el cliente necesitaba un módulo independiente que pudiera incluirse en las páginas web sin que ellos tuvieran que preocuparse por este negocio de Browserify.

Aquí hay un ejemplo donde usamos la opción --s con un argumento de module :

 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 que estás pasando --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 tiempo.

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 han señalado otros, contamina el espacio de nombres global, por lo que no es lo ideal). Quería agregar un poco más de detalles sobre cómo usar la opción independiente.

En el script de origen que desea agrupar, 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 a través de . . Aquí hay un ejemplo:

Mi archivo fuente src / script.js tendrá esto:
module.exports = {myFunc: func};

El comando de mi navegador se verá así:
browserify src/script.js --standalone myBundle > dist/bundle.js

Y mi script de cliente dist / client.js cargará el script empaquetado

y luego llamar a la función expuesta como esta:


No es necesario requerir el nombre del paquete en el script del cliente antes de llamar a las funciones expuestas, por ejemplo, no es necesario y no funcionará.

De hecho, al igual que todas las funciones incluidas en browserify sin modo independiente, la función require no estará disponible fuera del script incluido . Browserify le permite usar algunas funciones de Nodo del lado del cliente, pero solo en la secuencia de comandos incluida ; no tiene la intención de crear un módulo independiente que pueda importar y usar en cualquier parte del lado del cliente, por lo que tenemos que hacer frente a todos estos problemas adicionales solo para llamar a una función fuera del contexto de su paquete.

Lea el archivo README.md de browserify sobre el parámetro --standalone o google “browserify umd”

Acabo de leer las respuestas y parece que nadie mencionó el uso del ámbito de variable global. Lo que es útil si desea utilizar el mismo código en node.js y en el navegador.

 class Test { constructor() { } } global.TestClass = Test; 

Luego puedes acceder al TestClass en cualquier lugar.

   

Nota: El TestClass luego 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 que es realmente bueno, pero hace que sea difícil rastrear dónde se define una variable.

Tienes pocas opciones:

  1. Permitir 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 continuar manualmente con lo que se exporta.

  2. 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 índice en las carpetas:

 /src --entry.js --/helpers --- index.js --- someHelper.js --/providers --- index.js --- someProvider.js ... 

Con este patrón, se define una entrada como esta:

 exports.Helpers = require('./helpers'); exports.Providers = require('./providers'); ... 

Observe que el requerimiento carga automáticamente el index.js de cada subcarpeta respectiva

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 incluirá en la API enrollada.

Para propósitos de depuración, agregué esta línea a mi code.js:

 window.e = function(data) {eval(data);}; 

Entonces podría correr cualquier cosa, incluso fuera del paquete.

 e("anything();"); 
 window.LogData =function(data){ return unique(data); }; 

Llame a la función simplemente por LogData(data)

Esto es solo una pequeña modificación de la respuesta de thejh pero importante