Frage Wie schließe ich eine JavaScript-Datei in eine andere JavaScript-Datei ein?


Ist da etwas in JavaScript ähnlich? @import in CSS, mit dem Sie eine JavaScript-Datei in eine andere JavaScript-Datei einfügen können?


4146
2018-06-04 11:59


Ursprung


Antworten:


Die alten Versionen von JavaScript hatten keine Import-, Include- oder Require-Funktionen, daher wurden viele verschiedene Ansätze für dieses Problem entwickelt.

Aber neuere Versionen von JavaScript haben Standards wie ES6-Module um Module zu importieren, obwohl dies von den meisten Browsern noch nicht unterstützt wird. Viele Menschen nutzen Module mit Browser-Anwendungen bauen und / oder Transpilation Werkzeuge, um es praktisch zu machen, neue Syntax mit Funktionen wie Modulen zu verwenden.

ES6 Module

Beachten Sie, dass derzeit die Browser-Unterstützung für ES6-Module nicht besonders gut ist, aber es ist auf dem Weg. Gemäß diese StackOverflow-AntwortSie werden in Chrome 61, Firefox 54 (hinter der dom.moduleScripts.enabled Einstellung in about:config) und MS Edge 16, wobei nur Safari 10.1 Unterstützung ohne Flags bietet.

Daher müssen Sie derzeit noch Build- und / oder Umsetzungswerkzeuge für gültiges JavaScript verwenden, das ausgeführt wird, ohne dass der Benutzer diese Browserversionen verwenden oder Flags aktivieren muss.

Sobald ES6-Module an der Tagesordnung sind, gehen Sie folgendermaßen vor:

// module.js
export function hello() {
  return "Hello";
}
// main.js
import {hello} from 'module'; // or './module'
let val = hello(); // val is "Hello";

Node.js benötigen

Node.js verwendet derzeit a module.exports / erfordern System. Sie können verwenden babel transpile wenn du willst import Syntax.

// 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 Browser einzubinden, die keine Vorverarbeitung erfordern.

AJAX wird geladen

Sie könnten ein zusätzliches Skript mit einem AJAX-Aufruf laden und dann verwenden eval um es auszuführen. Dies ist der direkteste Weg, ist jedoch aufgrund des JavaScript-Sandbox-Sicherheitsmodells auf Ihre Domäne beschränkt. Verwenden eval öffnet auch die Tür für Bugs, Hacks und Sicherheitsprobleme.

jQuery wird geladen

Das jQuery Bibliothek bietet Ladefunktionalität in einer Zeile:

$.getScript("my_lovely_script.js", function() {
   alert("Script loaded but not necessarily executed.");
});

Dynamisches Skript wird geladen

Sie könnten 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. Darüber hinaus wertet der Browser den Code aus. Das <script> Das Tag kann in die Webseite eingefügt werden <head>oder kurz vor dem Schließen eingefügt </body> Etikett.

Hier ist ein Beispiel, wie das funktionieren könnte:

function dynamicallyLoadScript(url) {
    var script = document.createElement("script"); // Make a script DOM node
    script.src = url; // Set it's 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 ein neues hinzu <script> Tag zum Ende des Kopfbereichs der Seite, wo der src Attribut wird auf die URL gesetzt, die der Funktion als erster Parameter zugewiesen wird.

Beide Lösungen werden diskutiert und illustriert in JavaScript Madness: Dynamisches Skript wird geladen.

Erkennen, wann das Skript ausgeführt wurde

Jetzt gibt es ein großes Problem, über das Sie Bescheid wissen müssen. Das bedeutet das Sie laden den Code aus der Ferne. Moderne Webbrowser laden die Datei und führen das aktuelle Skript weiterhin 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 zum Laden dynamischer Skripts.)

Es bedeutet, dass wenn Sie diese Tricks direkt verwenden, Sie können Ihren neu geladenen Code nicht in der nächsten Zeile verwenden, nachdem Sie ihn zum Laden angefordert haben, weil es immer noch geladen wird.

Beispielsweise: 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 erneut hoch F5. Und es funktioniert! Verwirrend...

Was also zu tun?

Nun, Sie können den Hack verwenden, den der Autor in dem Link, den ich Ihnen gab, vorschlägt. Zusammengefasst verwendet er für Personen, die es eilig haben, ein Ereignis, um eine Rückruffunktion auszuführen, wenn das Skript geladen wird. Sie können also den gesamten Code über die Remote-Bibliothek in die Callback-Funktion einfügen. Beispielsweise:

function loadScript(url, callback)
{
    // Adding the script tag to the head as suggested before
    var head = document.getElementsByTagName('head')[0];
    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 a geladen wurde Lambda-Funktion:

var myPrettyCode = function() {
   // Here, do whatever you want
};

Dann rennst du das alles:

loadScript("my_lovely_script.js", myPrettyCode);

Beachten Sie, dass das Skript möglicherweise ausgeführt wird, nachdem das DOM geladen wurde oder früher, abhängig vom Browser und ob Sie die Zeile eingefügt haben script.async = false;. Da ist ein Toller Artikel zum Laden von Javascript im Allgemeinen das bespricht dies.

Quellcode-Zusammenführung / Vorverarbeitung

Wie oben in dieser Antwort erwähnt, verwenden viele Entwickler nun Build- / Transpilationstools wie WebPack, Babel oder Gulp in ihren Projekten, so dass sie neue Syntax- und Supportmodule besser verwenden, Dateien kombinieren, minimieren usw. können.


3579
2018-06-04 12:13



Wenn jemand etwas fortgeschrittener sucht, probieren Sie es aus ErfordernJS. Sie erhalten zusätzliche Vorteile wie das Abhängigkeitsmanagement, eine bessere Parallelität und vermeiden Doppelarbeit (dh, ein Skript wird mehrmals abgerufen).

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 Lösung verwenden, um dieses Skript zu erhalten.

Beispiel:

Abhängigkeiten als Module definieren:

einige-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
});

implementation.js ist Ihre "Haupt" JavaScript-Datei, die davon abhängt einige-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 einfache JavaScript-Dateien sowie mehr definiert   Module. Es ist für die In-Browser-Verwendung optimiert, auch in einem Web   Worker, aber es kann in anderen JavaScript-Umgebungen wie verwendet werden   Rhino und Knoten. Es implementiert die Asynchronous Module API.

RequireJS verwendet einfache Skript-Tags, um Module / Dateien zu laden   ermöglichen ein einfaches Debugging. Es kann einfach verwendet werden, um vorhandene zu laden   JavaScript-Dateien, so Sie können es ohne Ihr bestehendes Projekt hinzufügen   Sie müssen Ihre JavaScript-Dateien neu schreiben.

...


513
2018-06-07 20:55



Da eigentlich ist eine Möglichkeit, eine JavaScript-Datei zu laden nicht asynchron, so dass Sie die Funktionen, die in Ihrer neu geladenen Datei enthalten sind, direkt nach dem Laden verwenden können, und ich denke, dass es in allen Browsern funktioniert.

Sie müssen verwenden jQuery.append()auf der <head> Element Ihrer Seite, das heißt:

$("head").append('<script type="text/javascript" src="' + script + '"></script>');

Diese Methode hat jedoch auch ein Problem: Wenn in der importierten JavaScript-Datei ein Fehler auftritt, Feuerwanze (und auch Firefox Error Console und Chrome-Entwicklertools (auch) wird seinen Platz falsch melden, was ein großes Problem ist, wenn Sie Firebug verwenden, um JavaScript-Fehler viel zu verfolgen (tue ich). Firebug weiß aus irgendeinem Grund nichts über die neu geladene Datei. Wenn also ein Fehler in dieser Datei auftritt, wird gemeldet, dass er in Ihrer Hauptdatei aufgetreten ist HTML Datei, und Sie werden Schwierigkeiten haben, den wahren Grund für den Fehler herauszufinden.

Aber wenn das kein Problem für Sie ist, dann sollte diese Methode funktionieren.

Ich habe eigentlich ein jQuery-plugin genannt $ .import_js () welche 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 type="text/javascript" src="' + script + '"></script>');
                import_js_imported.push(script);
            }
        }
    });

})(jQuery);

Alles, was Sie tun müssen, um JavaScript zu importieren, ist:

$.import_js('/path_to_project/scripts/somefunctions.js');

Ich habe dazu auch einen einfachen Test gemacht Beispiel.

Es enthält a main.js Datei im Haupt-HTML und dann das Skript in main.js Verwendet $.import_js() um eine zusätzliche Datei namens included.js, die diese Funktion definiert:

function hello()
{
    alert("Hello world!");
}

Und direkt nach dem Einschließen included.js, das hello() Funktion wird aufgerufen, und Sie erhalten die Warnung.

(Diese Antwort ist eine Reaktion auf den Kommentar von e-satis).


162
2018-04-28 15:25



Eine andere Möglichkeit, die meiner Meinung nach viel sauberer ist, besteht darin, eine synchrone Ajax - Anfrage zu machen, anstatt eine <script> Etikett. Welches ist auch wie Node.js Griffe beinhaltet.

Hier 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 nächsten Zeile eine Funktion aus dem benötigten Skript aufrufen können:

subscript.doSomethingCool(); 

133
2017-09-08 18:22



Es gibt eine gute Nachricht für Sie. Sehr bald können Sie JavaScript-Code einfach laden. Es wird eine Standardmethode zum Importieren von Modulen von JavaScript-Code und wird Teil von Core-JavaScript selbst sein.

Du musst einfach schreiben import cond from 'cond.js'; um ein Makro namens zu laden cond aus einer Datei cond.js.

Sie müssen sich also weder auf ein JavaScript-Framework verlassen, noch müssen Sie explizit etwas machen Ajax Anrufe.

Beziehen auf:


86
2017-07-03 13:32



Es ist möglich, ein JavaScript-Tag dynamisch zu generieren und es von einem anderen JavaScript-Code aus an das HTML-Dokument 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");

72
2018-06-04 12:02



Erklärung import ist in ECMAScript 6.

Syntax

import name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import name , { member [ , [...] ] } from "module-name";
import "module-name" as name;

58
2018-04-17 01:56



Vielleicht können Sie diese Funktion verwenden, die ich auf dieser Seite gefunden habe Wie schließe ich eine JavaScript-Datei in eine JavaScript-Datei ein?:

function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';

    head.appendChild(script)
}

47
2018-06-04 12:04



Hier ist ein synchron Ausführung ohne jQuery:

function myRequire( url ) {
    var ajax = new XMLHttpRequest();
    ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
    ajax.onreadystatechange = function () {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4) {
            switch( ajax.status) {
                case 200:
                    eval.apply( window, [script] );
                    console.log("script loaded: ", url);
                    break;
                default:
                    console.log("ERROR: script not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

Beachten Sie, dass der Server festgelegt werden muss, um diese funktionsübergreifende Domäne zu erhalten allow-origin Header in seiner Antwort.


46
2017-12-11 11:54



Ich habe gerade diesen JavaScript - Code geschrieben (mit Prototyp zum DOM Manipulation):

var require = (function() {
    var _required = {};
    return (function(url, callback) {
        if (typeof url == 'object') {
            // We've (hopefully) got an array: time to chain!
            if (url.length > 1) {
                // Load the nth file as soon as everything up to the
                // n-1th one is done.
                require(url.slice(0, url.length - 1), function() {
                    require(url[url.length - 1], callback);
                });
            } else if (url.length == 1) {
                require(url[0], callback);
            }
            return;
        }
        if (typeof _required[url] == 'undefined') {
            // Haven't loaded this URL yet; gogogo!
            _required[url] = [];

            var script = new Element('script', {
                src: url,
                type: 'text/javascript'
            });
            script.observe('load', function() {
                console.log("script " + url + " loaded.");
                _required[url].each(function(cb) {
                    cb.call(); // TODO: does this execute in the right context?
                });
                _required[url] = true;
            });

            $$('head')[0].insert(script);
        } else if (typeof _required[url] == 'boolean') {
            // We already loaded the thing, so go ahead.
            if (callback) {
                callback.call();
            }
            return;
        }

        if (callback) {
            _required[url].push(callback);
        }
    });
})();

Verwendung:

<script src="prototype.js"></script>
<script src="require.js"></script>
<script>
    require(['foo.js','bar.js'], function () {
        /* Use foo.js and bar.js here */
    });
</script>

Kern: http://gist.github.com/284442.


41
2018-01-23 05:20



Hier ist die verallgemeinerte Version, wie Facebook es für ihren allgegenwärtigen Like-Button macht:

<script>
  var firstScript = document.getElementsByTagName('script')[0],
      js = document.createElement('script');
  js.src = 'https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js';
  js.onload = function () {
    // do stuff with your dynamically loaded script
    snowStorm.snowColor = '#99ccff';
  };
  firstScript.parentNode.insertBefore(js, firstScript);
</script>

Wenn es für Facebook funktioniert, wird es für Sie arbeiten.

Der Grund, warum wir nach dem ersten suchen script Element statt head oder body ist, weil einige Browser keine erstellen, wenn sie fehlen, aber wir haben garantiert eine script Element - dieses. Lesen Sie mehr unter http://www.jspatterns.com/the-ridilical-case-of-Adding-a-script-element/.


33
2017-07-08 02:41