On ne peut pas inclure un script dans un script en JS dans un navigateur Web. Il n’y a pas de mot clé import
, include
ou require
.
On peut néanmoins trouver un moyen d’inclure du code en le téléchargeant et en l’incluant dans la page.
Solution 1, la bourrine
On peut faire une requête GET et un eval sur
. C’est dangereux. C’est bancal. Ca marche que pour le domaine en cours. C’est pas une bonne idée. Je ne vous le montre donc pas.
Solution 2, la maline
On va créer une balise <script></script>
et la faire pointer sur le fichier à télécharger. Ainsi on utilise le mécanisme naturel pour le navigateur d’include du code.
var include = function(url, callback){ /* on crée une balise<script type="text/javascript"></script> */ var script = document.createElement('script'); script.type = 'text/javascript'; /* On fait pointer la balise sur le script qu'on veut charger avec en prime un timestamp pour éviter les problèmes de cache */ script.src = url + '?' + (new Date().getTime()); /* On dit d'exécuter cette fonction une fois que le script est chargé */ if (callback) { script.onreadystatechange = callback; script.onload = script.onreadystatechange; } /* On rajoute la balise script dans le head, ce qui démarre le téléchargement */ document.getElementsByTagName('head')[0].appendChild(script); } |
Ca s’utilise comme ça:
include('http://adressedemonscript.com/fichier.js', function() { code à exécuter une fois que le script est chargé }) |
La partie callback est très importante. En effet, si vous essayez d’exécuter du code après include()
qui dépend du code chargé par include()
, ça va foirer : le code n’est pas encore téléchargé. En effet, les navigateurs téléchargent les balises scripts en arrière plan et en parallèle :
include('http://adressedemonscript.com/fichier.js'); code à exécyter une fois que le script est chargé |
Il faut donc mettre ce code dans un callback, pour garantir qu’il soit lancé quand le script a terminé de chargé.
Solution 3, la coquine
jQuery, encore et toujours, possède un raccourcis pour faire tout ça pour vous:
$('http://adressedemonscript.com/fichier.js', function() { code à exécuter une fois que le script est chargé }) |
Le mieux reste tout de même de passer par de vrais outils comme RequireJS, IncludeJs, CommonJs… qui respectes la norme des WebModules et AMD. Beaucoup plus souple et pratique.
De plus, ta solution 2 executera la callback avant l’execution du script sur certains navigateurs (IE par exemple)
Bonne année !
J’allais pester promptement contre le fait de rajouter ENCORE 20 Mo de JS mais je viens de réaliser includejs fait 800b :-)
Le code source de includejs est très instructif, et par ailleurs les commentaires sont hillarants:
https://github.com/CapMousse/include.js/blob/master/include.js
Je suis pas un cador du javascript, mais j’ai l’impression qu’il y a une accolade de trop dans le code de la solution maline :
if (callback) {
}(trip)
C’est certainement du à une overdose de “free hugs”. Quand on reçoit trop d’accolades gratuites, après, on ne sait plus quoi un faire.
Tiens ça me fait penser à l’entreprise de jeux vidéos qui avait sorti Elvira: Mistress Of the Dark. Elle s’appelait Accolade. Ah ce jeu était génial. Se faire déchirer la trachée par un loup-garou, énucléer par un vautour ou décapiter et bouillir dans une marmite, ça n’a pas de prix. En plus on voyait ses nichons (à Elvira).
Tiens ça me fait penser à un pote qui se promenait dans les festivaux avec un T-Shirt sur lequel était écrit “Free Coït”.
(/trip)
C’est fort juste mon cher et Recher.
Ne manquerait-il pas la vieille (et assez controversée) technique du document.write() ? Elle est certes synchrone et généralement bloquante mais aussi très simple car elle ne nécessite pas de passer par un callback et est supportée par tous les navigateurs de ce siècle.
Ajoute mon bon, ajoute. Je ne la connait point.
Voilà :
function require(url) {
document.writeln("<script src='" + url + "'><" + "/script>");
}
Avec un fichier test.js contenant :
alert("Après injection : " + (typeof window.$ != "undefined"));
Le code ci-dessous affichera “true”
require("http://code.jquery.com/jquery.min.js");
require("test.js");
Si je ne m’abuse, document.writeln ne fonctionne que lors du parsing du DOM. Donc si on veut ajouter dynamiquement un script apres une action utilisateur par exemple, ca ne fonctionnera pas. Selon le navigateur ca donnera meme une belle page blanche.
C’est surement une des raisons pour laquelle cette technique est controversee en effet, mais je pense que la precision est importante :)
Oui Greg, tu as raison, la précision méritait d’être faite. Mais bon, manifestement, ça n’intéresse pas l’auteur du post.
WTF ?
Ah si, désolé, il vient de poster “WTF ?”
Allez parce que je suis gentil, j’ajoute quelques liens utiles relatifs au chargement dynamique des scripts en JS:
– pourquoi il ne faut pas utiliser appendChild
– pourquoi il ne faut pas affecter systématiquement onreadystatechnaged
Qu’ai donc dit qui mérite ce “sticker” “ERIC CARTMAN” ?
Pas mal ce lien sur appendChild oui. Je suis un chanceux, je peux me passer d’IE 6 et ses bugs.
Pour information, les web workers implémentent importScripts()
http://www.w3.org/TR/workers/#dom-workerglobalscope-importscripts
Bien sur, les scripts importés ne sont utilisable que depuis le contexte du worker (qui communique cependant avec le contexte principal)
Sympas. Quel nav implémente ça ?
http://www.debeug.com/questions/210/comment-inclure-un-fichier-javascript-dans-un-autre-fichier-javascript
C’est un google translate copier/coller d’un article de stack overflow.
http://code.seebz.net/p/include/
j’ai trouvé ça et ça fonctionne plutôt bien
Je peux dire une connerie (?) ?
Si je place tout bêtement le fichier javascript “commun” dans la page qui utilise un autre fichier javascript qui a besoin de ce “commun” ?!
Exemple:
//a la fin du body
C’est mal ? C’est idiot ? Ça marche pas dans tous les cas ?
Je me sert de cette technique pour mes libs locales…
Le code est pas passé…
//A la fin du body
Autant pour moi, faut que j’enlève les balises “scripts” ^^
//A la fin du body
script type="text/javascript" src="/static/js/common.js" #/script
script type="text/javascript" src="/static/js/produit.js" #/script
Tout le but de l’article est d’expliquer comment le faire dynamiquement. Ceci afin par exemple de charger une ressource en fonction du comportement de l’utilisateur ou pour faire du lazy loading.