Gibt es in JavaScript etwas Ähnliches wie @import
in CSS, mit der Sie eine JavaScript-Datei in eine andere JavaScript-Datei einfügen können?
Antworten
Zu viele Anzeigen?Ja, Es gibt...
Lesen Sie weiter. Unter ES6 können wir export
y import
einen Teil oder eine ganze JavaScript-Datei in eine andere Datei zu kopieren...
Doch halt, ES6 wird nicht von allen Browsern unterstützt, daher müssen Sie es mit babel.js
zum Beispiel...
Sie erstellen also eine Klasse wie unten:
class Person {
constructor(name) {
this.name = name;
}
build() {
return new Person(this);
}
}
module.exports = Person;
En eine andere JavaScript-Datei, importieren Sie wie folgt:
import { Person } from 'Person';
Sie können die Datei auch wie folgt anfordern:
const Person = require('./Person');
Wenn Sie eine ältere JavaScript-Version verwenden, können Sie requirejs :
requirejs(["helper/util"], function(util) {
// This function is called when scripts/helper/util.js is loaded.
// If util.js calls define(), then this function is not fired until
// util's dependencies have loaded, and the util argument will hold
// the module value for "helper/util".
});
Wenn Sie bei älteren Versionen bleiben wollen, wie jQuery können Sie auch etwas verwenden wie getScript :
jQuery.getScript('./another-script.js', function() {
// Call back after another-script loaded
});
Zu guter Letzt sollten Sie nicht vergessen, dass Sie ein Skript auch auf herkömmliche Weise zusammenstellen können, indem Sie die <script>
Tag...
<script src="./first-script.js"></script>
<script src="./second-script.js"></script>
<script src="./third-script.js"></script>
Außerdem gibt es die asynchron y aufschieben. Eigenschaften, die ich hier erwähnen sollte...
Anmerkung: Es gibt mehrere Möglichkeiten, ein externes Skript auszuführen:
- Wenn async vorhanden ist: Das Skript wird asynchron ausgeführt mit dem Rest der Seite ausgeführt (das Skript wird ausgeführt, während die Seite das Parsing fortsetzt)
- Wenn async nicht vorhanden ist und defer ist vorhanden: Das Skript wird ausgeführt, wenn die Seite das Parsen
- Wenn weder async noch defer vorhanden ist: Das Skript ist geholt und sofort ausgeführt, bevor der Browser mit dem die Seite weiter analysiert
Auf diese Frage gibt es eine Vielzahl von möglichen Antworten. Meine Antwort basiert offensichtlich auf einer Reihe von ihnen. Nachdem ich mir alle Antworten durchgelesen habe, bin ich zu dieser Antwort gekommen.
Das Problem mit $.getScript
und wirklich jede andere Lösung, die einen Rückruf erfordert, wenn das Laden abgeschlossen ist, ist, dass, wenn Sie mehrere Dateien haben, die es verwenden und voneinander abhängen Sie nicht mehr eine Möglichkeit zu wissen, wenn alle Skripte geladen wurden (sobald sie in mehreren Dateien verschachtelt sind).
Beispiel:
file3.js
var f3obj = "file3";
// Define other stuff
file2.js:
var f2obj = "file2";
$.getScript("file3.js", function(){
alert(f3obj);
// Use anything defined in file3.
});
file1.js:
$.getScript("file2.js", function(){
alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
alert(f2obj);
// Use anything defined in the loaded script...
});
Sie haben Recht, wenn Sie sagen, dass Sie Ajax angeben könnten, um synchron zu laufen oder XMLHttpRequest aber der aktuelle Trend scheint zu sein, synchrone Anfragen zu verwerfen, so dass Sie möglicherweise keine vollständige Browserunterstützung jetzt oder in Zukunft erhalten.
Sie könnten versuchen, Folgendes zu verwenden $.when
um ein Array von Deferred Objects zu prüfen, aber jetzt tun Sie dies in jeder Datei und Datei2 wird als geladen betrachtet, sobald die $.when
wird nicht ausgeführt, wenn der Rückruf ausgeführt wird, so dass Datei1 noch weiter ausgeführt wird, bevor Datei3 geladen wird. Das Problem ist immer noch das gleiche.
Ich beschloss, rückwärts zu gehen, anstatt vorwärts. Dankeschön document.writeln
. Ich weiß, es ist ein Tabu, aber solange es richtig angewendet wird, funktioniert es gut. Am Ende hat man einen Code, der leicht zu debuggen ist, der im DOM korrekt angezeigt wird und der die richtige Reihenfolge der Abhängigkeiten gewährleistet.
Sie können natürlich $ ("body").append() verwenden, aber dann können Sie nicht mehr richtig debuggen.
HINWEIS: Sie dürfen diese Funktion nur verwenden, während die Seite geladen wird, da Sie sonst einen leeren Bildschirm erhalten. Mit anderen Worten, immer vor / außerhalb von document.ready platzieren . Ich habe nicht getestet, dies zu verwenden, nachdem die Seite in einem Klick-Ereignis oder etwas Ähnliches geladen wurde, aber ich bin ziemlich sicher, dass es fehlschlagen wird.
Ich mochte die Idee, jQuery zu erweitern, aber offensichtlich muss man das nicht.
Vor dem Anruf document.writeln
überprüft es, ob das Skript nicht bereits geladen wurde, indem es alle Skriptelemente auswertet.
Ich gehe davon aus, dass ein Skript erst dann vollständig ausgeführt ist, wenn seine document.ready
Ereignis ausgeführt wurde. (Ich weiß, dass die Verwendung von document.ready
ist nicht erforderlich, aber viele Leute benutzen es, und die Handhabung ist eine Absicherung).
Wenn die zusätzlichen Dateien geladen sind, wird die document.ready
Callbacks werden in der falschen Reihenfolge ausgeführt. Um dieses Problem zu beheben, wird beim Laden eines Skripts das Skript, das es importiert hat, selbst erneut importiert und die Ausführung angehalten. Dies führt dazu, dass die ursprüngliche Datei nun ihre document.ready
Callback, der nach jedem von ihm importierten Skript ausgeführt wird.
Anstelle dieses Ansatzes könnten Sie versuchen, die jQuery readyList
aber das schien eine schlechtere Lösung zu sein.
Lösung:
$.extend(true,
{
import_js : function(scriptpath, reAddLast)
{
if (typeof reAddLast === "undefined" || reAddLast === null)
{
reAddLast = true; // Default this value to true. It is not used by the end user, only to facilitate recursion correctly.
}
var found = false;
if (reAddLast == true) // If we are re-adding the originating script we do not care if it has already been added.
{
found = $('script').filter(function () {
return ($(this).attr('src') == scriptpath);
}).length != 0; // jQuery to check if the script already exists. (replace it with straight JavaScript if you don't like jQuery.
}
if (found == false) {
var callingScriptPath = $('script').last().attr("src"); // Get the script that is currently loading. Again this creates a limitation where this should not be used in a button, and only before document.ready.
document.writeln("<script type='text/javascript' src='" + scriptpath + "'></script>"); // Add the script to the document using writeln
if (reAddLast)
{
$.import_js(callingScriptPath, false); // Call itself with the originating script to fix the order.
throw 'Readding script to correct order: ' + scriptpath + ' < ' + callingScriptPath; // This halts execution of the originating script since it is getting reloaded. If you put a try / catch around the call to $.import_js you results will vary.
}
return true;
}
return false;
}
});
Verwendung:
Datei3:
var f3obj = "file3";
// Define other stuff
$(function(){
f3obj = "file3docready";
});
Datei2:
$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
f2obj = "file2docready";
});
Datei1:
$.import_js('js/file2.js');
// Use objects from file2 or file3
alert(f3obj); // "file3"
alert(f2obj); // "file2"
$(function(){
// Use objects from file2 or file3 some more.
alert(f3obj); //"file3docready"
alert(f2obj); //"file2docready"
});
Außerdem gibt es Kopf.js . Es ist sehr einfach, damit umzugehen:
head.load("js/jquery.min.js",
"js/jquery.someplugin.js",
"js/jquery.someplugin.css", function() {
alert("Everything is ok!");
});
Wie Sie sehen, ist es einfacher als Require.js und so bequem wie jQuery's $.getScript
Methode. Außerdem verfügt es über einige fortgeschrittene Funktionen, wie bedingtes Laden, Merkmalserkennung und viel mehr .
Nur für Node.js hat das für mich am besten funktioniert!
Ich habe die meisten Lösungen hier ausprobiert, aber keine hat mir geholfen, einfach eine andere Datei zu laden, ohne den Bereich zu ändern. Schließlich habe ich dies verwendet. Damit bleibt der Geltungsbereich und alles andere erhalten. Es ist so gut wie Ihr Code ist in diesem Punkt.
const fs = require('fs');
eval(fs.readFileSync('file.js') + '');
Hier ist ein Workaround für Browser (nicht Node.js) unter Verwendung von HTML-Importen.
Erstens sind alle JavaScript-Klassen und -Skripte nicht in .js
Dateien, sondern in .js.html
Dateien (die .js . html
nur zwischen HTML-Seiten und vollständigen JavaScript-Skripten/Klassen zu unterscheiden), innerhalb <script>
Tags, etwa so:
MyClass.js.html
:
<script>
class MyClass {
// Your code here..
}
</script>
Wenn Sie dann Ihre Klasse importieren möchten, müssen Sie nur HTML-Importe verwenden:
<link rel="import" href="relative/path/to/MyClass.js.html"/>
<script>
var myClass = new MyClass();
// Your code here..
</script>
EDIT: Die HTML-Importe werden gestrichen.
HTML-Importe werden zugunsten von ES6-Modulen fallen gelassen. Sie sollten ES6-Module verwenden.
3 Stimmen
MDN-Dokumente über JavaScript-Module con entsprechende Beispiele auf github
0 Stimmen
Meine Antwort hier stackoverflow.com/a/72335692/9868445 wurde anonym und ohne Angabe von Gründen heruntergestuft, aber ich empfehle trotzdem einen Blick darauf zu werfen.