web-dev-qa-db-fra.com

Browserify - Comment appeler une fonction intégrée dans un fichier généré par browserify dans le navigateur

Je suis nouveau sur nodejs et browserify. J'ai commencé avec ce link .

J'ai le fichier main.js qui contient ce code

var unique = require('uniq');

var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];

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

Maintenant, j'installe le module uniq avec npm:

 npm install uniq

Ensuite, je regroupe tous les modules requis à partir de main.js dans un seul fichier appelé bundle.js avec la commande browserify: 

browserify main.js -o bundle.js

Le fichier généré ressemble à ceci:

(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])

Après avoir inclus le fichier bundle.js dans ma page index.htm, comment appeler la fonction logData?

69
SharpCoder

Par défaut, browserify ne vous permet pas d'accéder aux modules en dehors du code browserified. Si vous souhaitez appeler du code dans un module browserified, vous êtes censé parcourir votre code avec le module. Voir http://browserify.org/ pour des exemples.

Bien sûr, vous pouvez aussi explicitement rendre votre méthode accessible de l’extérieur comme ceci:

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

Ensuite, vous pouvez appeler LogData() de n’importe où ailleurs sur la page.

64
thejh

L'option --s constitue l'élément clé du regroupement de modules autonomes avec Browserify. Il expose tout ce que vous exportez de votre module en utilisant le module.exports du nœud en tant que variable globale. Le fichier peut ensuite être inclus dans une balise <script>.

Vous ne devez le faire que si, pour une raison quelconque, vous avez besoin que cette variable globale soit exposée. Dans mon cas, le client avait besoin d'un module autonome pouvant être inclus dans les pages Web sans avoir à se soucier de l'activité de Browserify.

Voici un exemple d'utilisation de l'option --s avec un argument de module:

browserify index.js --s module > dist/module.js

Cela exposera notre module en tant que variable globale nommée module.
La source

Mise à jour: Merci à @fotinakis. Assurez-vous de transmettre --standalone your-module-name. Si vous oubliez que --standalone accepte un argument, il est possible que Browserify génère un module vide car il ne peut pas le trouver.

J'espère que cela vous fait gagner du temps.

83

Lisez le fichier README.md de browserify concernant le paramètre --standalone .__ ou Google

7
undoZen

Je viens de lire les réponses et il semble que personne ne mentionne l'utilisation de la portée de la variable globale? Ce qui est utile si vous voulez utiliser le même code dans node.js et dans le navigateur.

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

Ensuite, vous pouvez accéder à la TestClass n’importe où.

<script src="bundle.js"></script>
<script>
var test = new TestClass(); // Enjoy!
</script>

Remarque: La TestClass devient alors disponible partout. Ce qui revient à utiliser la variable window.

De plus, vous pouvez créer un décorateur qui expose une classe à la portée globale. Ce qui est vraiment gentil mais rend difficile de savoir où une variable est définie.

5
Azarus

Vous avez quelques options:

  1. Laissez le plugin browserify-bridge auto-exporter les modules vers un module d'entrée généré. Ceci est utile pour les projets SDK ou les situations dans lesquelles vous n'avez pas à suivre manuellement ce qui est exporté.

  2. Suivez un modèle de pseudo-espace de noms pour une exposition cumulative:

Commencez par organiser votre bibliothèque de la manière suivante, en tirant parti des recherches d'index dans les dossiers:

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

Avec ce modèle, vous définissez une entrée comme ceci:

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

Notez que require charge automatiquement le fichier index.js de chaque sous-dossier respectif.

Dans vos sous-dossiers, vous pouvez simplement inclure un manifeste similaire des modules disponibles dans ce contexte:

exports.SomeHelper = require('./someHelper');

Ce modèle évolue très bien et permet un suivi contextuel (dossier par dossier) de ce qu’il faut inclure dans l’API remontée.

1
deepelement

Pour que votre fonction soit disponible à partir du HTML et du nœud côté serveur:

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>

Run:

npm install uniq
browserify main.js > bundle.js

et vous devriez obtenir les mêmes résultats lors de l'ouverture de main.html dans un navigateur que lors de l'exécution

node main.js
0
Ori Miller

il me faut un certain temps comprendre et comprendre cette question, même avec ces réponses

c'est vraiment simple - c'est sur l'emballage

à cette fin, je suppose que vous n'avez qu'un script pour l'application entière {{app_name}}

1 alternative

ajouter une fonction à l'objet "this"

function somefunction(param) {}
->
this.somefunction = function(param) {}

alors vous devez nommer cet objet pour qu'il soit disponible - vous le ferez ajoutez param "standalone with name" comme les autres conseillés

donc, si vous utilisez "watchify" avec "browserify" use this

var b = browserify({
    ...
    standalone: '{{app_name}}'
});

ou ligne de commande

browserify index.js --standalone {{app_name}} > index-bundle.js

alors vous pouvez appeler votre fonction depuis le navigateur

app_name.somefunction(param);
window.app_name.somefunction(param);

2 alternative

ajouter une fonction à l'objet "fenêtre"

function somefunction(param) {}
->
window.somefunction = function(param) {}

alors vous pouvez appeler votre fonction depuis le navigateur

somefunction(param);
window.somefunction(param);

-

peut-être j'aide quelqu'un

0
BG Bruno