ulmendorff: Kapselung von JS-Bibliotheken

Hallo,

ich habe Javascript Code in einer anonymen Funktion gekapselt.

(function (w, d, u) {  
 ...  
})();

nun soll dies auf einer fremden Seite eingebunden werden. Für die Einbindung dort besteht die Vorgabe, das auch sämtliche verwendeten Bibliotheken gekapselt werden sollen, so dass sich nichts im globalen Namensraum befindet.

Nun die Frage: Wie binde ich bspw. jQuery entsprechend ein, bzw. unter welchen Schlagworten finde ich etwas dazu?

vg ulmendorff

  1. Hallo,

    Wie binde ich bspw. jQuery entsprechend ein, bzw. unter welchen Schlagworten finde ich etwas dazu?

    Die meisten Bibliotheken schnappen sich automatisch einen globalen Bezeichner. Bei jQuery kann man das Setzen von window.$ und window.jQuery nur rückgängig machen:

    https://api.jquery.com/jQuery.noConflict/

    (function() {  
      var $ = jQuery.noConflict(true);})();
    

    Hier musst du aber beachten, dass die meisten Scripte, die auf jQuery aufbauen, ein globales window.$ benötigen (wie auch in o.g. Doku beschrieben). Wenn du einmal jQuery.noConflict(true) aufgerufen hast, ist deine jQuery-Versoin nur noch in der obigen Funktion verfügbar. Eine andere, vorher geladene Version kann weiterhin existieren.

    Was andere Bibliotheken angeht, so müsstest du in deren Referenzen nachsehen.

    Generell löst man solche Probleme durch die Nutzung eines Modulformats wie AMD oder CommonJS. Dabei sind sämtliche Scripte gekapselt, können nicht kollidieren und mehrere jQuery-Versionen wären kein Problem.

    Mathias

    1. Hallo,

      Generell löst man solche Probleme durch die Nutzung eines Modulformats wie AMD oder CommonJS. Dabei sind sämtliche Scripte gekapselt, können nicht kollidieren und mehrere jQuery-Versionen wären kein Problem.

      danke für die zielführende Lösung (im Gegensatz zum Beitrag von hotti, was ist denn das für einer?).
      Alle Bibilotheken werden erfolgreich mittels requirejs eingebunden.

      Nun habe ich noch ein Problem an dem ich hänge. Die neue Vorgabe ist nun, alles muss in eine Datei. Kann ich das auch mit requirejs lösen? Ich habe nur Beispiele gefunden, um externe Biblietheken zu laden...

      vg ulmendorff

      1. Hallo,

        Die neue Vorgabe ist nun, alles muss in eine Datei. Kann ich das auch mit requirejs lösen?

        Ja, mit dem Packaging-Tool r.js, das unter Node.js läuft.
        http://requirejs.org/docs/optimization.html

        Mathias

  2. hi,

    ich habe Javascript Code in einer anonymen Funktion gekapselt.

    Möglicherweise interessant: new

    Horst Oifach

    1. Meine Herren!

      ich habe Javascript Code in einer anonymen Funktion gekapselt.

      Möglicherweise interessant: new

      Er hat sein Skript in einem IIFE (Immediately-Invoked Function Expression) gekapselt, um den globalen Namenspace nicht zu zu müllen. Das ist ein Best Practice und hat nichts mit Instanziierung zu tun.

      molily erklärt die Welt.

      --
      “All right, then, I'll go to hell.”
      1. hi,

        Er hat sein Skript in einem IIFE (Immediately-Invoked Function Expression) gekapselt, um den globalen Namenspace nicht zu zu müllen. Das ist ein Best Practice und hat nichts mit Instanziierung zu tun.

        Jaja, schon klar, OOP ist die Lehre der Polymorphie von Säugetieren, Fischen und Schwanzlurchen und eine damit verbundene Kapselung der Daten lässt sich nur über schwer verständliche Design-Patterns lösen ;)

        SCNR;
        Listiger Lurch

        1. Meine Herren!

          Er hat sein Skript in einem IIFE (Immediately-Invoked Function Expression) gekapselt, um den globalen Namenspace nicht zu zu müllen. Das ist ein Best Practice und hat nichts mit Instanziierung zu tun.

          Jaja, schon klar, OOP ist die Lehre der Polymorphie von Säugetieren, Fischen und Schwanzlurchen und eine damit verbundene Kapselung der Daten lässt sich nur über schwer verständliche Design-Patterns lösen ;)

          Hier geht es nicht um einen objekt-orientierten Entwurf, sondern ausschließlich um Kapselung. Und JavaScript hat bis dato ausschließlich function-Scope. Wenn wir also alle unsere Variablen innerhalb einer Funktion deklarieren, bleibt die Umwelt unangetastet. Mit Objektorientierung hat das wirklich nichts zu tun. In dem IIFE könnte auch rein prozeduraler Code stehen.

          --
          “All right, then, I'll go to hell.”
          1. Aber mein Herr,

            Hier geht es nicht um einen objekt-orientierten Entwurf, sondern ausschließlich um Kapselung.

            Ach was, wenn es im Programm nur um die Eier geht, isses doch völlig egal, ob das Heck zu einem Huhn oder einem gewöhnlichen Saurier gehört ;)

            SCNR;

            1. Meine Herren!

              Ach was, wenn es im Programm nur um die Eier geht, isses doch völlig egal, ob das Heck zu einem Huhn oder einem gewöhnlichen Saurier gehört ;)

              Du missverstehst die Problematik: es gibt hier kein ODER. Ein IIFE ist die EINZIGE Möglichkeit den globalen Namespace nicht zu belasten.

              --
              “All right, then, I'll go to hell.”
              1. Hallo,

                Du missverstehst die Problematik: es gibt hier kein ODER. Ein IIFE ist die EINZIGE Möglichkeit den globalen Namespace nicht zu belasten.

                Ich warte ja schon gespannt auf hottis neues JS-FW...

                Viel Grüße
                Siri

                1. Moin,

                  Ich warte ja schon gespannt auf hottis neues JS-FW...

                  Zeige mir Dein Framework!

                  Zeige mir Deine Lösung für das hier, mit denselben zwei Videos, der kleinen Grafik und den Texten zusammen in einer Ajax-Response. Du darfst dazu die Videos auf Deinen Server kopieren.

                  Ich gebe Dir zwei Stunden Zeit, ich selbst habe ich dafür nur eine Stunde gebraucht.

                  Also dann, bis nachher um 11 Uhr.

                  Grüße an alle Heckenschützen,
                  Horst

                  1. Meine Herren!

                    Ich warte ja schon gespannt auf hottis neues JS-FW...

                    Zeige mir Dein Framework!

                    Zeige mir deins :P

                    Zeige mir Deine Lösung für das hier, mit denselben zwei Videos, der kleinen Grafik und den Texten zusammen in einer Ajax-Response. Du darfst dazu die Videos auf Deinen Server kopieren.

                    Diese Lösung würde ich so nie umsetzen, das hat mehrere Gründe:

                    • Die Ressourcen, die bei dir durch einen Response geschickt werden, sind für den Benutzer nicht intuitiv verlinkbar.

                    • Die Lösung ist alles andere als robust, in meinem Smartphone-Browser (Chrome 32) passiert nichts. (Übrigens zerstört der riesige Werbebanner da oben, dein responsives Design. Ich empfehle dir sowieso keine Werbung auf einer Seite zu schalten, die du auch geschäftlich nutzt).

                    • Das Datenvolumen, das eingespart wird – und ich glaube, das ist die Aufgabe hier – ist alles andere als vielversprechend. Dazu kommen hohe Armortisierungskosten, die durch den Overhead entstehen, den du erst verursachst.

                    • Ich muss für jeden Multipart-Request serverseitigen und clientseitigen Code schreiben, das widerspricht den Prinzipien von skalierbarer Software.

                    Also nochmal: nette Spielerei, aber kein System, das man im Produktiveinsatz haben möchte.

                    --
                    “All right, then, I'll go to hell.” – Huck Finn
                    1. Aber mein Herr,

                      Also nochmal: nette Spielerei, aber kein System, das man im Produktiveinsatz haben möchte.

                      Ich würde das eher als eine Studie bezeichnen. Also:

                      Zeige mit Deine Lösung, die mit denselben Inhalten (s.*) dasselbe tut und teile mir bitte mit, wie lange Du dafür brauchst, das umzusetzen.

                      Dann können wir vergleichen.

                      Horst

                      *) Download Link ist eingebaut, musst nur über den Link "random access" umschalten. Ansonsten einfach die Webadresse (Blob-Url) kopieren und in einem eigenen Browserfenster dergleichen Sitzung öffnen. Die Grafik hat eine Länge von 522 byte, die Videos jeweils knapp über 1MB. Und die Texte darfste auch kopieren ;)

                      PS: Für einen Produktiveinsatz käme BSON/MongoDB in Frage, vorausgesetzt, die Bibliotheken sind verfügbar.

                      1. Nochwas,

                        bevor Du beginnst....

                        Ich würde das eher als eine Studie bezeichnen. Also:

                        Zeige mit Deine Lösung, die mit denselben Inhalten (s.*) dasselbe tut und teile mir bitte mit, wie lange Du dafür brauchst, das umzusetzen.

                        Dann können wir vergleichen.

                        .... dieselbe Datei, welche in der Ajax-Response gesendet wird, soll unverändert auch lokal funktionieren: Entweder über ein input type file oder Drag&Drop auf ein canvas-Element.

                        Horst

                        --
                        Ein Kritiker ist wie eine Henne, die gackert, wenn andere Hühner Eier legen (Danke Erich v.D.)
                      2. Meine Herren!

                        Zeige mit Deine Lösung, die mit denselben Inhalten (s.*) dasselbe tut und teile mir bitte mit, wie lange Du dafür brauchst, das umzusetzen.

                        Dann können wir vergleichen.

                        Auf diesen sportlichen Vergleich lasse ich mich nicht ein (sportlich im Sinne von Schwanz). Ich finde dein Entwurf hat deutliche technische Mängel, die ich schon erläutert habe. Diesen Entwurf als Grundlage für eine Heuristik zu wählen, die die Produktivität von Entwicklern vergleicht, ist absolut kontraproduktiv.

                        --
                        “All right, then, I'll go to hell.” – Huck Finn
                      3. Zeige mit Deine Lösung, die mit denselben Inhalten (s.*) dasselbe tut und teile mir bitte mit, wie lange Du dafür brauchst, das umzusetzen.

                        Wieso sollte das irgendwer tun? Wer hat ein Interesse daran? Wirst du für die Umsetzung bezahlen?

                        Dann können wir vergleichen.

                        Was vergleichen? Wieso? Mit welcher Erkenntnis?

                        Sieh es doch ein: Du hast den Wettbewerb längst gewonnen. Für dein obskures ausgedachtes Problem gibt es keine bessere Lösung als die deine, und du setzt sie am schnellsten um.

                        Glückwünsche
                        Mathias

                        1. hi,

                          Sieh es doch ein: Du hast den Wettbewerb längst gewonnen. Für dein obskures ausgedachtes Problem gibt es keine bessere Lösung als die deine, und du setzt sie am schnellsten um.

                          Naja, hierfür, Inhalte einer lokalen DB im Browser darstellen habe ich ein bischen länger gebraucht. Und es gibt mit Sicherheit andere Lösungen und an meinem Code noch Einiges zu verbessern (Fehlerbehandlung usw..).

                          Mir gehts darum, mit kleinen Basteleien die großen Dinge zu verstehen und selbstverständlich auch die neuen Features der Browser, neue DOM-Objekte und XHR2.

                          Jeder Profi hat mal ganz klein angefangen und verdient Achtung sowie Respekt. Letzteres habe ich bis gestern noch mit Dir in Verbindung gebacht, seit Deiner hier getroffenen Äußerung erscheint mir das als total unwichtig.

                          Schöne Grüße.

                          1. Hallo!

                            Mir gehts darum, mit kleinen Basteleien die großen Dinge zu verstehen …

                            Jeder Profi hat mal ganz klein angefangen und verdient Achtung sowie Respekt.

                            Ich habe nichts gegen solche Basteleien, sondern finde sie zum Verständnis ebenfalls sinnvoll.

                            Was ich nicht verstehe, ist der »Battle«, der hier angezettelt wurde.

                            Mathias

              2. Ein IIFE ist die EINZIGE Möglichkeit den globalen Namespace nicht zu belasten.

                Manche schreiben ja

                new function() {};

                anstatt

                (function() {})();

                was vor allem beim Revealing Module Pattern sinnvoll sein kann

                var Module = new function() {  
                  var private = 1;  
                  var public = function() { alert(private) };  
                  this.foo = public;  
                };
                

                vs.

                var Module = (function() {  
                  var private = 1;  
                  var public = function () {};  
                  return {  
                    foo: public  
                  };  
                })();
                

                Ich finde »new« hier verwirrend (eigentlich ist es überall verwirrend, wenn man nicht ECMAScript-Interna kennt), daher bevorzuge ich die explizite Variante der IIFE.

                Mathias

                1. Meine Herren!

                  Manche schreiben ja

                  new function() {};

                  anstatt

                  (function() {})();

                  Danke für die Aufklärung. Die Schreibweise ist mir auch schon häufiger begegnet, findet aber in meinem aktiven JavaScript-Wortschatz keine Anwendung.

                  --
                  “All right, then, I'll go to hell.” – Huck Finn
  3. Nun die Frage: Wie binde ich bspw. jQuery entsprechend ein?

    (function ($, w, d, u) {
     ...
    })(jQuery, window, document, void(0)/*undefined*/);

    siehe hier: JSFiddle

    gruss

    chucky

    1. Meine Herren!

      Nun die Frage: Wie binde ich bspw. jQuery entsprechend ein?

      (function ($, w, d, u) {
      ...
      })(jQuery, window, document, void(0)/*undefined*/);

      Neey, da lebt dann doch offensichtlich eine jQuery-Variable im globalen Namensraum, das gilt es doch zu vermeiden.

      --
      “All right, then, I'll go to hell.” – Huck Finn
      1. entschuldige :)

        //require.js

        define(['jquery'],function($){
             $(function(){
                 console.log('local scope!');
             });
        });