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?Die alten Versionen von JavaScript hatten kein import, include oder require, so dass viele verschiedene Ansätze für dieses Problem entwickelt wurden.
Aber seit 2015 (ES6) hat JavaScript die ES6-Module Standard für den Import von Modulen in Node.js, der auch von die meisten modernen Browser .
Um die Kompatibilität mit älteren Browsern zu gewährleisten, können Sie Tools wie Webpack y Rollup und/oder Transpilierungswerkzeuge wie Babel verwendet werden können.
ES6-Module
ECMAScript (ES6)-Module wurden unterstützt in Node.js seit v8.5, mit dem --experimental-modules
Flag, und seit mindestens Node.js v13.8.0 ohne dieses Flag. Um "ESM" zu aktivieren (im Gegensatz zu Node.js' früherem Modulsystem im CommonJS-Stil ["CJS"]), verwenden Sie entweder "type": "module"
en package.json
oder geben Sie den Dateien die Erweiterung .mjs
. (In ähnlicher Weise können Module, die mit dem früheren CJS-Modul von Node.js geschrieben wurden, den Namen .cjs
wenn Ihr Standard ESM ist).
Verwendung von package.json
:
{
"type": "module"
}
Entonces module.js
:
export function hello() {
return "Hello";
}
Entonces main.js
:
import { hello } from './module.js';
let val = hello(); // val is "Hello";
Verwendung von .mjs
hätten Sie module.mjs
:
export function hello() {
return "Hello";
}
Entonces main.mjs
:
import { hello } from './module.mjs';
let val = hello(); // val is "Hello";
ECMAScript-Module in Browsern
Browser haben Unterstützung für das direkte Laden von ECMAScript-Modulen (keine Tools wie Webpack erforderlich) seit Safari 10.1, Chrome 61, Firefox 60 und Edge 16. Prüfen Sie die aktuelle Unterstützung unter caniuse . Es besteht keine Notwendigkeit, Node.js zu verwenden. .mjs
Erweiterung; Browser ignorieren die Dateierweiterungen von Modulen/Skripten vollständig.
<script type="module">
import { hello } from './hello.mjs'; // Or the extension could be just `.js`
hello('world');
</script>
// hello.mjs -- or the extension could be just `.js`
export function hello(text) {
const div = document.createElement('div');
div.textContent = `Hello ${text}`;
document.body.appendChild(div);
}
Lesen Sie mehr unter https://jakearchibald.com/2017/es-modules-in-browsers/
Dynamische Importe in Browsern
Durch dynamische Importe kann das Skript bei Bedarf andere Skripte laden:
<script type="module">
import('hello.mjs').then(module => {
module.hello('world');
});
</script>
Lesen Sie mehr unter https://developers.google.com/web/updates/2017/11/dynamic-import
Node.js erfordern
Der ältere CJS-Modul-Stil, der in Node.js immer noch weit verbreitet ist, ist die module.exports
/ require
System.
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
Es gibt andere Möglichkeiten für JavaScript, externe JavaScript-Inhalte in Browsern einzubinden, die keine Vorverarbeitung erfordern.
AJAX-Laden
Sie könnten ein zusätzliches Skript mit einem AJAX-Aufruf laden und dann eval
um es auszuführen. Dies ist der einfachste Weg, aber aufgrund des JavaScript-Sandbox-Sicherheitsmodells ist er auf Ihre Domäne beschränkt. Verwendung von eval
öffnet auch die Tür für Bugs, Hacks und Sicherheitsprobleme.
Laden abrufen
Wie bei dynamischen Importen können Sie ein oder mehrere Skripte mit einer fetch
Aufruf unter Verwendung von Versprechen, um die Ausführungsreihenfolge für Skriptabhängigkeiten zu kontrollieren, indem die Fetch Inject Bibliothek:
fetchInject([
'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})
jQuery Laden
En jQuery Bibliothek bietet Ladefunktionalität in einer Zeile :
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
Dynamisches Laden von Skripten
Sie können ein Skript-Tag mit der Skript-URL in den HTML-Code einfügen. Um den Overhead von jQuery zu vermeiden, ist dies eine ideale Lösung.
Das Skript kann sich sogar auf einem anderen Server befinden. Außerdem wertet der Browser den Code aus. Die <script>
Tag kann entweder in die Webseite eingefügt werden <head>
oder kurz vor dem Schluss eingefügt </body>
Tag.
Hier ein Beispiel dafür, wie dies funktionieren könnte:
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // create a script DOM node
script.src = url; // set its src to the provided URL
document.head.appendChild(script); // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}
Diese Funktion fügt eine neue <script>
Tag an das Ende des Kopfbereichs der Seite, wo der src
Attribut wird auf die URL gesetzt, die der Funktion als erster Parameter übergeben wird.
Beide Lösungen werden in der folgenden Broschüre erörtert und erläutert JavaScript-Wahnsinn: Dynamisches Laden von Skripten .
Erkennen, wann das Skript ausgeführt wurde
Nun gibt es ein großes Problem, das Sie kennen sollten. Das zu tun bedeutet, dass Sie laden den Code aus der Ferne . Moderne Webbrowser laden die Datei und führen Ihr aktuelles Skript weiter aus, da sie alles asynchron laden, um die Leistung zu verbessern. (Dies gilt sowohl für die jQuery-Methode als auch für die manuelle Methode des dynamischen Skriptladens).
Das heißt, wenn Sie diese Tricks direkt anwenden, können Sie den neu geladenen Code in der nächsten Zeile, nachdem Sie ihn geladen haben, nicht mehr verwenden weil sie noch geladen wird.
Zum Beispiel: my_lovely_script.js
enthält MySuperObject
:
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
var s = new MySuperObject();
Error : MySuperObject is undefined
Dann laden Sie die Seite neu, indem Sie F5 . Und es funktioniert! Verwirrend...
Was kann man also dagegen tun?
Nun, Sie können den Hack verwenden, den der Autor in dem von mir angegebenen Link vorschlägt. Kurz gesagt, für Leute, die es eilig haben, verwendet er ein Ereignis, um eine Callback-Funktion auszuführen, wenn das Skript geladen wird. So können Sie den gesamten Code, der die Remote-Bibliothek verwendet, in die Callback-Funktion einfügen. Zum Beispiel:
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.head;
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
Dann schreiben Sie den Code, den Sie verwenden möchten, NACHDEM das Skript in einer Lambdafunktion :
var myPrettyCode = function() {
// Here, do whatever you want
};
Dann lassen Sie das alles laufen:
loadScript("my_lovely_script.js", myPrettyCode);
Beachten Sie, dass das Skript ausgeführt werden kann, nachdem das DOM geladen wurde, oder davor, je nach Browser und ob Sie die Zeile script.async = false;
. Es gibt eine Toller Artikel über das Laden von Javascript im Allgemeinen in der dies erörtert wird.
Quellcode-Zusammenführung/Vorverarbeitung
Wie oben in dieser Antwort erwähnt, verwenden viele Entwickler Build-/Transpilierungs-Tools wie Parcel, Webpack oder Babel in ihren Projekten, die es ihnen ermöglichen, eine neue JavaScript-Syntax zu verwenden, Abwärtskompatibilität für ältere Browser zu gewährleisten, Dateien zu kombinieren, zu minimieren, Code aufzuteilen usw.
Wenn jemand etwas Fortgeschritteneres sucht, sollte er Folgendes ausprobieren RequireJS . Sie profitieren von zusätzlichen Vorteilen wie der Verwaltung von Abhängigkeiten, besserer Gleichzeitigkeit und der Vermeidung von Doppelarbeit (d. h. dem mehrmaligen Abrufen eines Skripts).
Sie können Ihre JavaScript-Dateien in "Module" schreiben und sie dann als Abhängigkeiten in anderen Skripten referenzieren. Oder Sie können RequireJS als einfache "Holen Sie sich dieses Skript"-Lösung verwenden.
Beispiel:
Definieren Sie Abhängigkeiten als Module:
some-dependency.js
define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {
//Your actual script goes here.
//The dependent scripts will be fetched if necessary.
return libraryObject; //For example, jQuery object
});
Umsetzung.js ist Ihre "Haupt"-JavaScript-Datei, die abhängig ist von some-dependency.js
require(['some-dependency'], function(dependency) {
//Your script goes here
//some-dependency.js is fetched.
//Then your script is executed
});
Auszug aus dem GitHub README:
RequireJS lädt sowohl einfache JavaScript-Dateien als auch mehr definierte Module. Es ist für die Verwendung im Browser optimiert, auch in einem Web Worker, aber es kann auch in anderen JavaScript-Umgebungen verwendet werden, wie Rhino und Node. Es implementiert die asynchrone Modul-API.
RequireJS verwendet einfache Skript-Tags zum Laden von Modulen/Dateien, so dass es eine einfache Fehlersuche ermöglichen. Es kann einfach verwendet werden, um bestehende JavaScript-Dateien, also können Sie es zu Ihrem bestehenden Projekt hinzufügen, ohne ohne dass Sie Ihre JavaScript-Dateien neu schreiben müssen.
...
Es gibt tatsächlich ist eine Möglichkeit zum Laden einer JavaScript-Datei no asynchron, so dass Sie die Funktionen, die in Ihrer neu geladenen Datei enthalten sind, direkt nach dem Laden verwenden können, und ich denke, es funktioniert in allen Browsern.
Sie müssen Folgendes verwenden jQuery.append()
über die <head>
Element Ihrer Seite, das heißt:
$("head").append($("<script></script>").attr("src", url));
/* Note that following line of code is incorrect because it doesn't escape the
* HTML attribute src correctly and will fail if `url` contains special characters:
* $("head").append('<script src="' + url + '"></script>');
*/
Allerdings gibt es auch bei dieser Methode ein Problem: Wenn in der importierten JavaScript-Datei ein Fehler auftritt, Firebug (und auch Firefox Error Console und Chrome-Entwickler-Tools auch) wird seine Stelle falsch melden, was ein großes Problem ist, wenn Sie Firebug verwenden, um JavaScript-Fehler aufzuspüren viel (ich tue). Firebug kennt die neu geladene Datei aus irgendeinem Grund einfach nicht, und wenn in dieser Datei ein Fehler auftritt, meldet es, dass er in Ihrer Hauptdatei HTML Datei, und Sie werden Schwierigkeiten haben, den wahren Grund für den Fehler herauszufinden.
Aber wenn das für Sie kein Problem ist, dann sollte diese Methode funktionieren.
Ich habe tatsächlich ein jQuery-Plugin namens $.import_js() die diese Methode verwendet:
(function($)
{
/*
* $.import_js() helper (for JavaScript importing within JavaScript code).
*/
var import_js_imported = [];
$.extend(true,
{
import_js : function(script)
{
var found = false;
for (var i = 0; i < import_js_imported.length; i++)
if (import_js_imported[i] == script) {
found = true;
break;
}
if (found == false) {
$("head").append($('<script></script').attr('src', script));
import_js_imported.push(script);
}
}
});
})(jQuery);
Um JavaScript zu importieren, müssen Sie also nur Folgendes tun:
$.import_js('/path_to_project/scripts/somefunctions.js');
Ich habe auch einen einfachen Test dafür gemacht unter Beispiel .
Sie umfasst eine main.js
Datei im Haupt-HTML und dann das Skript in main.js
utilise $.import_js()
um eine zusätzliche Datei namens included.js
, die diese Funktion definiert:
function hello()
{
alert("Hello world!");
}
Und gleich nach der Aufnahme von included.js
El hello()
aufgerufen, und Sie erhalten die Meldung.
(Diese Antwort ist eine Antwort auf den Kommentar von e-satis).
Eine andere Möglichkeit, die meiner Meinung nach viel sauberer ist, besteht darin, eine synchrone Ajax-Anfrage zu stellen, anstatt eine <script>
Tag. Das ist auch die Art und Weise Node.js Griffe enthalten.
Hier ist ein Beispiel mit jQuery:
function require(script) {
$.ajax({
url: script,
dataType: "script",
async: false, // <-- This is the key
success: function () {
// all good...
},
error: function () {
throw new Error("Could not load script " + script);
}
});
}
Sie können es dann in Ihrem Code verwenden, wie Sie normalerweise ein Include verwenden würden:
require("/scripts/subscript.js");
Und in der Lage sein, in der nächsten Zeile eine Funktion aus dem gewünschten Skript aufzurufen:
subscript.doSomethingCool();
Es ist möglich, ein JavaScript-Tag dynamisch zu generieren und es an ein HTML-Dokument aus einem anderen JavaScript-Code heraus anzuhängen. Dadurch wird eine gezielte JavaScript-Datei geladen.
function includeJs(jsFilePath) {
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
}
includeJs("/path/to/some/file.js");
- See previous answers
- Weitere Antworten anzeigen
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.