web-dev-qa-db-fra.com

Comment inclure un fichier JavaScript dans un autre fichier JavaScript?

Y a-t-il quelque chose dans JavaScript similaire à @import dans CSS qui vous permet d'inclure un fichier JavaScript dans un autre fichier JavaScript?

4481
Alec Smart

Les anciennes versions de JavaScript n’avaient pas d’importation, d’inclusion ou de nécessité, autant d’approches différentes de ce problème ont été développées.

Mais depuis 2015 (ES6), JavaScript dispose de la norme modules ES6 pour importer des modules dans Node.js, qui est également prise en charge par la plupart des navigateurs modernes .

Pour assurer la compatibilité avec les anciens navigateurs, les outils build et/ou transpilation peuvent être utilisés.

Modules ES6

Les modules ECMAScript (ES6) sont pris en charge dans Node.js depuis la version 8.5, avec l'indicateur --experimental-modules. Tous les fichiers concernés doivent avoir l'extension .mjs.

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

Modules ECMAScript dans les navigateurs

Les navigateurs ont pris en charge le chargement direct des modules ECMAScript (aucun outil comme Webpack n’est requis) depuis Safari 10.1, Chrome 61, Firefox 60 et Edge 16. Consultez le support actuel à l’adresse caniuse .

<script type="module">
  import { hello } from './hello.mjs';
  hello('world');
</script>
// hello.mjs
export function hello(text) {
  const div = document.createElement('div');
  div.textContent = `Hello ${text}`;
  document.body.appendChild(div);
}

Lire la suite sur le site https://jakearchibald.com/2017/es-modules-in-browsers/

Importations dynamiques dans les navigateurs

Les importations dynamiques permettent au script de charger d’autres scripts selon les besoins:

<script type="module">
  import('hello.mjs').then(module => {
      module.hello('world');
    });
</script>

Pour en savoir plus, consultez la page https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js nécessite

L'ancien style d'importation de modules, encore largement utilisé dans Node.js, est le système module.exports/require .

// mymodule.js
module.exports = {
   hello: function() {
      return "Hello";
   }
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"   

Il existe d'autres moyens pour JavaScript d'inclure du contenu JavaScript externe dans les navigateurs qui ne nécessitent pas de prétraitement.

AJAX Chargement

Vous pouvez charger un script supplémentaire avec un appel AJAX, puis utiliser evalpour l'exécuter. C'est le moyen le plus simple, mais il est limité à votre domaine en raison du modèle de sécurité JavaScript du sandbox. Utiliser evalouvre également la porte aux bugs, aux hacks et aux problèmes de sécurité.

Chercher chargement

Comme pour les importations dynamiques, vous pouvez charger un ou plusieurs scripts avec un appel fetchen utilisant la promesse de contrôler l’ordre d’exécution des dépendances de script à l’aide de la bibliothèque Fetch Inject :

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 Chargement

La bibliothèque jQuery fournit la fonctionnalité de chargement sur une ligne :

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

Chargement de script dynamique

Vous pouvez ajouter une balise de script avec l'URL du script dans le code HTML. Pour éviter les frais généraux de jQuery, il s'agit d'une solution idéale.

Le script peut même résider sur un autre serveur. De plus, le navigateur évalue le code. La balise <script> peut être injectée dans la page Web <head> ou insérée juste avant la balise de fermeture </body>.

Voici un exemple de la façon dont cela pourrait fonctionner:

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

Cette fonction ajoutera une nouvelle balise <script> à la fin de la section d'en-tête de la page, l'attribut srcétant défini sur l'URL attribuée à la fonction en tant que premier paramètre.

Ces deux solutions sont décrites et illustrées dans JavaScript Madness: Chargement du script dynamique .

Détecter quand le script a été exécuté

Maintenant, il y a un gros problème que vous devez connaître. Cela implique que vous chargez le code à distance . Les navigateurs Web modernes chargeront le fichier et continueront à exécuter votre script actuel car ils chargent tout de manière asynchrone pour améliorer les performances. (Cela s'applique à la méthode jQuery et à la méthode de chargement manuel dynamique des scripts.)

Cela signifie que si vous utilisez ces astuces directement, , vous ne pourrez pas utiliser votre code nouvellement chargé à la ligne suivante après l'avoir demandé à être chargé , car il sera toujours chargement.

Par exemple: my_lovely_script.js contient MySuperObjectname__:

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

Ensuite, vous rechargez la page frapper F5. Et il fonctionne! Déroutant...

Alors, que faire?

Eh bien, vous pouvez utiliser le hack suggéré par l'auteur dans le lien que je vous ai donné. En résumé, pour les personnes pressées, il utilise un événement pour exécuter une fonction de rappel lorsque le script est chargé. Ainsi, vous pouvez mettre tout le code en utilisant la bibliothèque distante dans la fonction de rappel. Par exemple:

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

Ensuite, vous écrivez le code que vous voulez utiliser APRÈS que le script soit chargé dans un fonction lambda :

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

Ensuite, vous lancez tout ça:

loadScript("my_lovely_script.js", myPrettyCode);

Notez que le script peut s'exécuter après le chargement du DOM ou avant, selon le navigateur et si vous avez inclus la ligne script.async = false;. Il y a un grand article sur le chargement de Javascript en général qui en parle.

Fusion de code source/prétraitement

Comme indiqué au début de cette réponse, de nombreux développeurs utilisent des outils de génération/transpilation tels que Parcel, Webpack ou Babel dans leurs projets, ce qui leur permet d'utiliser la syntaxe JavaScript à venir, d'assurer la compatibilité ascendante des navigateurs plus anciens, de combiner des fichiers, de minifier, effectuer le fractionnement de code, etc.

4044
e-satis

Si quelqu'un recherche quelque chose de plus avancé, essayez RequireJS . Vous obtiendrez des avantages supplémentaires tels que la gestion des dépendances, une meilleure simultanéité et d'éviter la duplication (c'est-à-dire, récupérer un script plusieurs fois).

Vous pouvez écrire vos fichiers JavaScript dans des "modules", puis les référencer en tant que dépendances dans d'autres scripts. Ou vous pouvez utiliser RequireJS en tant que solution simple "allez chercher ce script".

Exemple:

Définissez les dépendances en tant que modules:

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

implementation.js est votre fichier JavaScript "principal" qui dépend de some-dependency.js.

require(['some-dependency'], function(dependency) {

    //Your script goes here
    //some-dependency.js is fetched.   
    //Then your script is executed
});

Extrait du GitHub README:

RequireJS charge des fichiers JavaScript simples ainsi que davantage définis modules. Il est optimisé pour une utilisation dans le navigateur, y compris dans un Web Worker, mais il peut être utilisé dans d'autres environnements JavaScript, tels que Rhino et Node. Il implémente l'API de module asynchrone.

RequireJS utilise des balises de script simples pour charger des modules/fichiers, il devrait donc être permettre un débogage facile. Il peut être utilisé simplement pour charger des fichiers existants Les fichiers JavaScript, donc vous pouvez les ajouter à votre projet existant sans avoir à ré-écrire vos fichiers JavaScript.

... 

533
John Strickler

Il y a en fait un moyen de charger un fichier JavaScript pas de manière asynchrone, vous pouvez donc utiliser les fonctions incluses dans votre fichier récemment chargé juste après le chargement, et je pense que cela fonctionne dans tous les navigateurs.

Vous devez utiliser jQuery.append() sur l'élément <head> de votre page, c'est-à-dire:

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

Cependant, cette méthode pose également un problème: si une erreur se produit dans le fichier JavaScript importé, Firebug (ainsi que Firefox Error Console et Chrome Developer Tools aussi) signalera à tort sa place, ce qui est un problème. gros problème si vous utilisez Firebug pour suivre beaucoup les erreurs JavaScript (je le fais). Firebug ignore tout simplement le fichier nouvellement chargé pour une raison quelconque. Par conséquent, si une erreur se produit dans ce fichier, il le signale dans votre fichier principal HTML , et vous aurez du mal à trouver le réel. raison de l'erreur.

Mais si cela ne vous pose pas de problème, cette méthode devrait fonctionner.

J'ai en fait écrit un plugin jQuery appelé $ .import_js () qui utilise cette méthode:

(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);

Donc, tout ce que vous devez faire pour importer du JavaScript est:

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

J'ai également fait un test simple pour cela à Exemple .

Il inclut un fichier main.js dans le code HTML principal, puis le script dans main.js utilise $.import_js() pour importer un fichier supplémentaire appelé included.js, qui définit cette fonction:

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

Et juste après avoir inclus included.js, la fonction hello() est appelée et vous recevez l'alerte.

(Cette réponse est en réponse au commentaire de e-satis).

173
Kipras

Une autre façon, qui, à mon avis, est beaucoup plus propre, consiste à faire une demande Ajax synchrone au lieu d'utiliser une balise <script>. C’est aussi comment Node.js handles inclut.

Voici un exemple d'utilisation de 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);
        }
    });
}

Vous pouvez ensuite l'utiliser dans votre code comme vous utiliseriez habituellement un include:

require("/scripts/subscript.js");

Et être capable d'appeler une fonction du script requis dans la ligne suivante:

subscript.doSomethingCool(); 
138
Ariel

Il y a une bonne nouvelle pour vous. Très vite, vous pourrez charger du code JavaScript facilement. Cela deviendra un moyen standard d'importer des modules de code JavaScript et fera partie du code JavaScript même. 

Vous devez simplement écrire import cond from 'cond.js'; pour charger une macro nommée cond à partir d'un fichier cond.js.

Ainsi, vous n'avez pas besoin de faire appel à un framework JavaScript ni à explicitement appeler Ajax call.

Faire référence à:

90
Imdad

Il est possible de générer dynamiquement une balise JavaScript et de l'ajouter à un document HTML à partir d'un autre code JavaScript. Cela chargera le fichier JavaScript ciblé.

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");
79

Statement import est dans ECMAScript 6.

Syntaxe

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;
62
draupnie

Peut-être que vous pouvez utiliser cette fonction que j'ai trouvée sur cette page Comment inclure un fichier JavaScript dans un fichier JavaScript?:

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

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

    head.appendChild(script)
}

Voici un synchrone version sans 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);
}

Notez que pour que ce domaine fonctionne, le serveur doit définir l'en-tête allow-Origin dans sa réponse.

47
heinob

Je viens d'écrire ce code JavaScript (en utilisant Prototype pour 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);
        }
    });
})();

Usage:

<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>

Gist: http://Gist.github.com/284442 .

43
nornagon

Voici la version généralisée de la façon dont Facebook le fait pour son bouton omniprésent comme:

<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>

Si cela fonctionne pour Facebook, cela fonctionnera pour vous.

La raison pour laquelle nous recherchons le premier élément script au lieu de head ou body est que certains navigateurs n'en créent pas s'ils sont manquants, mais nous avons la garantie d'avoir un élément script - celui-ci. Pour en savoir plus, consultez http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .

36
Dan Dascalescu

Si vous voulez en JavaScript pur, vous pouvez utiliser document.write.

document.write('<script src="myscript.js" type="text/javascript"></script>');

Si vous utilisez la bibliothèque jQuery, vous pouvez utiliser la méthode $.getScript.

$.getScript("another_script.js");
31
Venu immadi

Vous pouvez également assembler vos scripts en utilisant PHP :

Fichier main.js.php:

<?php
    header('Content-type:text/javascript; charset=utf-8');
    include_once("foo.js.php");
    include_once("bar.js.php");
?>

// Main JavaScript code goes here
24
Calmarius

La plupart des solutions présentées ici impliquent un chargement dynamique. Je cherchais à la place un compilateur qui rassemble tous les fichiers dépendants en un seul fichier de sortie. Identique aux préprocesseurs moinsSass , ils traitent la règle CSS @import at. N'ayant rien trouvé de tel, j'ai écrit un outil simple pour résoudre le problème.

Voici donc le compilateur, https://github.com/dsheiko/jsic , qui remplace $import("file-path") par le contenu du fichier demandé en toute sécurité. Voici le plugin Grunt correspondant: https://github.com/dsheiko/grunt-jsic .

Sur la branche principale de jQuery, ils concaténent simplement les fichiers source atomiques en un seul fichier commençant par intro.js et se terminant par outtro.js. Cela ne me convient pas car cela n'offre aucune flexibilité pour la conception du code source. Découvrez comment cela fonctionne avec jsic:

_/src/main.js

var foo = $import("./Form/Input/Tel");

src/Form/Input/Tel.js

function() {
    return {
          prop: "",
          method: function(){}
    }
}

Maintenant nous pouvons exécuter le compilateur:

node jsic.js src/main.js build/mail.js

Et obtenir le fichier combiné

build/main.js

var foo = function() {
    return {
          prop: "",
          method: function(){}
    }
};
24
Dmitry Sheiko

Si votre intention de charger le fichier JavaScript est en utilisant les fonctions du fichier importé/inclus , vous pouvez également définir un objet global et définir les fonctions comme éléments d'objet. Par exemple:

global.js

A = {};

fichier1.js

A.func1 = function() {
  console.log("func1");
}

fichier2.js

A.func2 = function() {
  console.log("func2");
}

main.js

A.func1();
A.func2();

Vous devez juste faire attention lorsque vous incluez des scripts dans un fichier HTML. La commande devrait être comme ci-dessous:

<head>
  <script type="text/javascript" src="global.js"></script>
  <script type="text/javascript" src="file1.js"></script>
  <script type="text/javascript" src="file2.js"></script>
  <script type="text/javascript" src="main.js"></script>
</head>
20
Adem İlhan

Cela devrait faire:

xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
18
tggagne

Ou plutôt que d'inclure au moment de l'exécution, utilisez un script à concaténer avant le téléchargement.

J'utilise Sprockets (Je ne sais pas s'il y en a d'autres). Vous construisez votre code JavaScript dans des fichiers séparés et incluez les commentaires traités par le moteur Sprockets en tant que includes Pour le développement, vous pouvez inclure des fichiers de manière séquentielle, puis pour la production, pour les fusionner ...

Voir également:

17
JMawer

Si vous utilisez Web Workers et souhaitez inclure des scripts supplémentaires dans le périmètre de l'opérateur, les autres réponses fournies sur l'ajout de scripts à la balise head, etc. ne fonctionneront pas pour vous.

Heureusement, les { les travailleurs Web ont leur propre fonction importScripts } qui est une fonction globale dans la portée de Web Worker, native du navigateur lui-même car elle fait partie de la spécification .

Sinon, en tant que deuxième réponse la plus votée à la question , RequireJS peut également inclure des scripts dans un Web Worker (appelant probablement importScripts lui-même, mais avec quelques autres fonctionnalités utiles).

14
Turnerj

J'avais un problème simple, mais les réponses à cette question m'ont déconcerté.

Je devais utiliser une variable (myVar1) définie dans un fichier JavaScript (myvariables.js) dans un autre fichier JavaScript (main.js).

Pour cela j'ai fait comme ci-dessous:

Charge le code JavaScript dans le fichier HTML, dans le bon ordre, en premier lieu myvariables.js, puis main.js:

<html>
    <body onload="bodyReady();" >

        <script src="myvariables.js" > </script>
        <script src="main.js" > </script>

        <!-- Some other code -->
    </body>
</html>

Fichier: myvariables.js

var myVar1 = "I am variable from myvariables.js";

Fichier: main.js

// ...
function bodyReady() {
    // ...
    alert (myVar1);    // This shows "I am variable from myvariables.js", which I needed
    // ...
}
// ...

Comme vous l'avez vu, j'avais utilisé une variable dans un fichier JavaScript dans un autre fichier JavaScript, mais je n'avais pas besoin d'en inclure une dans un autre. Je devais simplement m'assurer que le premier fichier JavaScript chargé avant le deuxième fichier JavaScript et que les variables du premier fichier JavaScript sont accessibles automatiquement dans le deuxième fichier JavaScript.

Cela a sauvé ma journée. J'espère que ça aide.

13

La syntaxe @import permettant de réaliser une importation JavaScript de type CSS est possible à l'aide d'un outil tel que Mixture via leur type de fichier .mix spécial (voir ici ). J'imagine que l'application utilise simplement l'une des méthodes susmentionnées en interne, bien que je ne sache pas. 

Dans la documentation de Mixture sur les fichiers .mix

Les fichiers de mixage sont simplement des fichiers .js ou .css avec .mix. dans le nom du fichier. UNE fichier de mix étend simplement les fonctionnalités d'un style normal ou fichier de script et vous permet d'importer et de combiner.

Voici un exemple de fichier .mix qui combine plusieurs fichiers .js en un:

// scripts-global.mix.js
// Plugins - Global

@import "global-plugins/headroom.js";
@import "global-plugins/retina-1.1.0.js";
@import "global-plugins/isotope.js";
@import "global-plugins/jquery.fitvids.js";

Mixture renvoie ceci en tant que scripts-global.js et également en tant que version réduite (scripts-global.min.js).

Remarque: je ne suis aucunement affilié à Mixture, mis à part son utilisation en tant qu'outil de développement front-end. Je suis tombé sur cette question après avoir vu un fichier JavaScript .mix en action (dans l’un des circuits d’affichage Mixture) et avoir été un peu dérouté par cette idée («vous pouvez le faire? J'ai ensuite réalisé qu'il s'agissait d'un type de fichier spécifique à l'application (quelque peu décevant, accepté). Néanmoins, imaginé que la connaissance pourrait être utile pour les autres.

UPDATE: le mélange est maintenant libre (hors ligne).

UPDATE: le mélange est maintenant interrompu. Anciennes versions du mélange sont toujours disponibles

12
Isaac Gregson

Ma méthode habituelle est:

var require = function (src, cb) {
    cb = cb || function () {};

    var newScriptTag = document.createElement('script'),
        firstScriptTag = document.getElementsByTagName('script')[0];
    newScriptTag.src = src;
    newScriptTag.async = true;
    newScriptTag.onload = newScriptTag.onreadystatechange = function () {
        (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') && (cb());
    };
    firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag);
}

Cela fonctionne très bien et n'utilise pas de rechargement de page pour moi. J'ai essayé la méthode AJAX (l'une des autres réponses) mais cela ne semble pas fonctionner aussi bien pour moi.

Voici une explication du fonctionnement du code pour les plus curieux: il crée essentiellement une nouvelle balise de script (après la première) de l’URL. Il le configure en mode asynchrone afin de ne pas bloquer le reste du code, mais d'appeler un rappel lorsque le paramètre readyState (l'état du contenu à charger) devient «chargé».

11

J'ai écrit un module simple qui automatise le travail d'importation/inclusion des scripts de module en JavaScript. Pour une explication détaillée du code, reportez-vous à l'article de blog JavaScript require/import/include modules.

// ----- USAGE -----

require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');

ready(function(){
    //Do something when required scripts are loaded
});

    //--------------------

var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
                                                   //the root directory of your library, any library.


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };
    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

_.rmod = namespaceToUri = function(script_name, url) {
    var np = script_name.split('.');
    if (np.getLast() === '*') {
        np.pop();
        np.Push('_all');
    }

    if(!url)
        url = '';

    script_name = np.join('.');
    return  url + np.join('/')+'.js';
};

//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
    var uri = '';
    if (script_name.indexOf('/') > -1) {
        uri = script_name;
        var lastSlash = uri.lastIndexOf('/');
        script_name = uri.substring(lastSlash+1, uri.length);
    } 
    else {
        uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
    }

    if (!_rmod.loading.scripts.hasOwnProperty(script_name)
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri,
            _rmod.requireCallback,
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.Push(fn);
};
11
stamat
var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);
10
Sam4Code

En langage moderne, ce serait 

function loadJs( url ){
  return new Promise( resolve => {
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    document.head.appendChild( script );
  });
}
10
Dmitry Sheiko

Il y a aussi Head.js . Il est très facile de traiter avec:

head.load("js/jquery.min.js",
          "js/jquery.someplugin.js",
          "js/jquery.someplugin.css", function() {
  alert("Everything is ok!");
});

Comme vous le voyez, c'est plus facile que Require.js et aussi pratique que la méthode $.getScript de jQuery. Il dispose également de fonctionnalités avancées, telles que le chargement conditionnel, la détection de fonctionnalités et beaucoup plus .

9
Ale

Je suis venu à cette question parce que je cherchais un moyen simple de maintenir une collection de plugins JavaScript utiles. Après avoir vu certaines des solutions ici, je suis venu avec ceci:

  1. Configurez un fichier appelé "plugins.js" (ou extensions.js ou ce que vous avez). Conservez vos fichiers de plug-in avec ce fichier maître.

  2. plugins.js aura un tableau appelé "pluginNames []" que nous itérerons sur each (), puis ajouterons une balise à la tête de chaque plugin

    // définit le tableau à mettre à jour lorsque nous ajoutons ou supprimons des fichiers de plug-in var pluginNames = ["lettering", "fittext", "butterjam", etc.]; // une balise de script pour chaque plugin $ .each (pluginNames, function () { $ ('head'). append (''); });

  3. appelez manuellement le seul fichier dans votre tête:
    <script src="js/plugins/plugins.js"></script>

J'ai constaté que même si tous les plugins étaient déposés dans la balise head comme il se doit, ils ne sont pas toujours exécutés par le navigateur lorsque vous cliquez sur la page ou l'actualisez.

J'ai trouvé qu'il était plus fiable d'écrire simplement les balises de script dans un PHP include. Vous n'avez qu'à l'écrire une fois, et c'est tout autant de travail que d'appeler le plugin en utilisant JavaScript.

9
rgb_life

Ce script ajoutera un fichier JavaScript au sommet de toute autre balise <script>:

(function () {
    var li = document.createElement('script'); 
    li.type = 'text/javascript'; 
    li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"; 
    li.async=true; 
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(li, s);
})();
9
Vicky Gonsalves

Il y a beaucoup de réponses possibles à cette question. Ma réponse est évidemment basée sur un certain nombre d'entre elles. C'est ce que j'ai fini avec après avoir lu toutes les réponses.

Le problème de $.getScript et de toute autre solution nécessitant un rappel lorsque le chargement est terminé est que, si plusieurs fichiers l'utilisent et dépendent les uns des autres, vous ne pouvez plus savoir quand tous les scripts ont été chargés (une fois qu'ils ont été chargés). imbriqué dans plusieurs fichiers).

Exemple:

fichier3.js

var f3obj = "file3";

// Define other stuff

fichier2.js:

var f2obj = "file2";
$.getScript("file3.js", function(){

    alert(f3obj);

    // Use anything defined in file3.
});

fichier1.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...
});

Vous avez raison de dire que vous pouvez spécifier qu'Ajax doit s'exécuter de manière synchrone ou utiliser XMLHttpRequest , mais la tendance actuelle semble être de désapprouver les demandes synchrones. Vous risquez donc de ne pas obtenir une prise en charge complète du navigateur.

Vous pouvez essayer d'utiliser $.when pour vérifier un tableau d'objets différés, mais maintenant vous le faites dans tous les fichiers et fichier2 sera considéré comme chargé dès que le $.when sera exécuté, pas lors de l'exécution du rappel, donc fichier1 continue son exécution avant fichier3. est chargé. Cela a toujours le même problème.

J'ai décidé de faire marche arrière au lieu d'avancer. Merci document.writeln. Je sais que c'est tabou, mais tant qu'il est utilisé correctement, cela fonctionne bien. Vous vous retrouvez avec un code qui peut être facilement mis au point, affiché correctement dans le DOM et peut garantir l'ordre de chargement correct des dépendances.

Vous pouvez bien sûr utiliser $ ("body"). Append (), mais alors vous ne pourrez plus déboguer correctement.

REMARQUE: vous ne devez l'utiliser que pendant le chargement de la page, sinon vous obtenez un écran vide. En d'autres termes, place toujours ceci avant/en dehors de document.ready. Je n'ai pas testé l'utilisation de cette option après le chargement de la page dans un événement click ou quelque chose du genre, mais je suis certain que cela va échouer.

J'ai aimé l'idée d'étendre jQuery, mais vous n'avez évidemment pas besoin de le faire.

Avant d'appeler document.writeln, il vérifie que le script n'a pas déjà été chargé en évaluant tous les éléments du script.

Je suppose qu'un script n'est pas complètement exécuté tant que son événement document.ready n'a pas été exécuté. (Je sais que l'utilisation de document.ready n'est pas obligatoire, mais de nombreuses personnes l'utilisent, ce qui constitue une protection.)

Lorsque les fichiers supplémentaires sont chargés, les rappels document.ready seront exécutés dans le mauvais ordre. Pour résoudre ce problème lorsqu'un script est réellement chargé, le script qui l'a importé est réimporté lui-même et son exécution est arrêtée. Ainsi, le rappel document.ready du fichier d'origine est maintenant exécuté après n'importe quel script importé.

Au lieu de cette approche, vous pouvez essayer de modifier jQuery readyList, mais cela semble être une solution pire.

Solution:

$.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;
    }
});

Usage:

File3:

var f3obj = "file3";

// Define other stuff
$(function(){
    f3obj = "file3docready";
});

Fichier2:

$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
    f2obj = "file2docready";
});

Fichier1:

$.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"
});
8
curlyhairedgenius

J'ai créé une fonction qui vous permettra d'utiliser un langage similaire à C #/Java pour inclure un fichier JavaScript. Je l'ai testé un peu, même à l'intérieur de un autre fichier JavaScript et il semble fonctionner. JQuery nécessite cependant un peu de "magie" à la fin.

J'ai placé ce code dans un fichier à la racine de mon répertoire de script (je l'ai nommé global.js, mais vous pouvez utiliser ce que vous voulez. Sauf erreur, jQuery devrait être le seul script requis sur une page donnée. Gardez à l'esprit ceci est en grande partie non testé au-delà de certaines utilisations de base, il peut donc y avoir ou non des problèmes avec la façon dont je l'ai fait; utilisez-le à vos risques et périls

/**
* @fileoverview This file stores global functions that are required by other libraries.
*/

if (typeof(jQuery) === 'undefined') {
    throw 'jQuery is required.';
}

/** Defines the base script directory that all .js files are assumed to be organized under. */
var BASE_DIR = 'js/';

/**
* Loads the specified file, outputting it to the <head> HTMLElement.
*
* This method mimics the use of using in C# or import in Java, allowing
* JavaScript files to "load" other JavaScript files that they depend on
* using a familiar syntax.
*
* This method assumes all scripts are under a directory at the root and will
* append the .js file extension automatically.
*
* @param {string} file A file path to load using C#/Java "dot" syntax.
*
* Example Usage:
* imports('core.utils.extensions');
* This will output: <script type="text/javascript" src="/js/core/utils/extensions.js"></script>
*/
function imports(file) {
    var fileName = file.substr(file.lastIndexOf('.') + 1, file.length);

    // Convert PascalCase name to underscore_separated_name
    var regex = new RegExp(/([A-Z])/g);
    if (regex.test(fileName)) {
        var separated = fileName.replace(regex, ",$1").replace(',', '');
        fileName = separated.replace(/[,]/g, '_');
    }

    // Remove the original JavaScript file name to replace with underscore version
    file = file.substr(0, file.lastIndexOf('.'));

    // Convert the dot syntax to directory syntax to actually load the file
    if (file.indexOf('.') > 0) {
        file = file.replace(/[.]/g, '/');
    }

    var src = BASE_DIR + file + '/' + fileName.toLowerCase() + '.js';
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;

    $('head').find('script:last').append(script);
}
7
Wayne Molina

Bien que ces réponses soient bonnes, il existe une "solution" simple qui existe depuis le chargement du script et qui couvre 99,999% des cas d'utilisation de la plupart des utilisateurs. Incluez simplement le script dont vous avez besoin avant le script qui l’exige. Pour la plupart des projets, il ne faut pas longtemps pour déterminer quels scripts sont nécessaires et dans quel ordre.

<!DOCTYPE HTML>
<html>
    <head>
        <script src="script1.js"></script>
        <script src="script2.js"></script>
    </head>
    <body></body>
</html>

Si script2 nécessite script1, il s'agit du moyen le plus simple et absolu de procéder de la sorte. Je suis très surpris que personne n'en ait parlé, car c'est la réponse la plus évidente et la plus simple qui puisse s'appliquer dans presque tous les cas.

6
KthProg

Il y a plusieurs façons d'implémenter des modules en Javascript. Voici les 2 plus populaires:

Modules ES6

Les navigateurs ne supportent pas encore ce système de modulation. Pour utiliser cette syntaxe, vous devez utiliser un bundle tel que webpack. De toute façon, utiliser un bundle est préférable car cela peut combiner tous vos fichiers différents en un seul (ou plusieurs fichiers associés). Cela servira les fichiers du serveur au client plus rapidement, car chaque requête HTTP est associée à une surcharge. Ainsi, en réduisant la requête HTTP globale, nous améliorons les performances. Voici un exemple de modules ES6: 

// main.js file

export function add (a, b) {
  return a + b;
}

export default function multiply (a, b) {
  return a * b;
}


// test.js file

import {add}, multiply from './main';   // for named exports between curly braces {export1, export2}
                                        // for default exports without {}

console.log(multiply(2, 2));  // logs 4

console.log(add(1, 2));  // logs 3

CommonJS (utilisé dans NodeJS)

Ce système de modulation est utilisé dans NodeJS. Vous ajoutez essentiellement vos exportations à un objet appelé module.exports. Vous pouvez ensuite accéder à cet objet via une require('modulePath'). Il est important de réaliser que ces modules sont mis en cache. Par conséquent, si vous require() un module donné à deux reprises, il retournera le module déjà créé.

// main.js file

function add (a, b) {
  return a + b;
}

module.exports = add;  // here we add our add function to the exports object


// test.js file

const add = require('./main'); 

console.log(add(1,2));  // logs 3
6
Willem van der Veen

Voici une solution de contournement pour les navigateurs (pas Node.js) utilisant des importations HTML.

Premièrement, toutes les classes et tous les scripts JavaScript ne figurent pas dans les fichiers .js, mais dans les fichiers .js.html (le .js .html doit simplement être reconnu entre les pages HTML et les scripts/classes JavaScript complets), à l'intérieur des balises <script>, comme ceci:

MyClass.js.html:

<script>
   class MyClass {

      // Your code here..

   }

</script>

Ensuite, si vous souhaitez importer votre classe, il vous suffit d'utiliser les importations HTML:

<link rel="import" href="relative/path/to/MyClass.js.html"/>

<script>
   var myClass = new MyClass();
   // Your code here..
</script>

EDIT: les importations HTML seront supprimées

Les importations HTML et les modules ES6 sont déjà bien implémentés dans la plupart des navigateurs du monde entier . Mais étant donné que les importations HTML ne feront certainement pas partie des normes, contrairement aux modules ES6, son développement sera abandonné. Vous devez donc commencer à utiliser les modules ES6.

6
Yairopro

Voici un plugin Grunt vous permettant d'utiliser la syntaxe @import "path/to/file.js"; dans tout fichier, y compris les fichiers JavaScript. Il peut être associé à uglify, à watch ou à n’importe quel autre plugin.

Il peut être installé avec npm install: https://npmjs.org/package/grunt-import

6
Marcin

Mieux vaut utiliser la méthode jQuery . Pour retarder l'événement ready, appelez d'abord $.holdReady(true). Exemple ( source ):

$.holdReady(true);
$.getScript("myplugin.js", function() {
    $.holdReady(false);
});
6
weageoo

Keep it Nice, court, simple et maintenable! :]

// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
    FULL_PATH + 'plugins/script.js'      // Script example
    FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library 
    FULL_PATH + 'plugins/crypto-js/hmac-sha1.js',      // CryptoJS
    FULL_PATH + 'plugins/crypto-js/enc-base64-min.js'  // CryptoJS
];

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

 // initialize a single load 
load('plugins/script.js');

// initialize a full load of scripts
if (s.length > 0)
{
    for (i = 0; i < s.length; i++)
    {
        load(s[i]);
    }
}

Ce code est simplement un bref exemple fonctionnel qui pourrait nécessite des fonctionnalités supplémentaires pour une prise en charge complète sur une plate-forme donnée (ou donnée).

5
tfont

Je le fais fondamentalement comme suit, en créant un nouvel élément et en joignant cela à head:

var x = document.createElement('script');
x.src = 'http://example.com/test.js';
document.getElementsByTagName("head")[0].appendChild(x);

Dans jQuery :

// jQuery
$.getScript('/path/to/imported/script.js', function()
{
    // Script is now loaded and executed.
    // Put your dependent JavaScript code here.
});
5
Rahul Srivastava

Pour NodeJS seulement, cela a fonctionné pour moi le meilleur!

J'ai essayé la plupart des solutions ici, mais aucune ne m'a permis de charger un autre fichier sans changer d'étendue. Enfin j'ai utilisé ça. Ce qui préserve la portée et tout. Il est aussi bon que votre code est dans ce point.

const fs = require('fs');
eval(fs.readFileSync('file.js')+'');
5
rturkek

C'est très simple. Supposons que vous souhaitiez importer le fichier A.js dans le fichier B.js.

Maintenant, il est certain que vous avez lié B.js dans un fichier HTML, puis liez simplement A.js avant B.js dans ce fichier HTML. Ensuite, les variables publiques de A.js seront disponibles à l'intérieur de B.js

Cela ne nécessite pas de réponse compliquée.

4

J'ai l'obligation de charger de manière asynchrone un tableau de fichiers JavaScript et de faire un rappel au dernier moment. Fondamentalement, ma meilleure approche est la suivante:

// Load a JavaScript file from other JavaScript file
function loadScript(urlPack, callback) {
    var url = urlPack.shift();
    var subCallback;

    if (urlPack.length == 0) subCallback = callback;
    else subCallback = function () {
        console.log("Log script: " + new Date().getTime());
        loadScript(urlPack, 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 = subCallback;
    script.onload = subCallback;

    // Fire the loading
    head.appendChild(script);
}

Exemple:

loadScript(
[
    "js/DataTable/jquery.dataTables.js",
    "js/DataTable/dataTables.bootstrap.js",
    "js/DataTable/dataTables.buttons.min.js",
    "js/DataTable/dataTables.colReorder.min.js",
    "js/DataTable/dataTables.fixedHeader.min.js",
    "js/DataTable/buttons.bootstrap.min.js",
    "js/DataTable/buttons.colVis.min.js",
    "js/DataTable/buttons.html5.min.js"
], function() { gpLoad(params); });

Le second script ne se chargera pas tant que le premier ne sera pas complètement chargé, et donc ...

Résultats:

 Result

4
MiBol

Si vous utilisez Angular, un module de plugin $ ocLazyLoad peut vous aider à le faire. 

Voici quelques extraits de sa documentation:

Chargez un ou plusieurs modules et composants avec plusieurs fichiers:

$ocLazyLoad.load(['testModule.js', 'testModuleCtrl.js', 'testModuleService.js']);

Chargez un ou plusieurs modules avec plusieurs fichiers et spécifiez un type si nécessaire: Remarque: lorsque vous utilisez le formatage de style requireJS (avec js! Au début par exemple), ne spécifiez pas d'extension de fichier. Utilise l'un ou l'autre.

$ocLazyLoad.load([
  'testModule.js',
   {type: 'css', path: 'testModuleCtrl'},
   {type: 'html', path: 'testModuleCtrl.html'},
   {type: 'js', path: 'testModuleCtrl'},
   'js!testModuleService',
   'less!testModuleLessFile'
]);

Vous pouvez charger des bibliothèques externes (non angulaires):

$ocLazyLoad.load(['testModule.js', 
   'bower_components/bootstrap/dist/js/bootstrap.js', 'anotherModule.js']);

Vous pouvez également charger des fichiers css et modèles:

 $ocLazyLoad.load([
     'bower_components/bootstrap/dist/js/bootstrap.js',
     'bower_components/bootstrap/dist/css/bootstrap.css',
     'partials/template1.html'
 ]);
4
gm2008

Importation et exportation de modules à l'aide de ES6 fonctionnant avec Node.js

Nommez les fichiers avec l'extension .mjs au lieu de .js

Créer des fichiers

touch main.mjs lib.mjs

main.js

import { add } from './lib.mjs';
console.log(add(40, 2));

lib.mjs

export let add = (x,y) => {
  return x + y
}

Courir

node --experimental-modules main.js
3
jasonleonhard

Maintenant, je suis peut-être totalement égaré, mais voici ce que j'ai récemment commencé à faire ... Commencez et finissez vos fichiers JavaScript avec un retour chariot, placez-le dans le script PHP, suivi d'un autre retour chariot . Le commentaire JavaScript "//" est ignoré par PHP, de sorte que l'inclusion se produit quand même. Le but des retours chariot est que la première ligne de votre JavaScript inclus ne soit pas commentée.

Techniquement, vous n'avez pas besoin du commentaire, mais il y a des erreurs dans Dreamweaver qui m'énervent. Si vous écrivez dans un IDE qui n'enregistre pas d'erreur, vous n'avez pas besoin du commentaire ni des retours à la ligne.

\n
//<?php require_once("path/to/javascript/dependency.js"); ?>

function myFunction(){
    // stuff
}
\n
3
Duncan
var s=["Hscript.js","checkRobert.js","Hscript.js"];
for(i=0;i<s.length;i++){
  var script=document.createElement("script");
  script.type="text/javascript";
  script.src=s[i];
  document.getElementsByTagName("head")[0].appendChild(script)
};
3
Robert A

N'oubliez pas de vérifier LAB.js !

<script type="text/javascript">
       $LAB
       .script("jquery-1.8.3.js").wait()
       .script("scripts/clientscript.js");      
</script>
3
emolaus

Dans un projet précédent, j'ai eu pas mal de succès en utilisant ajile pour importer des fichiers JavaScript réutilisables. J'ai toujours souhaité qu'il y ait une fonctionnalité pour cela intégrée à JavaScript lui-même.

3
jpierson

Une autre approche consiste à utiliser les importations HTML. Ceux-ci peuvent contenir des références de script ainsi que des références de feuille de style.

Vous pouvez simplement lier un fichier HTML comme

<link rel="import" href="vendorScripts.html"/>

Dans le fichier vendorScripts.html, vous pouvez inclure vos références de script telles que:

<script src="scripts/vendors/jquery.js"></script>
<script src="scripts/vendors/bootstrap.js"></script>
<script src="scripts/vendors/angular.js"></script>
<script src="scripts/vendors/angular-route.js"></script>

Regardez HTML Imports pour plus de détails.

Malheureusement, cela ne fonctionne que dans Chrome.

2
gabriel211

Vous ne pouvez pas importer, mais vous pouvez référencer.

PhpShtorm IDE. Pour référencer un fichier .js à un autre .js, ajoutez-le simplement en haut du fichier:

<reference path="../js/file.js" />

Bien sûr, vous devez utiliser votre propre PATH dans le fichier JavaScript.

Je ne sais pas si cela fonctionnera dans d'autres IDE. Probablement oui, juste essayer. Cela devrait également fonctionner dans Visual Studio.

2

Oui, il y a ...

Continuez à lire, dans ES6, nous pouvons export et import une partie ou un fichier javascript entier en un autre ...

Mais attendez, ES6 n'est pas pris en charge par tous les navigateurs. Vous avez donc besoin de le transpiler à l'aide de babel.js par exemple ...

Donc, vous créez une classe comme ci-dessous:

class Person {
  constructor(name) {
    this.name = name;
  }

  build() {
    return new Person(this);
  }
}

module.exports = Person;

dans un autre fichier JavaScript, effectuez l'importation comme suit:

import { Person } from 'Person';

Vous pouvez également exiger le fichier comme:

const Person = require('./Person');

Si vous utilisez une version plus ancienne de JavaScript, vous pouvez utiliser 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".
});

Si vous voulez vous en tenir à l'ancienne version de fichiers, comme jQuery, vous pouvez également utiliser quelque chose comme getScript:

jQuery.getScript('./another-script.js', function() {
    // Call back after another-script loaded
});

Dernier point mais non le moindre, n'oubliez pas que vous pouvez utiliser la méthode traditionnelle de création de script à l'aide de la balise <script> ...

<script src="./first-script.js"></script>
<script src="./second-script.js"></script>
<script src="./third-script.js"></script>

Il y a aussi les attributs async et defer que je devrais les mentionner ici ...

Remarque: Un script externe peut être exécuté de plusieurs manières:

  • Si async est présent: le script est exécuté de manière asynchrone avec le reste de la page (le script sera exécuté pendant que la page continue l'analyse)
  • Si async n'est pas présent et diffère est present: le script est exécuté à la fin de la page analyse
  • Si ni asynchrone ni différé n'est présent: Le script est récupéré et exécuté immédiatement, avant que le navigateur ne continue analyser la page
2
Alireza

Voici peut-être un autre moyen! Dans Node.js, vous procédez comme suit! http://requirejs.org/docs/node.html

sub.js

module.exports = {
  log: function(string) {
    if(console) console.log(string);
  }
  mylog: function(){
    console.log('just for log test!');
  }
}

main.js

var mylog =require('./sub');

mylog.log('Hurray, it works! :)');
mylog.mylog();
2
xgqfrms

J'ai essayé ce problème avec une autre approche,

La commande d’importation de script n’a aucun effet ici.

index.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Trials</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="main.js"></script>
    <script src="scriptA.js"></script>
</head>

<body>
<h3>testing js in js (check console logs)</h3>
<button onclick="fnClick()">TEST</button>
</body>

</html>

main.js

function fnClick() {
  console.log('From\tAAAAA');
  var pro = myExpo.hello();
  console.log(pro);
}

scriptA.js

myExpo = {
    hello: function () {
        console.log('From\tBBBBB');
        return "Hello";
    }
}

et le résultat est

From    AAAAA
From    BBBBB
Hello
1
Milton Ain

ES6: OUI, utilisez type = "module" dans la balise de script ( support )

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

Et dans le fichier script.js, incluez un autre fichier comme celui-ci:

import { hello } from './module.js';
...
// alert(hello());

Dans 'module.js', vous devez fonction/classe d'exportation que vous importerez

export function hello() {
    return "Hello World";
}

Travailler exemple ici .

1
Kamil Kiełczewski

Si vous constatez que deux scripts ou plus occupent la même fonction lors de leur appel, nous ne pouvons pas les inclure dans les mêmes temps, nous devons le faire dynamiquement par sélection de l'utilisateur.

L'inclusion d'autres fichiers dans jQuery à l'aide de $.getScript fonctionne puisque le script ne sera pas mis en cache par défaut . Nous sommes donc en sécurité pour appeler un autre script. Les appels peuvent être organisés comme ceci:

HTML

<select class="choice">
  <option value="script1" selected>Script-1</option>
  <option value="script2">Script-2</option>
</select>

JS 

  $(".choice").change(on_change);

    var url = "https://example.com";
    $.url1 = url + "/script1.js";
    $.url2 = url + "/script2.js";

  function on_change() {
    if ($(".choice").val()=="script1") {
        script1();
    } else {
        script2();
    }

    // script1
    function script1() {   
      $.getScript($.url1, function( data, textStatus, jqxhr ) {
          //excecute here
      });  
    }

    // script2
    function script2() {
       $.getScript($.url2, function( data, textStatus, jqxhr ) {
          //excecute here
      });  
    }
0
Chetabahana

Little Extend pour libérer de answer @Dan Dascalescu tiré de facebook idea.

(function() {   
var __ = {};
this._ = function(name, callback) {
    if(__[name]==undefined) {
        __[name] = true;
        var firstScript = document.getElementsByTagName('script')[0],
          js = document.createElement('script');
          js.src =  name;
          js.onload = callback;
          firstScript.parentNode.insertBefore(js, firstScript);
    }
}
})();

(new _('https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js', function() {
 snowStorm.snowColor = '#99ccff';
}));
0
Kamil Dąbrowski

Veuillez noter que nous utilisons habituellement scripts statiques _. Nous voulons donc tirer le meilleur parti possible du cache .

Utilisation

$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
  console.log( textStatus );
});

L'option cache: true a été ajoutée à la méthode ajax.

0
Adam111p
var xxx = require("../lib/your-library.js")

ou

import xxx from "../lib/your-library.js" //get default export
import {specificPart} from '../lib/your-library.js' //get named export
import * as _name from '../lib/your-library.js'  //get full export to alias _name
0
Mesut Yiğit

Vous pouvez utiliser mon loadScript ES module pour le chargement des fichiers javaScript.

Usage:

Dans votre balise head, incluez le code suivant:

<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.js"></script>

ou

<script src="https://raw.githack.com/anhr/loadScriptNodeJS/master/build/loadScript.min.js"></script>

Vous pouvez maintenant utiliser window.loadScript pour charger vos fichiers JavaScript.

loadScript.async (src, [options])

Fichier JavaScript à chargement asynchrone.

src: URL d'un fichier de script externe ou tableau des noms de fichier de script.

options: les options suivies sont disponibles

onload: function () The onload event occurs when a script has been loaded. Default is undefined.

onerror: function ( str, e ) The onerror event occurs when an error has been occured. Default is undefined.

    str: error details

    e: event

appendTo: The node to which the new script will be append. Default is head node.

Par exemple

loadScript.async( "JavaScript.js",
        {
            onload: function () {

                var str = 'file has been loaded successfully';
                console.log( str );

            },
            onerror: function ( str, e ) {

                console.error( str );

            },

        } );

Exemple d'utilisation

0
Andrej

Chargement dynamique de plusieurs scripts dans l'ordre

La fonction ci-dessus fonctionne correctement si vous ne chargez qu'un seul script ou si vous ne vous souciez pas de l'ordre de chargement de plusieurs scripts. Si certains scripts dépendent d’autres, vous devez utiliser Promise pour spécifier l’ordre de chargement. La raison derrière ceci est que Javascript charge des ressources telles que des scripts et des images de manière asynchrone. La séquence de chargement ne dépend pas de la séquence d'appels asynchrones, ce qui signifie que le chargement de script1 avant ce script ne sera pas garanti, même si vous appelez dynamicallyLoadScript("scrip1") avant d'appeler dynamicallyLoadScript("scrip2")

Voici donc une autre version de dynamicallyLoadScript qui garantit l’ordre de chargement:

// Based on: https://javascript.info/promise-basics#example-loadscript
function dynamicallyLoadScript(url) {
        return new Promise(function(resolve, reject) {
        var script = document.createElement("script");
        script.src = url;
        script.onload = resolve;
        script.onerror = () => reject(new Error(`Error when loading ${url}!`));
        document.body.appendChild(script);
    });

Pour plus sur Promises, voir cette excellente page .

L'utilisation de ce nouveau script dynamiquement LoadScript est très simple:

dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => dynamicallyLoadScript("script4.js"))
.then(() => dynamicallyLoadScript("script5.js"))
//...

Maintenant, les scripts sont chargés dans l'ordre suivant: script1.js, script2.js, script3.js, etc.

Exécuter le code dépendant après le chargement du script

De plus, vous pouvez immédiatement exécuter du code qui utilise les scripts après leur chargement. Ajoutez simplement un autre .then après le chargement du script:

dynamicallyLoadScript("script1.js")
.then(() => dynamicallyLoadScript("script2.js"))
.then(() => foo()) // foo can be a function defined in either script1, script2
.then(() => dynamicallyLoadScript("script3.js"))
.then(() => {
     if (var1){ // var1 can be a global variable defined in either script1, script2, or script3
          bar(var1); // bar can be a function defined in either script1, script2, or script3
     } else {
          foo(var1);
     }
})
//more .then chains...

Traiter les erreurs de chargement

Pour afficher les rejets de promesses non gérées (erreurs de chargement des scripts, etc.), placez cet écouteur d'événements unhandledrejection en haut de votre code:

// Based on: https://javascript.info/promise-error-handling#unhandled-rejections
window.addEventListener('unhandledrejection', function(event) {
     // the event object has two special properties:
     console.error(event.promise);// the promise that generated the error
     console.error(event.reason); // the unhandled error object
});

Maintenant, vous serez averti de toute erreur de chargement de script.


Fonction de raccourci

Si vous chargez beaucoup de scripts sans exécuter de code immédiatement après le chargement, cette fonction abrégée peut s'avérer utile:

function dynamicallyLoadScripts(urls){
        if (urls.length === 0){
            return;
        }
        let promise = dynamicallyLoadScript(urls[0]);
        urls.slice(1).forEach(url => {
            promise = promise.then(() => dynamicallyLoadScript(url));
        });
    }

Pour l'utiliser, il suffit de passer un tableau d'URL de script comme ceci:

const scriptURLs = ["dist/script1.js", "dist/script2.js", "dist/script3.js"];
dynamicallyLoadScripts(scriptURLs);

Les scripts seront chargés dans l'ordre dans lequel ils apparaissent dans le tableau.

0
AlienKevin