Come posso includere un file JavaScript in un altro file JavaScript?


5194

C'è qualcosa in JavaScript simile a @importCSS che ti consente di includere un file JavaScript all'interno di un altro file JavaScript?



82
@Daniel, non voglio usare una chiamata AJAX.
Alec Smart,

13
Perché non dichiarare il file importato prima dell'altro che lo richiede, semplicemente usando i scripttag ordinati ?
falsarella,

6
@Claudiu Ciò non aiuterebbe a importare nulla, ma dovrebbe funzionare anche. Se si dispone di un file JS che dipende da un altro file JS, dichiarare prima i tag di script dei file delle dipendenze, quindi in seguito verranno già caricate le dipendenze. Se hai una situazione in cui non è un approccio possibile, le risposte qui dovrebbero essere utili.
falsarella,

1
qual è il vantaggio pratico di farlo? in entrambi i casi la base di codice dipendente dal file javascript non verrà caricata e inizierà a funzionare in ogni caso non viene caricata!
Ciasto piekarz,

Risposte:


4472

Le vecchie versioni di JavaScript non avevano importazione, inclusione o richiesta, quindi sono stati sviluppati molti approcci diversi a questo problema.

Ma dal 2015 (ES6), JavaScript ha lo standard di moduli ES6 per importare moduli in Node.js, che è supportato anche dalla maggior parte dei browser moderni .

Per la compatibilità con i browser più vecchi, crea strumenti come Webpack e Rollup e / o strumenti di transpilation come Babel .

Moduli ES6

I moduli ECMAScript (ES6) sono supportati in Node.js dalla v8.5, con il --experimental-modulesflag e almeno da Node.js v13.8.0 senza il flag. Per abilitare "ESM" (vs. precedente sistema di moduli CommonJS stile di Node.js [ "CJS"]) si sia per uso "type": "module"in package.jsono dare i file l'estensione .mjs. (Allo stesso modo, i moduli scritti con il precedente modulo CJS di Node.js possono essere nominati .cjsse il tuo valore predefinito è ESM.)

Utilizzando package.json:

{
    "type": "module"
}

Quindi module.js:

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

Quindi main.js:

import { hello } from './module.js';
let val = hello();  // val is "Hello";

Usando .mjs, avresti module.mjs:

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

Quindi main.mjs:

import { hello } from './module.mjs';
let val = hello();  // val is "Hello";

Moduli ECMAScript nei browser

I browser hanno supportato il caricamento diretto dei moduli ECMAScript (non sono richiesti strumenti come Webpack) da Safari 10.1, Chrome 61, Firefox 60 e Edge 16. Controlla l'attuale supporto su caniuse . Non è necessario utilizzare l' .mjsestensione Node.js ; i browser ignorano completamente le estensioni dei file su moduli / script.

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

Maggiori informazioni su https://jakearchibald.com/2017/es-modules-in-browsers/

Importazioni dinamiche nei browser

Le importazioni dinamiche consentono allo script di caricare altri script secondo necessità:

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

Maggiori informazioni su https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js richiede

Il vecchio stile del modulo CJS, ancora ampiamente utilizzato in Node.js, è il sistema module.exports/require .

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

Esistono altri modi in cui JavaScript può includere contenuti JavaScript esterni nei browser che non richiedono la preelaborazione.

Caricamento AJAX

È possibile caricare uno script aggiuntivo con una chiamata AJAX e quindi utilizzarlo evalper eseguirlo. Questo è il modo più semplice, ma è limitato al tuo dominio a causa del modello di sicurezza sandbox JavaScript. L'utilizzo evalapre anche la porta a bug, hack e problemi di sicurezza.

Caricamento in corso

Come Dynamic Imports, puoi caricare uno o più script con una fetchchiamata usando le promesse per controllare l'ordine di esecuzione delle dipendenze degli script usando la libreria 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)}`)
})

Caricamento jQuery

La libreria jQuery fornisce funzionalità di caricamento su una riga :

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

Caricamento di script dinamico

È possibile aggiungere un tag di script con l'URL dello script in HTML. Per evitare il sovraccarico di jQuery, questa è una soluzione ideale.

Lo script può persino risiedere su un altro server. Inoltre, il browser valuta il codice. Il <script>tag può essere inserito nella pagina Web <head>o inserito appena prima del </body>tag di chiusura .

Ecco un esempio di come potrebbe funzionare:

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

Questa funzione aggiungerà un nuovo <script>tag alla fine della sezione head della pagina, dove ilsrc attributo è impostato sull'URL che viene assegnato alla funzione come primo parametro.

Entrambe queste soluzioni sono discusse e illustrate in JavaScript Madness: Dynamic Script Loading .

Rilevare quando lo script è stato eseguito

Ora, c'è un grosso problema che devi conoscere. Ciò implica che si carica in remoto il codice . I browser Web moderni caricheranno il file e continueranno a eseguire lo script corrente perché caricano tutto in modo asincrono per migliorare le prestazioni. (Questo vale sia per il metodo jQuery che per il metodo di caricamento manuale degli script dinamici.)

Significa che se usi questi trucchi direttamente, non sarai in grado di usare il tuo nuovo codice caricato nella riga successiva dopo che hai chiesto di caricarlo , perché continuerà a caricarsi.

Ad esempio: my_lovely_script.jscontiene 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

Quindi ricarichi la pagina colpendo F5. E funziona! Confondere ...

Quindi cosa fare al riguardo?

Bene, puoi usare l'hack che l'autore suggerisce nel link che ti ho dato. In breve, per le persone che vanno di fretta, usa un evento per eseguire una funzione di richiamata quando viene caricato lo script. Quindi puoi inserire tutto il codice usando la libreria remota nella funzione di callback. Per esempio:

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

Quindi scrivi il codice che vuoi usare DOPO che lo script è caricato in una funzione lambda :

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

Quindi esegui tutto ciò:

loadScript("my_lovely_script.js", myPrettyCode);

Si noti che lo script può essere eseguito dopo il caricamento del DOM o prima, a seconda del browser e se è stata inclusa la riga script.async = false;. C'è un ottimo articolo sul caricamento di Javascript in generale che ne discute.

Unione / preelaborazione del codice sorgente

Come accennato all'inizio di questa risposta, molti sviluppatori usano strumenti di compilazione / transpilazione come Parcel, Webpack o Babel nei loro progetti, consentendo loro di utilizzare la sintassi JavaScript imminente, fornire compatibilità con le versioni precedenti per i browser più vecchi, combinare file, minimizzare, eseguire la suddivisione del codice ecc.


130
No, ma qualcuno che usa qualcosa di avanzato come Rhino o altro non farebbe questa domanda.
e-soddisfa il

192
Per essere completi, esiste un terzo modo: in alcune soluzioni quando controlli entrambi i file javascript, puoi semplicemente creare 1 file javascript gigante che combina il contenuto di entrambi i file.
Rospo,

20
Dovrei "document.createElement (" my_lovely_script.js ");" nell'esempio essere "document.createElement (" script ")"?
Russell Silva,

14
In che modo eval apre la porta agli hack se sta eseguendo il tuo codice?
Vince Panuccio,

6
La tua risposta richiede alcune modifiche per IE ( onreadystatechangeevento e readyStateproprietà). Inoltre, il caricamento dinamico degli script non beneficia degli scanner precaricati di Broswer. Consiglia questo articolo HTML5Rocks: html5rocks.com/en/tutorials/speed/script-loading
ruhong

570

Se qualcuno è alla ricerca di qualcosa di più avanzato, prova RequireJS . Otterrai ulteriori vantaggi come la gestione delle dipendenze, una migliore concorrenza ed eviterai la duplicazione (ovvero il recupero di uno script più di una volta).

Puoi scrivere i tuoi file JavaScript in "moduli" e quindi fare riferimento a loro come dipendenze in altri script. Oppure puoi usare RequireJS come una semplice soluzione "vai a prendere questo script".

Esempio:

Definire le dipendenze come moduli:

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

Implement.js è il tuo file JavaScript "principale" che dipende da some-dependency.js

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

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

Estratto dal file README di GitHub :

RequireJS carica file JavaScript semplici e moduli più definiti. È ottimizzato per l'uso nel browser, incluso in un Web Worker, ma può essere utilizzato in altri ambienti JavaScript, come Rhino e Node. Implementa l'API del modulo asincrono.

RequireJS utilizza tag di script semplici per caricare moduli / file, quindi dovrebbe consentire un debug semplice. Può essere usato semplicemente per caricare file JavaScript esistenti, quindi è possibile aggiungerlo al progetto esistente senza dover riscrivere i file JavaScript.

...


1
@aaaidan: la ragione di MattDmo si basa su una libreria esterna che a sua volta si basa sulla risposta accettata.
David Mulder,

1
Per superare request.js il più recente sarebbe js angolare che è più stabile e facile da usare insieme ad altre funzionalità HTML e di associazione vincolanti.
zeeshan,

5
-1: Quelle astrazioni - "some_dependency" - sono davvero povere, con indici che aggiungono confusione. Faccio fatica a capire come appare un esempio di codice funzionante. Se l'autore fornisse un esempio funzionante, quasi tutti sarebbero in grado di adattarlo e generalizzarlo alle sue esigenze.
Tegiri Nenashi,

1
non funziona bene con MVC e bundle di script con minificazione automatica
Triynko

1
'aggiungi .. senza dover riscrivere i tuoi file JavaScript'; bello, ma esattamente? Cur. la risposta suggerisce di aggiungere un tale "richiesta" (non "requisito"?) allo script principale + tale "definizione" per ogni file dipendente, sì? Ma che IS riscrive quindi cosa non riscritto? -rest del codice in quanto RequireJS consente a ea file di eseguire normalmente le def. globali? lo fa? Ho appena provato a farlo , + (dimenticato?) <Script src = " requirejs.org/docs/release/2.2.0/comments/require.js "> </script>, quindi 'requirejs ([' GoogleDrive.com/host /..',.. lasting,function (a, b) {mycode}) ': Firebug dice a tutti i dipendenti caricati MA i loro valori non definiti in mycode & after.
Destiny Architect,

195

In realtà c'è un modo per caricare un file JavaScript no in modo asincrono, così si potrebbe utilizzare le funzioni incluse nella vostra destra file appena caricato dopo il caricamento di esso, e penso che funziona in tutti i browser.

Devi utilizzare jQuery.append()l' <head>elemento della tua pagina, ovvero:

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

Tuttavia, questo metodo ha anche un problema: se si verifica un errore nel file JavaScript importato, Firebug (e anche Firefox Error Console e Chrome Developer Tools ) segnalerà la sua posizione in modo errato, il che è un grosso problema se si utilizza Firebug per tracciare Errori JavaScript molto giù (lo faccio). Firebug semplicemente non conosce il file appena caricato per qualche motivo, quindi se si verifica un errore in quel file, segnala che si è verificato nel tuo HTML principale file e avrai difficoltà a scoprire il vero motivo dell'errore.

Ma se questo non è un problema per te, allora questo metodo dovrebbe funzionare.

In realtà ho scritto un plugin jQuery chiamato $ .import_js () che utilizza questo metodo:

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

Quindi tutto ciò che dovresti fare per importare JavaScript è:

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

Ho anche fatto un semplice test per questo in Esempio .

Include un main.jsfile nell'HTML principale e quindi lo script main.jsutilizzato $.import_js()per importare un file aggiuntivo chiamato included.js, che definisce questa funzione:

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

E subito dopo l'inclusione included.js, la hello()funzione viene chiamata e viene visualizzato l'avviso.

(Questa risposta è in risposta al commento di e-satis).


Sto provando questo metodo, ma non funziona per me, l'elemento non appare nel tag head.
siti del

16
@juanpastas - usa jQuery.getScript, in questo modo non devi preoccuparti di scrivere il plugin ...
MattDMo

6
Hmm, secondo questo articolo , l'aggiunta di un scriptelemento headcauserà l'esecuzione in modo asincrono, a meno che non asyncsia specificatamente impostato su false.
Flimm,

1
La variabile di script non dovrebbe essere codificata in entità html? Se il link contiene ", il codice si interromperà
RedClover

1
@Flimm caro signore, io e il mio team ringraziamo per il tuo commento e ti devo personalmente una birra di soldi pari se mai ci incontriamo di persona
Alex

155

Un altro modo, che secondo me è molto più pulito, è fare una richiesta Ajax sincrona invece di usare un <script>tag. Questo è anche il modo in cui Node.js gestisce.

Ecco un esempio usando 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);
        }
    });
}

Puoi quindi usarlo nel tuo codice come di solito usi un include:

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

Ed essere in grado di chiamare una funzione dallo script richiesto nella riga successiva:

subscript.doSomethingCool(); 

1
Buona soluzione, la testa include purtroppo asincrona, la soluzione ajax funziona.
Matteo Conta,

17
Come qualcun altro ha menzionato, requestjs.org fa questo e ha anche un pre-compilatore che mette insieme i file js in modo che vengano caricati più velocemente. Potresti volerlo controllare.
Ariel,

2
Ho scoperto che potevo eseguire il debug aggiungendo questa direttiva nella parte inferiore del file per Chrome: // @ sourceURL = view_index.js
Todd Vance

11
sfortunatamente, asincrono: false è ora deprecato in jQuery. Potrebbe rompersi in futuro, quindi eviterei.
sqram

3
@katsh Non stiamo usando oggetti jqXHR qui. La tua citazione non sembra sostenere il tuo precedente commento affermando che async: falsepresumibilmente è deprecato. Non è! Come afferma la tua citazione, solo le cose relative a jqXHR lo sono.
Zero3,

101

C'è una buona notizia per te. Molto presto sarai in grado di caricare facilmente il codice JavaScript. Diventerà un modo standard di importare moduli di codice JavaScript e farà parte del core JavaScript stesso.

Devi semplicemente scrivere import cond from 'cond.js';per caricare una macro chiamata condda un file cond.js.

Quindi non devi fare affidamento su alcun framework JavaScript né devi effettuare esplicitamente chiamate Ajax .

Fare riferimento a:


12
require / import sul jsfile è stato troppo a lungo in arrivo. (IMO).
rwheadon,

6
@rwheadon yeah sembra spaventoso che questo non faccia parte della lingua! Come la gente fa qualsiasi cosa è oltre me! Sono nuovo e questo sembra il peggio (di molti) pezzi di follia
JonnyRaa,

@ jonny-leeds Anche senza caricamento del modulo integrato, JavaScript nel browser è abbastanza flessibile da poter implementare una libreria come RequireJS per la gestione dei nostri moduli.
Appassionato del

8
metà 2015- Ancora non implementato in nessun browser, developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
scape

si hai ragione. ora sto iniziando a sentirmi male per questo :(. Thouh, una volta implementato in tutti i browser questa sarà una grande funzionalità integrata in javascript.
Imdad

97

È possibile generare dinamicamente un tag JavaScript e aggiungerlo al documento HTML da un altro codice JavaScript. Questo caricherà il file JavaScript di destinazione.

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

8
@ e-satis - In realtà, questo è un vantaggio, uno script di sincronizzazione bloccherebbe. Cavalli per i corsi, ma 9 volte su 10 vuoi l'opzione non bloccante.
annakata,

@Svitlana - gli elementi di script creati in questo modo sono asincroni. Attualmente questo potrebbe essere visto come lo sfruttamento di una scappatoia, quindi potrebbe non essere una prova futura, non ho visto nulla in nessuno standard che chiarisca questo.
annakata,

In realtà lo riprendo, ho notato che stai aggiungendo al corpo piuttosto che alla testa.
annakata,

@annakata: qual è la differenza? A proposito, Yahoo suggerisce di aggiungere tag di script alla fine del corpo, quindi nulla dovrebbe sbagliare con esso quando si aggiunge dinamicamente.
Svitlana Maksymchuk,

7
@ e-satis asincrono è buono perché non congela la tua pagina. Usa il callback per ricevere una notifica al terminejs.onload = callback;
Vitim.us

74

La dichiarazione importè in ECMAScript 6.

Sintassi

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;

... ma non è supportato da nessun browser fino ad oggi, secondo la tabella di compatibilità nella pagina a cui ti sei collegato.
Zero3,

6
Ora puoi scrivere il codice ES6 e compilarlo con Babel.js ( babeljs.io ) in qualunque sia il tuo sistema di moduli preferito (CommonJS / AMD / UMD): babeljs.io/docs/usage/modules
Jeremy Harris

@ Zero3 Apparentemente il nuovo IE (Edge) è l'unico
Julian Avar il

nel 2019 IE continua a non supportarlo in nessuna forma. Perché Microsoft deve essere così contrario all'usabilità?
GreySage,

61

Forse puoi usare questa funzione che ho trovato in questa pagina Come posso includere un file JavaScript in un file 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)
}

5
Dovrebbe essere utile aggiungerescript.onload = callback;
Vitim.us

@SvitlanaMaksymchuk quindi, se non uso var, la variabile sarà globale?
Francisco Corrales Morales,

@FranciscoCorrales sì.
Christopher Chiche,

Finisce in globale con o senza il var :)
Vedran Maricevic.


54

Ecco una versione sincrona senza 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);
}

Si noti che per far funzionare questo interdominio, il server dovrà impostare l' allow-originintestazione nella sua risposta.


Funzione eccellente! Carica JavaScript prima che qualsiasi ulteriore JS venga scritto dopo il corpo. Molto importante quando si caricano più script.
martedì

3
@heinob: cosa posso fare per farlo funzionare su più domini? (caricamento script da http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js)
user2284570

@ user2284570: se sei il proprietario di un dominio straniero: imposta l'intestazione `allow-origin 'nella risposta del server. Se non sei il proprietario: niente. Scusate! Questa è la politica di origine incrociata.
Heinob,

2
@ user2284570: capisco il tuo commento in quel modo, che non sei il proprietario del dominio da cui vuoi caricare lo script. In tal caso, puoi solo caricare uno script tramite un <script>tag inserito , non tramite XMLHttpRequest.
Heinob,

2
Per coloro che hanno intenzione di utilizzare questo in Firefox (diciamo per imacros scripting), aggiungi questa riga nella parte superiore del file:const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
Kwestion

49

Ho appena scritto questo codice JavaScript (usando Prototype per la manipolazione del DOM ):

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

Uso:

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


7
jrburke ha scritto questo come RequireJS. Github: requirejs.org/docs/requirements.html
Mike Caron

Questo non sta mettendo lo script caricato al di fuori dell'ambito in cui viene chiamato request ()? Sembra che eval () sia l'unico modo per farlo nell'ambito. oppure c'è un'altro modo?
trusktr,

44

Ecco la versione generalizzata di come lo fa Facebook per il loro pulsante Mi piace onnipresente:

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

Se funziona per Facebook, funzionerà per te.

Il motivo per cui cerchiamo il primo scriptelemento anziché heado bodyè perché alcuni browser non ne creano uno se mancano, ma abbiamo la garanzia di avere un scriptelemento: questo. Maggiori informazioni su http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .


3
Accidenti a tutti! Alcuni dei metodi qui funzionano anche, ma con un'impostazione dinamica questo funziona meglio.
fino al

ho esteso la tua sceneggiatura per eliminare il pubblico
Kamil Dąbrowski il

39

Se vuoi in puro JavaScript, puoi usare document.write.

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

Se si utilizza la libreria jQuery, è possibile utilizzare il $.getScriptmetodo

$.getScript("another_script.js");

8
document.write non rimuoverebbe tutto il resto?
Eisa Adil,

30

Puoi anche assemblare i tuoi script usando PHP :

File 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

16
Sembra che il punto sia mantenere tutto questo in javascript nel front-end
Ariel,

1
Grazie per avermelo ricordato. Puoi anche avere PHP scrivere tag <script> nell'intestazione HTML, in modo che vengano caricati i file js necessari (e solo quelli).
Rolf,

29

La maggior parte delle soluzioni mostrate qui implica un caricamento dinamico. Stavo invece cercando un compilatore che assemblava tutti i file dipendenti in un unico file di output. Lo stesso dei preprocessori Less / Sass si occupano del CSS@import regola . Dal momento che non ho trovato nulla di decente di questo tipo, ho scritto un semplice strumento per risolvere il problema.

Quindi ecco il compilatore, https://github.com/dsheiko/jsic , che sostituisce in $import("file-path")modo sicuro il contenuto del file richiesto. Ecco il plugin Grunt corrispondente : https://github.com/dsheiko/grunt-jsic .

Sul ramo master jQuery, concatenano semplicemente i file di origine atomici in uno singolo iniziando con intro.jse finendo con outtro.js. Questo non mi va bene in quanto non offre flessibilità nella progettazione del codice sorgente. Scopri come funziona con jsic:

src / main.js

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

src / Form / Input / Tel.js

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

Ora possiamo eseguire il compilatore:

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

E ottieni il file combinato

build / main.js

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

2
Da questo post ho trovato una soluzione molto migliore - compilatore di moduli CommonJS - github.com/dsheiko/cjsc Quindi puoi semplicemente scrivere moduli CommonJs o NodeJs e accedervi reciprocamente mantenendoli in ambiti isolati. I vantaggi: Non sono necessarie più richieste HTTP che influiscono sulle prestazioni Non è necessario racchiudere manualmente il codice del modulo: è responsabilità del compilatore (quindi migliore leggibilità del codice sorgente) Non sono necessarie librerie esterne È compatibile con UMD- e moduli NodeJs (ad es. puoi indirizzare jQuery, Backbone come moduli senza toccare il loro codice)
Dmitry Sheiko

26

Se la tua intenzione di caricare il file JavaScript utilizza le funzioni del file importato / incluso , puoi anche definire un oggetto globale e impostare le funzioni come oggetti oggetto. Per esempio:

global.js

A = {};

file1.js

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

file2.js

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

main.js

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

Devi solo fare attenzione quando includi gli script in un file HTML. L'ordine dovrebbe essere come di seguito:

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

22

Questo dovrebbe fare:

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

5
l' evalè ciò che c'è di sbagliato con esso. Da Crockford , " evalè malvagio. La evalfunzione è la caratteristica più abusata di JavaScript. Evitatela. evalHa alias. Non usare il Functioncostruttore. Non passare stringhe a setTimeouto setInterval." Se non hai letto il suo "JavaScript: le parti buone", esci e fallo subito. Non te ne pentirai.
MattDMo

13
@MattDMo "Qualcuno ha detto che era male" non è proprio un argomento.
Casey,

4
@emodendroket Immagino che tu non sia a conoscenza di chi sia Douglas Crockford .
MattDMo,

13
@MattDMo Sono pienamente consapevole di chi è, ma è un essere umano, non un dio.
Casey,

2
@tggagne: cosa posso fare per farlo funzionare su più domini? (caricamento script da http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js)
user2284570

21

O piuttosto che includere in fase di esecuzione, utilizzare uno script per concatenare prima del caricamento.

Uso i pignoni (non so se ce ne sono altri). Costruisci il tuo codice JavaScript in file separati e includi i commenti che vengono elaborati dal motore Sprockets come include. Per lo sviluppo è possibile includere i file in sequenza, quindi per la produzione unirli ...

Guarda anche:


Browserify è molto più popolare di Sprockets.
Dan Dascalescu,

18

Ho avuto un semplice problema, ma sono rimasto sconcertato dalle risposte a questa domanda.

Ho dovuto usare una variabile (myVar1) definita in un file JavaScript (myvariables.js) in un altro file JavaScript (main.js).

Per questo ho fatto come di seguito:

Ho caricato il codice JavaScript nel file HTML, nell'ordine corretto, myvariables.js prima, quindi main.js:

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

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

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

File: myvariables.js

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

File: main.js

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

Come hai visto, avevo usato una variabile in un file JavaScript in un altro file JavaScript, ma non avevo bisogno di includerne uno in un altro. Avevo solo bisogno di assicurarmi che il primo file JavaScript caricato prima del secondo file JavaScript e, le variabili del primo file JavaScript siano accessibili automaticamente nel secondo file JavaScript.

Questo mi ha salvato la giornata. Spero che questo possa essere d'aiuto.


Il problema con questa risposta è che non è qualcosa del genere import. È necessario un file HTML per ottenere elementi da un file js a un altro.
Cannicidio del

Verissimo. Questo è ciò che alcune altre risposte hanno come soluzioni. Tuttavia avevo due file JS, uno dovrebbe usare le altre variabili JS. Nessun nodo.js, next.js, express.js, ecc., Quindi l'importazione o la richiesta non funzioneranno, con solo semplici file .js.
Manohar Reddy Poreddy,

Comprensibile, tuttavia, la domanda è in realtà chiedere di importare un file javascript all'interno di un altro file stesso, non solo accedere alle sue variabili utilizzando un file HTML. Ad esempio, supponiamo che tu stia creando funzionalità per un pulsante e usi tre diversi file js, uno per la gestione dei clic, uno per la gestione al passaggio del mouse, uno per i callback per ciascuno degli altri due. Sarebbe utile importare le altre due j nella terza j stessa e avere un solo <script>tag. Questo può aiutare con l'organizzazione. Questa risposta non è semplicemente la domanda posta e non è l'ideale in questo contesto.
Cannicidio,

Quando ho cercato la soluzione del mio problema, ho cercato nel modo giusto, tuttavia Google pensa che questa sia la pagina corretta, quindi sono arrivato qui. Ecco perché ho scritto la mia risposta qui. A quanto pare, ho fatto bene, a causa di 15 voti sopra. Per non sprecare il tempo di altre persone, ho dato un chiaro inizio a ciò che è il mio scenario - ho messo il codice HTML al primo posto - che sembra aiutato, dal momento che hai risposto e detto che HTML non è il tuo scenario. Spero che sia chiarito.
Manohar Reddy Poreddy,

Sì, in effetti sembra che alcune persone abbiano cercato un problema leggermente diverso, a cui questa è una soluzione, e hanno trovato questo. Sebbene questa non sia necessariamente la risposta a questa domanda, è sicuramente la risposta a un'altra domanda simile. Come tale, va bene avere questa risposta qui poiché aiuta coloro che cercavano quella risposta. Grazie per la risposta, questo l'ha chiarito.
Cannicida,

16

Nel caso in cui tu stia utilizzando Web Worker e desideri includere script aggiuntivi nell'ambito del lavoratore, le altre risposte fornite sull'aggiunta di script al headtag, ecc. Non funzioneranno per te.

Fortunatamente, i Web Worker hanno una propria importScriptsfunzione che è una funzione globale nell'ambito del Web Worker, nativa del browser stesso in quanto fa parte delle specifiche .

In alternativa, come evidenzia la seconda risposta più votata alla tua domanda , RequireJS può anche gestire gli script inclusi in un Web Worker (probabilmente chiamando importScriptsse stesso, ma con alcune altre utili funzionalità).


16

In linguaggio moderno con la spunta se lo script è già stato caricato sarebbe:

function loadJs(url){
  return new Promise( (resolve, reject) => {
    if (document.querySelector(`head > script[src="${src}"]`) !== null) return resolve()
    const script = document.createElement("script")
    script.src = url
    script.onload = resolve
    script.onerror = reject
    document.head.appendChild(script)
  });
}

Utilizzo (asincrono / attendi):

try { await loadJs("https://.../script.js") } 
catch(error) {console.log(error)}

o

await loadJs("https://.../script.js").catch(err => {})

Utilizzo (promessa):

loadJs("https://.../script.js").then(res => {}).catch(err => {})

Bello. Buona soluzione
Naftali aka Neal,

Conciso e necessita solo di ES5, ed evita elegantemente una richiamata formale. Grazie Dmitry!
Eureka,

Wow, funziona nel browser senza server. pi.js = semplicemente var pi = 3.14. chiama la funzione loadJS () tramiteloadJs("pi.js").then(function(){ console.log(pi); });
zipzit il

14

La @importsintassi per ottenere l'importazione JavaScript simile a CSS è possibile utilizzando uno strumento come Mixture tramite il loro .mixtipo di file speciale (vedi qui ). Immagino che l'applicazione usi semplicemente uno dei metodi sopra citati, anche se non lo so.

Dalla documentazione Mixture sui .mixfile:

I file mix sono semplicemente file .js o .css con .mix. nel nome del file. Un file mix semplicemente estende la funzionalità di un normale file di stile o di script e consente di importare e combinare.

Ecco un .mixfile di esempio che combina più .jsfile in uno:

// 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";

La miscela genera questo come scripts-global.jse anche come versione minimizzata ( scripts-global.min.js).

Nota: non sono in alcun modo affiliato con Mixture, a parte l'utilizzo come strumento di sviluppo front-end. Mi sono imbattuto in questa domanda quando ho visto un .mixfile JavaScript in azione (in una delle piastre della caldaia Mixture) e ne sono stato un po 'confuso ("puoi farlo?" Ho pensato tra me e me). Poi mi sono reso conto che si trattava di un tipo di file specifico dell'applicazione (un po 'deludente, d'accordo). Tuttavia, ho pensato che la conoscenza potesse essere utile per gli altri.

AGGIORNAMENTO : Mixture ora è gratuito (offline).

AGGIORNAMENTO : La miscela è ora interrotta. I vecchi rilasci di miscele sono ancora disponibili


Sarebbe fantastico se fosse un modulo nodo.
b01,

@ b01 Sembra una sfida;) Se solo avessi il tempo ... forse qualcun altro lo fa?
Isaac Gregson,


13

Il mio solito metodo è:

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

Funziona benissimo e non usa ricariche di pagine per me. Ho provato il metodo AJAX (una delle altre risposte) ma non sembra funzionare altrettanto bene per me.

Ecco una spiegazione di come funziona il codice per coloro che sono curiosi: essenzialmente, crea un nuovo tag di script (dopo il primo) dell'URL. Lo imposta in modalità asincrona in modo che non blocchi il resto del codice, ma chiama un callback quando readyState (lo stato del contenuto da caricare) cambia in "caricato".


13

Sebbene queste risposte siano ottime, esiste una semplice "soluzione" che esiste da quando esiste il caricamento degli script e coprirà il 99,999% dei casi d'uso della maggior parte delle persone. Includi solo lo script di cui hai bisogno prima dello script che lo richiede. Per la maggior parte dei progetti non ci vuole molto per determinare quali script sono necessari e in quale ordine.

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

Se script2 richiede script1, questo è davvero il modo più semplice per fare qualcosa del genere. Sono molto sorpreso che nessuno l'abbia sollevato, in quanto è la risposta più ovvia e più semplice che verrà applicata in quasi ogni singolo caso.


1
Immagino che per molte persone, incluso me stesso, abbiamo bisogno di un nome file dinamico.
Stuart McIntyre,

1
@StuartMcIntyre in quel caso, imposta l'attributo src del tag script in fase di runtime e attendi l'evento onload (ovviamente ci sono soluzioni migliori in quel caso nel 2019).
KthProg,

12

Ho scritto un modulo semplice che automatizza il lavoro di importazione / inclusione di script del modulo in JavaScript. Per una spiegazione dettagliata del codice, fare riferimento al post sul blog JavaScript richiede / importa / include moduli .

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

10

Questo script aggiungerà un file JavaScript all'inizio di qualsiasi altro <script>tag:

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

10

C'è anche Head.js . È molto facile gestire:

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

Come vedi, è più semplice di Require.js e conveniente come il $.getScriptmetodo jQuery . Ha anche alcune funzionalità avanzate, come il caricamento condizionale, il rilevamento delle funzionalità e molto altro .


10

Ci sono molte potenziali risposte a questa domanda. La mia risposta si basa ovviamente su alcuni di essi. Questo è quello che ho finito dopo aver letto tutte le risposte.

Il problema con $.getScripte in realtà qualsiasi altra soluzione che richiede un callback al termine del caricamento è che se si hanno più file che lo utilizzano e dipendono l'uno dall'altro non si ha più modo di sapere quando tutti gli script sono stati caricati (una volta nidificati in più file).

Esempio:

file3.js

var f3obj = "file3";

// Define other stuff

file2.js:

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

    alert(f3obj);

    // Use anything defined in file3.
});

file1.js:

$.getScript("file2.js", function(){
    alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
    alert(f2obj);

    // Use anything defined in the loaded script...
});

Hai ragione quando dici che potresti specificare Ajax da eseguire in modo sincrono o usare XMLHttpRequest , ma la tendenza attuale sembra essere quella di deprecare le richieste sincrone, quindi potresti non ottenere il supporto completo del browser ora o in futuro.

Potresti provare a usare $.whenper controllare una matrice di oggetti differiti, ma ora lo stai facendo in ogni file e file2 sarà considerato caricato non appena $.whenviene eseguito non quando viene eseguita la richiamata, quindi file1 continua ancora l'esecuzione prima che venga caricato file3 . Questo ha ancora lo stesso problema.

Ho deciso di andare indietro invece che in avanti. Grazie document.writeln. So che è un tabù, ma fintanto che viene usato correttamente funziona bene. Si finisce con il codice che può essere facilmente eseguito il debug, viene visualizzato correttamente nel DOM e può garantire l'ordine di caricamento corretto delle dipendenze.

Ovviamente puoi usare $ ("body"). Append (), ma non potrai più eseguire correttamente il debug.

NOTA: è necessario utilizzarlo solo durante il caricamento della pagina, altrimenti viene visualizzata una schermata vuota. In altre parole, posizionalo sempre prima / all'esterno di document.ready . Non ho provato a usarlo dopo che la pagina è stata caricata in un evento click o qualcosa del genere, ma sono abbastanza sicuro che fallirà.

Mi è piaciuta l'idea di estendere jQuery, ma ovviamente non è necessario.

Prima di chiamare document.writeln, verifica che lo script non sia già stato caricato valutando tutti gli elementi dello script.

Presumo che uno script non sia completamente eseguito fino a quando il suo document.readyevento non è stato eseguito. (So ​​che document.readynon è richiesto l'uso, ma molte persone lo usano e gestirlo è una salvaguardia.)

Quando vengono caricati i file aggiuntivi, i document.readycallback verranno eseguiti nell'ordine sbagliato. Per risolvere questo problema quando uno script viene effettivamente caricato, lo script che lo ha importato viene reimportato e l'esecuzione viene interrotta. Ciò fa ora document.readyeseguire il callback del file di origine dopo uno qualsiasi degli script che importa.

Invece di questo approccio potresti provare a modificare jQuery readyList, ma questa sembra una soluzione peggiore.

Soluzione:

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

Uso:

file3:

var f3obj = "file3";

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

file2:

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

file1:

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

Questo è esattamente ciò che afferma la risposta attualmente accettata: non abbastanza.
Cannicidio del

La differenza principale è che se manca una dipendenza, aggiungerà il tag di script per la dipendenza, quindi aggiungerà anche il tag di script per il file chiamante e genererà un errore che interrompe l'esecuzione. Ciò provoca l'elaborazione e l'esecuzione degli script nell'ordine corretto e la necessità di richiamate. Quindi lo script dipendente verrà caricato ed eseguito prima dello script chiamante mentre supporta l'annidamento.
curlyhairedgenius,

Quanto a "la tendenza attuale sembra essere quella di deprecare le richieste sincrone", ciò è vero solo perché molti sviluppatori le hanno abusate e hanno fatto attendere inutilmente gli utenti. Tuttavia, se la richiesta è naturalmente sincrona, come un'istruzione Include, allora il semplice Ajax sincrono va bene. Ho creato una funzione di estensione JavaScript generale che esegue in modo sincrono funzioni come la lettura di un file che non fa parte di JavaScript eseguendo un file "server" PHP e lo trovo molto utile quando si scrivono app utilizzando JavaScript. Nessun server web locale è necessario per tale Ajax.
David Spector,

10

Esistono diversi modi per implementare i moduli in Javascript, ecco i 2 più popolari:

Moduli ES6

I browser non supportano ancora questo sistema di modulazione, quindi per poter utilizzare questa sintassi è necessario utilizzare un bundler come il webpack. L'uso di un bundler è comunque meglio perché può combinare tutti i tuoi diversi file in un singolo file (o associato a coppie). Questo servirà i file dal server al client più velocemente perché ogni richiesta HTTP ha un sovraccarico associato con esso. Pertanto, riducendo la richiesta HTTP globale, miglioriamo le prestazioni. Ecco un esempio di moduli 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 (utilizzato in NodeJS)

Questo sistema di modulazione viene utilizzato in NodeJS. Fondamentalmente aggiungi le tue esportazioni a un oggetto che viene chiamato module.exports. È quindi possibile accedere a questo oggetto tramite a require('modulePath'). Importante qui è rendersi conto che questi moduli vengono memorizzati nella cache, quindi se require()un determinato modulo due volte restituirà il modulo già creato.

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

9

Sono arrivato a questa domanda perché stavo cercando un modo semplice per mantenere una raccolta di plugin JavaScript utili. Dopo aver visto alcune delle soluzioni qui, ho pensato a questo:

  1. Imposta un file chiamato "plugins.js" (o extensions.js o come vuoi). Mantieni i tuoi file plugin insieme a quel file principale.

  2. plugins.js avrà un array chiamato pluginNames[]che ripeteremo each(), quindi aggiungere un <script>tag in testa per ogni plugin

//set array to be updated when we add or remove plugin files
var pluginNames = ["lettering", "fittext", "butterjam", etc.];

//one script tag for each plugin
$.each(pluginNames, function(){
    $('head').append('<script src="js/plugins/' + this + '.js"></script>');
});
  1. Chiama manualmente solo un file nella tua testa:
    <script src="js/plugins/plugins.js"></script>

MA:

Anche se tutti i plugin vengono inseriti nel tag head come dovrebbero, non sempre vengono eseguiti dal browser quando si fa clic sulla pagina o si aggiorna.

Ho trovato più affidabile scrivere semplicemente i tag di script in un include PHP. Devi solo scriverlo una volta e questo è tanto lavoro quanto chiamare il plugin usando JavaScript.


@will, la tua soluzione sembra molto più pulita della mia e sono preoccupato che potrei avere degli errori se uso la mia, in quanto utilizza .append (). Quindi, per usare questo, puoi semplicemente chiamare quella funzione una volta per ogni file plugin che desideri includere?
rgb_life
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.