JavaScript erfordert () auf der Clientseite

83

Ist es möglich, require()auf Client-Seite zu verwenden (oder etwas Ähnliches)?

Beispiel

var myClass = require('./js/myclass.js');
Debra Maddux
quelle

Antworten:

41

Sie sollten dafür in require.js oder head.js nachsehen .

Andrew Hare
quelle
5
@Debra: Warum gehen Sie nicht zum Abschnitt "Nutzung" auf ihrer Website?
Leichtigkeitsrennen im Orbit
2
Werfen Sie einen Blick auf Require () , wenn Sie eine leichtere Lösung als require.js, head.js oder Lab.js wünschen.
Torben
2
... oder heutzutage können Sie den clientseitigen Code mit einer Vielzahl von Tools wie Webpack bündeln
Aprillion
Beachten Sie bei der Verwendung von requirejs die folgenden Einschränkungen: stackoverflow.com/questions/29652716/… . Ansonsten funktioniert bei mir.
user180574
14

Wenn Sie den Node.js-Stil haben möchten, können Sie Folgendes requireverwenden:

var require = (function () {
    var cache = {};
    function loadScript(url) {
        var xhr = new XMLHttpRequest(),
            fnBody;
        xhr.open('get', url, false);
        xhr.send();
        if (xhr.status === 200 && xhr.getResponseHeader('Content-Type') === 'application/x-javascript') {
            fnBody = 'var exports = {};\n' + xhr.responseText + '\nreturn exports;';
            cache[url] = (new Function(fnBody)).call({});
        }
    }
    function resolve(module) {
        //TODO resolve urls
        return module;
    }
    function require(module) {
        var url = resolve(module);
        if (!Object.prototype.hasOwnProperty.call(cache, url)) {
            loadScript(url);
        }
        return cache[url];
    }
    require.cache = cache;
    require.resolve = resolve;
    return require;
}());

Achtung: Dieser Code funktioniert, ist jedoch unvollständig (insbesondere beim Auflösen von URLs) und implementiert nicht alle Funktionen von Node.js (ich habe ihn erst letzte Nacht zusammengestellt). SIE SOLLTEN DIESEN CODE NICHT in echten Apps verwenden, aber es gibt Ihnen einen Ausgangspunkt. Ich habe es mit diesem einfachen Modul getestet und es funktioniert:

function hello() {
    console.log('Hello world!');
}

exports.hello = hello;
Renaat De Muynck
quelle
3
Diese Antwort hat mir gefallen, weil sie keine Lösung ist. Ich hasse es wirklich, wenn Leute nur die Lösung geben. Geben Sie die Antwort, die ihnen hilft, beim nächsten Mal die Lösung zu finden. Gut gemacht!
Jasmine
13

Ich habe mir die gleichen Fragen gestellt. Als ich es mir ansah, fand ich die Auswahl überwältigend.

Glücklicherweise habe ich diese hervorragende Tabelle gefunden, die Ihnen bei der Auswahl des besten Laders basierend auf Ihren Anforderungen hilft:

https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxhYQ

serby
quelle
1
Ich frage mich, ob das Vorhandensein einer Tabelle mit Optionen bedeutet, dass wir als Entwickler noch keinen großartigen Weg gefunden haben, dies zu tun.
Costa
7

Ich habe festgestellt, dass es im Allgemeinen empfohlen wird, Skripte zur Kompilierungszeit vorzuverarbeiten und sie in einem (oder sehr wenigen) Paketen zu bündeln, wobei sie requireauch zur Kompilierungszeit in einen "Lightweight Shim" umgeschrieben werden.

Ich habe nach "neuen" Tools gegoogelt, die dazu in der Lage sein sollten

Und das bereits erwähnte browserifysollte auch ganz gut passen - http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/

Worum geht es in den Modulsystemen?

xmojmr
quelle
Und ermöglicht es neben der Bündelung auch die Verwendung von Knotenpaketen in diesem Bündel?
eran otzap
4

Sie können Elemente im DOM erstellen, das Elemente lädt.

Wie solche:

var myScript = document.createElement('script'); // Create new script element
myScript.type = 'text/javascript'; // Set appropriate type
myScript.src = './js/myclass.js'; // Load javascript file
Andre Backlund
quelle
4

Verwenden Sie einfach Browserify, einen Compiler, der Ihre Dateien verarbeitet, bevor sie in Produktion gehen, und die Datei in Bundles packt.

Stellen Sie sich vor, Sie haben eine main.js-Datei, für die die Dateien Ihres Projekts erforderlich sind. Wenn Sie browserify ausführen, werden einfach alle verarbeitet und ein Bundle mit all Ihren Dateien erstellt, sodass die requireAufrufe synchron im Browser ohne HTTP-Anforderungen und verwendet werden können Zum Beispiel mit sehr geringem Aufwand für die Leistung und die Größe des Bundles.

Weitere Informationen finden Sie unter dem Link: http://browserify.org/

Fernando Mota
quelle
Browserify wurde bereits 2011 von @dkastner erwähnt. Ich habe einige Alternativen in meiner Antwort gegoogelt, aber ich kenne die Lösung Nr. 1 noch nicht
xmojmr
2

Einige Antworten bereits - aber ich möchte Sie auf YUI3 und das Laden des On-Demand-Moduls hinweisen. Es funktioniert sowohl auf dem Server (node.js) als auch auf dem Client. Ich habe eine Demo-Website, die genau denselben JS-Code verwendet, der entweder auf dem Client oder auf dem Server ausgeführt wird, um die Seiten zu erstellen, aber das ist ein anderes Thema.

YUI3: http://developer.yahoo.com/yui/3/

Videos: http://developer.yahoo.com/yui/theater/

Beispiel:

(Voraussetzung: Die grundlegenden YUI3-Funktionen in 7k yui.js wurden geladen)

YUI({
    //configuration for the loader
}).use('node','io','own-app-module1', function (Y) {
    //sandboxed application code
    //...

    //If you already have a "Y" instance you can use that instead
    //of creating a new (sandbox) Y:
    //  Y.use('moduleX','moduleY', function (Y) {
    //  });
    //difference to YUI().use(): uses the existing "Y"-sandbox
}

Dieser Code lädt die YUI3-Module "node" und "io" sowie das Modul "own-app-module1" und führt dann die Rückruffunktion aus. Eine neue Sandbox "Y" mit allen Funktionen von YUI3 und own-app-module1 wird erstellt. Im globalen Namespace wird nichts angezeigt. Das Laden der Module (.js-Dateien) wird vom YUI3-Loader übernommen. Außerdem wird die Konfiguration (optional, hier nicht angezeigt) verwendet, um eine -debug- oder -min-Version (ified) der zu ladenden Module auszuwählen.

Mörre
quelle
1

Hier ist eine Lösung, die einen ganz anderen Ansatz verfolgt: Packen Sie alle Module in ein JSON-Objekt und benötigen Sie Module, indem Sie den Dateiinhalt ohne zusätzliche Anforderungen lesen und ausführen.

https://github.com/STRd6/require/blob/master/main.coffee.md

STRd6 / require hängt davon ab, ob zur Laufzeit ein JSON-Paket verfügbar ist. Die requireFunktion wird für dieses Paket generiert. Das Paket enthält alle Dateien, die Ihre App möglicherweise benötigt. Es werden keine weiteren http-Anforderungen gestellt, da das Paket alle Abhängigkeiten bündelt. Dies ist so nah wie möglich an dem Node.js-Stil, den der Client benötigt.

Die Struktur des Pakets ist wie folgt:

entryPoint: "main"
distribution:
  main: 
    content: "alert(\"It worked!\")"
  ...
dependencies:
  <name>: <a package>

Im Gegensatz zu Node kennt ein Paket seinen externen Namen nicht. Es ist Sache des Pakets, einschließlich der Abhängigkeit, es zu benennen. Dies bietet eine vollständige Kapselung.

Angesichts all dieser Einstellungen ist hier eine Funktion, die eine Datei aus einem Paket lädt:

loadModule = (pkg, path) ->
  unless (file = pkg.distribution[path])
    throw "Could not find file at #{path} in #{pkg.name}" 

  program = file.content
  dirname = path.split(fileSeparator)[0...-1].join(fileSeparator)

  module =
    path: dirname
    exports: {}

  context =
    require: generateRequireFn(pkg, module)        
    global: global
    module: module
    exports: module.exports
    PACKAGE: pkg
    __filename: path
    __dirname: dirname

  args = Object.keys(context)
  values = args.map (name) -> context[name]

  Function(args..., program).apply(module, values)

  return module

Dieser externe Kontext bietet eine Variable, auf die Module Zugriff haben.

Eine requireFunktion ist Modulen ausgesetzt, sodass sie möglicherweise andere Module benötigen.

Zusätzliche Eigenschaften wie ein Verweis auf das globale Objekt und einige Metadaten werden ebenfalls angezeigt.

Schließlich führen wir das Programm innerhalb des Moduls aus und geben den Kontext an.

Diese Antwort ist besonders hilfreich für diejenigen, die einen synchronen node.js-Stil benötigen, der eine Anweisung im Browser erfordert und nicht an Lösungen zum Laden von Remote-Skripten interessiert ist.

Daniel X Moore
quelle
1

Ich finde, dass das Komponentenprojekt einen wesentlich optimierten Workflow bietet als andere Lösungen (einschließlich require.js). Daher empfehle ich, https://github.com/component/component zu überprüfen . Ich weiß, dass dies eine etwas späte Antwort ist, aber für jemanden nützlich sein kann.

Zsolt Szatmari
quelle
0

Hier ist eine einfache Möglichkeit, Anforderungen und Exporte in Ihrem Webclient zu verwenden. Es ist ein einfacher Wrapper, der eine globale Variable "Namespace" erstellt, und Sie verpacken Ihren CommonJS-kompatiblen Code in eine "define" -Funktion wie folgt:

namespace.lookup('org.mydomain.mymodule').define(function (exports, require) {
    var extern = require('org.other.module');
    exports.foo = function foo() { ... };
});

Weitere Dokumente hier:

https://github.com/mckoss/namespace

mckoss
quelle
0

Die clientseitig erforderliche Bibliothek bietet eine asynchrone load()Funktion, mit der jede JS-Datei oder jedes NPM-Modul (das verwendet wird module.exports), jede .cssDatei, jede .json, jede .html, jede andere Datei als Text geladen werden kann .

z.B, npm install clientside-require --save

<script src = '/node_modules/clientside-require/dist/bundle.js'></script>
<script>
load('color-name') // an npm module
   .then(color_name=>{
        console.log(color_name.blue); // outputs  [0, 0, 255]
   })
</script>

Ein wirklich cooler Teil dieses Projekts ist, dass Sie in jedem load()ed-Skript die Synchronfunktion require()genauso verwenden können, wie Sie es in node.js erwarten würden!

z.B,

load('/path/to/functionality.js')

und innen /path/to/functionality.js:

var query_string = require("qs") // an npm module
module.exports = function(name){
    return qs.stringify({
         name:name,
         time:new Date()
    }
}

Dieser letzte Teil, der die synchrone require()Methode implementiert , ermöglicht es ihm, NPM-Pakete zu verwenden, die für die Ausführung auf dem Server erstellt wurden.


Dieses Modul wurde entwickelt, um die requireFunktionalität im Browser so genau wie möglich zu implementieren . Haftungsausschluss: Ich habe dieses Modul geschrieben.

Ulad Kasach
quelle
Gibt es irgendwo ein vollständiges Arbeitsbeispiel? Ich versuche, meine eigenen Klassen auf der Clientseite zu laden, und es wird nicht funktionieren.
Jallmer
-4

Ja, es ist sehr einfach zu bedienen, aber Sie müssen die Javascript-Datei per Skript-Tag in den Browser laden

<script src="module.js"></script> 

und dann Benutzer in js Datei wie

var moduel = require('./module');

Ich mache eine App mit Elektron und es funktioniert wie erwartet.

Manoj
quelle