¿Cómo puedo incluir un archivo JavaScript en otro archivo JavaScript?


¿Hay algo en JavaScript similar a @import en CSS que le permita incluir un archivo JavaScript dentro de otro archivo JavaScript?

Author: Steven Vascellaro, 2009-06-04

30 answers

Las versiones antiguas de JavaScript no tenían importación, incluyen o requieren, por lo que se han desarrollado muchos enfoques diferentes para este problema.

Pero desde 2015 (ES6), JavaScript ha tenido el estándar ES6 modules para importar módulos en Node.js, que también es compatible con la mayoría de los navegadores modernos.

Para la compatibilidad con navegadores más antiguos, se pueden usar las herramientas build y/o transpilation.

Módulos ES6

ECMAScript (ES6) los módulos han sido soportados en Node.js desde v8.5, con la bandera --experimental-modules. Todos los archivos involucrados deben tener la extensión .mjs.

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

Módulos ECMAScript en navegadores

Los navegadores han tenido soporte para cargar módulos ECMAScript directamente (no se requieren herramientas como Webpack) desde Safari 10.1, Chrome 61, Firefox 60 y Edge 16. Compruebe el soporte actual en 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);
}

Leer más en: https://jakearchibald.com/2017/es-modules-in-browsers /

Importaciones dinámicas en navegadores

Las importaciones dinámicas permiten que el script cargue otros scripts según sea necesario:

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

Lea más en: https://developers.google.com/web/updates/2017/11/dynamic-import

Nodo.js require

El antiguo estilo de importación de módulos, todavía ampliamente utilizado en Node.js, es el módulo .exports / require system.

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

Hay otras maneras para que JavaScript incluya contenido JavaScript externo en navegadores que no requieren preprocesamiento.

AJAX Cargando

Puede cargar un script adicional con una llamada AJAX y luego usar eval para ejecutarlo. Esta es la forma más sencilla, pero se limita a su dominio debido al modelo de seguridad de JavaScript sandbox. El uso de eval también abre la puerta a errores, hacks y problemas de seguridad.

Cargando jQuery

La biblioteca jQuery proporciona cargando funcionalidad en una línea :

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

Carga dinámica de Script

Puede agregar una etiqueta de script con la URL del script en el HTML. Para evitar la sobrecarga de jQuery, esta es una solución ideal.

El script puede incluso residir en un servidor diferente. Además, el navegador evalúa el código. La etiqueta <script> puede inyectarse en la página web <head>, o insertarse justo antes de la etiqueta </body> de cierre.

Aquí hay un ejemplo de cómo esto podría trabajo:

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

Esta función agregará una nueva etiqueta <script> al final de la sección head de la página, donde el atributo src se establece en la URL que se le da a la función como primer parámetro.

Ambas soluciones se discuten e ilustran en JavaScript Madness: Dynamic Script Loading.

Detectar cuando se ha ejecutado el script

Ahora, hay un gran problema que debes conocer. Hacer eso implica que carga remotamente el código. Los navegadores web modernos cargarán el archivo y seguirán ejecutando su script actual porque lo cargan todo de forma asíncrona para mejorar el rendimiento. (Esto se aplica tanto al método jQuery como al método manual dynamic script loading.)

Significa que si usas estos trucos directamente, no podrás usar tu código recién cargado la siguiente línea después de que lo hayas pedido que se cargue, porque seguirá cargando.

Por ejemplo: my_lovely_script.js contiene 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

Luego recargas la página pulsando F5. Y funciona! Confuso...

Entonces, ¿qué hacer al respecto ?

Bueno, puedes usar el hack que el autor sugiere en el enlace que te di. En resumen, para las personas con prisa, utiliza un evento para ejecutar una función de devolución de llamada cuando se carga el script. Así que puede poner todo el código usando la biblioteca remota en la función de devolución de llamada. Por ejemplo:

function loadScript(url, callback)
{
    // Adding the script tag to the head as suggested before
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;

    // Then bind the event to the callback function.
    // There are several events for cross browser compatibility.
    script.onreadystatechange = callback;
    script.onload = callback;

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

Luego escribes el código que quieres usar DESPUÉS de cargar el script en una función lambda :

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

Entonces ejecuta todo eso: {[26]]}

loadScript("my_lovely_script.js", myPrettyCode);

Tenga en cuenta que el script puede ejecutarse después de que el DOM se haya cargado, o antes, dependiendo del navegador y si incluyó la línea script.async = false;. Hay un gran artículo sobre la carga de Javascript en general que discute esto.

Fusión/Preprocesamiento de Código fuente

Como se mencionó en la parte superior de esta respuesta, muchos desarrolladores usan build / transpilation herramientas como Parcel, Webpack o Babel en sus proyectos, lo que les permite usar la próxima sintaxis de JavaScript, proporcionar compatibilidad con versiones anteriores para navegadores más antiguos, combinar archivos, minificar, realizar división de código, etc.

 3679
Author: e-satis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-08 16:11:26

Si alguien está buscando algo más avanzado, pruebe RequireJS. Obtendrá beneficios adicionales, como la administración de dependencias, una mejor concurrencia y evitar la duplicación (es decir, recuperar un script más de una vez).

Puede escribir sus archivos JavaScript en "modules" y luego referenciarlos como dependencias en otros scripts. O puede usar RequireJS como una solución simple de "obtener este script".

Ejemplo:

Definir dependencias como módulos:

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

Ejecución.js es su archivo JavaScript "principal" que depende de some-dependency.js

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

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

Extracto del [23]} GitHub README:

RequireJS carga archivos JavaScript simples, así como más definidos módulos. Está optimizado para el uso en el navegador, incluso en una Web Worker, pero se puede utilizar en otros entornos JavaScript, como Rhino y Node. Implementa el API de Módulo Asíncrono.

RequireJS usa etiquetas de script simples para cargar módulos / archivos, por lo que debería permitir la depuración fácil. Se puede utilizar simplemente para cargar existente Archivos JavaScript, por lo que puede agregarlo a su proyecto existente sin tener que reescribir sus archivos JavaScript.

...

 517
Author: John Strickler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-28 13:11:26

En realidad es una forma de cargar un archivo JavaScript no asincrónicamente, por lo que podría utilizar las funciones incluidas en el archivo recién cargado justo después de cargarlo, y creo que funciona en todos los navegadores.

Necesitas usar jQuery.append() en el elemento <head> de tu página, es decir:

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

Sin embargo, este método también tiene un problema: si ocurre un error en el archivo JavaScript importado, Firebug (y también Firefox Error Console y Chrome Developer Tools as well) reportará su lugar incorrectamente, lo cual es un gran problema si usa Firebug para rastrear errores de JavaScript mucho (yo sí). Firebug simplemente no sabe sobre el archivo recién cargado por alguna razón, por lo que si se produce un error en ese archivo, informa que ocurrió en su archivo principal HTML, y tendrá problemas para encontrar la verdadera razón del error.

Pero si eso no es un problema para usted, entonces este método debería funcionar.

Tengo en realidad escribió un plugin de jQuery llamado }.import_js() que utiliza este método:

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

Así que todo lo que necesitas hacer para importar JavaScript es:

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

También hice una prueba simple para esto en Ejemplo.

Incluye un archivo main.js en el HTML principal y luego el script en main.js usa $.import_js() para importar un archivo adicional llamado included.js, que define esta función:

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

Y justo después de incluir included.js, se llama a la función hello(), y recibes la alerta.

(Esta respuesta es en respuesta al comentario de e-satis).

 167
Author: Kipras,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-21 04:29:29

Otra forma, que en mi opinión es mucho más limpia, es hacer una solicitud Ajax síncrona en lugar de usar una etiqueta <script>. Que es también cómo Nodo .js maneja incluye.

Aquí hay un ejemplo 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);
        }
    });
}

Luego puedes usarlo en tu código como usualmente usarías un include:

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

Y poder llamar a una función desde el script requerido en la siguiente línea:

subscript.doSomethingCool(); 
 134
Author: Ariel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-28 12:55:50

Hay una buena noticia para ti. Muy pronto podrás cargar código JavaScript fácilmente. Se convertirá en una forma estándar de importar módulos de código JavaScript y será parte del propio core JavaScript.

Simplemente tienes que escribir import cond from 'cond.js'; para cargar una macro llamada cond desde un archivo cond.js.

Así que no tienes que confiar en ningún framework JavaScript ni tienes que hacer llamadas explícitamente Ajax.

Refiérase a:

 87
Author: Imdad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-19 18:05:37

Es posible generar dinámicamente una etiqueta JavaScript y anexarla al documento HTML desde dentro de otro código JavaScript. Esto cargará el archivo JavaScript dirigido.

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");
 73
Author: Svitlana Maksymchuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-28 12:44:30

Declaración import está en ECMAScript 6.

Sintaxis

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;
 59
Author: draupnie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-11 09:47:07

Tal vez pueda usar esta función que encontré en esta página ¿Cómo puedo incluir un archivo JavaScript en un archivo 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)
}
 48
Author: Arnaud Gouder de Beauregard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-15 17:01:22

Aquí hay una versión síncrona sin 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);
}

Tenga en cuenta que para que este cross-domain funcione, el servidor necesitará establecer allow-origin header en su respuesta.

 46
Author: heinob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-18 14:44:10

Acabo de escribir este código JavaScript (usando Prototype para DOM manipulación):

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>

Síntesis: http://gist.github.com/284442 .

 41
Author: nornagon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-25 21:04:40

Aquí está la versión generalizada de cómo Facebook lo hace por su ubicuo botón Me gusta:

<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 funciona para Facebook, funcionará para ti.

La razón por la que buscamos el primer elemento script en lugar de head o body es porque algunos navegadores no crean uno si falta, pero estamos garantizados para tener un elemento script - este. Lea más en http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/.

 34
Author: Dan Dascalescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-08 02:48:05

Si lo desea en JavaScript puro, puede usar document.write.

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

Si usa la biblioteca jQuery, puede usar el método $.getScript.

$.getScript("another_script.js");
 29
Author: Venu immadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 21:20:07

La mayoría de las soluciones mostradas aquí implican carga dinámica. En su lugar, estaba buscando un compilador que reuniera todos los archivos dependientes en un solo archivo de salida. Igual que Menos/Los preprocesadores Sass se ocupan de la regla at de CSS @import. Como no encontré nada decente de este tipo, escribí una herramienta simple para resolver el problema.

Así que aquí está el compilador, https://github.com/dsheiko/jsic , que reemplaza $import("file-path") con el contenido del archivo solicitado de forma segura. Aqui es el correspondiente Grunt plugin: https://github.com/dsheiko/grunt-jsic .

En la rama master de jQuery, simplemente concatenan archivos fuente atómicos en uno solo que comienza con intro.js y termina con outtro.js. Eso no me conviene, ya que no proporciona flexibilidad en el diseño del código fuente. Echa un vistazo a cómo funciona con jsic:

src / main.js

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

src / Form/Input / Tel.js

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

Ahora podemos ejecutar el compilador:

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

Y obtener el archivo combinado

build / main.js

var foo = function() {
    return {
          prop: "",
          method: function(){}
    }
};
 23
Author: Dmitry Sheiko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-19 18:13:46

También puede ensamblar sus scripts usando PHP :

Archivo 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
 22
Author: Calmarius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-28 12:50:11

Si su intención de cargar el archivo JavaScript es utilizando las funciones del archivo importado/incluido, también puede definir un objeto global y establecer las funciones como elementos de objeto. Por ejemplo:

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

Solo tiene que tener cuidado al incluir scripts en un archivo HTML. El orden debe ser el siguiente:

<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>
 19
Author: Adem İlhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-11 09:42:00

Esto debería hacer:

xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);
 17
Author: tggagne,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-02 13:50:20

O en lugar de incluir en tiempo de ejecución, use un script para concatenar antes de cargar.

Uso Piñones (no se si hay otros). Usted construye su código JavaScript en archivos separados e incluye comentarios que son procesados por el motor Sprockets como includes. Para el desarrollo puede incluir archivos de forma secuencial, luego para la producción para fusionarlos...

Véase también:

 16
Author: JMawer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-19 18:02:51

En caso de que esté utilizando Web Workers y desee incluir scripts adicionales en el ámbito del worker, las otras respuestas proporcionadas sobre la adición de scripts a la etiqueta head, etc. no funcionará para ti.

Afortunadamente, Los Trabajadores Web tienen su propia función importScripts que es una función global en el ámbito del Trabajador Web, nativa del propio navegador, ya que es parte de la especificación .

Alternativamente, como la segunda respuesta más votada a su aspectos destacados de la pregunta, RequireJS también puede manejar la inclusión de scripts dentro de un Trabajador Web (probablemente llamando a importScripts a sí mismo, pero con algunas otras características útiles).

 13
Author: Turnerj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:59

Tuve un problema simple, pero estaba desconcertado por las respuestas a esta pregunta.

Tuve que usar una variable (myVar1) definida en un archivo JavaScript (myvariables.js) en otro archivo JavaScript (main.js).

Para esto hice lo siguiente:

Cargado el código JavaScript en el archivo HTML, en el orden correcto, myvariables.primero js, luego main.js:

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

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

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

Archivo: myvariables.js

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

Archivo: main.js

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

Como has visto, he usado una variable en un JavaScript archivo en otro archivo JavaScript, pero no necesitaba incluir uno en otro. Solo necesitaba asegurarme de que el primer archivo JavaScript cargado antes del segundo archivo JavaScript, y, las variables del primer archivo JavaScript son accesibles en el segundo archivo JavaScript, automáticamente.

Esto me salvó el día. Espero que esto ayude.

 12
Author: Manohar Reddy Poreddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-11 09:45:11

La sintaxis @import para lograr la importación de JavaScript similar a CSS es posible utilizando una herramienta como Mixture a través de su tipo de archivo especial .mix (ver aquí). Imagino que la aplicación simplemente utiliza uno de los métodos antes mencionados interalmente, aunque no lo sé.

De la documentación de la mezcla en los archivos .mix:

Los archivos de mezcla son simples .js or .archivos css con .mezcla. en el nombre del archivo. Un mix file simplemente extiende la funcionalidad de un estilo normal o archivo de script y le permite importar y combinar.

Aquí hay un ejemplo de archivo .mix que combina múltiples archivos .js en 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 mezcla produce esto como scripts-global.js y también como una versión minificada (scripts-global.min.js).

Nota: No estoy afiliado de ninguna manera con Mixture, aparte de usarlo como una herramienta de desarrollo front-end. Me encontré con esta pregunta al ver un archivo JavaScript .mix en acción (en una de las placas de cocción de mezcla) y estar un poco confundido por ella ("puede hacer esto?"Pensé para mí mismo). Entonces me di cuenta de que era un tipo de archivo específico de la aplicación (algo decepcionante, de acuerdo). Sin embargo, pensé que el conocimiento podría ser útil para otros.

ACTUALIZACIÓN : La mezcla es ahora libre (sin conexión).

ACTUALIZACIÓN : La mezcla se ha descontinuado. Las emisiones de mezclas antiguas todavía están disponibles

 11
Author: Isaac Gregson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-17 11:53:48

Escribí un módulo simple que automatiza el trabajo de importar/incluir scripts de módulos en JavaScript. Para una explicación detallada del código, consulte la publicación del blogJavaScript requerir / importar / incluir módulos.

// ----- 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
Author: stamat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-19 18:26:26

Mi método habitual es:

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

Funciona muy bien y no usa recargas de página para mí. He probado el método AJAX (una de las otras respuestas), pero no parece funcionar tan bien para mí.

Aquí hay una explicación de cómo funciona el código para aquellos que son curiosos: esencialmente, crea una nueva etiqueta de script (después de la primera) de la URL. Lo establece en modo asíncrono para que no bloquee el resto del código, pero llama a una devolución de llamada cuando el readyState (el estado del contenido a ser loaded) cambia a 'loaded'.

 10
Author: Christopher Dumas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-26 17:02:15
var js = document.createElement("script");

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

document.body.appendChild(js);
 9
Author: Sam4Code,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-22 06:44:32

En el lenguaje moderno sería

function loadJs( url ){
  return new Promise( resolve => {
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    document.head.appendChild( script );
  });
}
 9
Author: Dmitry Sheiko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-20 15:15:02

Este script agregará un archivo JavaScript a la parte superior de cualquier otra etiqueta <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);
})();
 8
Author: Vicky Gonsalves,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-19 18:14:07

También Hay Cabeza.js . Es muy fácil de tratar:

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

Como ves, es más fácil que Requerir.js y tan conveniente como el método $.getScript de jQuery. También tiene algunas características avanzadas, como carga condicional, detección de características y mucho más.

 8
Author: Ale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-19 18:18:01

Llegué a esta pregunta porque estaba buscando una manera simple de mantener una colección de complementos de JavaScript útiles. Después de ver algunas de las soluciones aquí, se me ocurrió esto:

  1. Configure un archivo llamado " plugins.js" (o extensiones.js o lo que sea). Mantenga sus archivos de plugin junto con ese archivo maestro.

  2. Plugins.js tendrá una matriz llamada "pluginNames []" que iteraremos sobre cada(), a continuación, añadir una etiqueta a la cabeza para cada plugin

    / / establecer una matriz que se actualizará cuando agreguemos o eliminemos archivos de complementos var pluginNames = ["lettering", "fittext", "butterjam", etc.]; // una etiqueta de script para cada plugin $.cada (pluginNames, función(){ head ('cabeza').anexar(''); });

  3. Llame manualmente solo el archivo en su cabeza:
    <script src="js/plugins/plugins.js"></script>

Encontré que a pesar de que todos los complementos se estaban cayendo en la etiqueta principal de la manera que deberían, no siempre estaban siendo ejecutados por el navegador cuando haga clic en la página o actualice.

Encontré que es más confiable simplemente escribir las etiquetas de script en un PHP include. Solo tienes que escribirlo una vez y eso es tanto trabajo como llamar al plugin usando JavaScript.

 8
Author: rgb_life,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 21:21:29

Hay muchas respuestas potenciales para esta pregunta. Mi respuesta se basa obviamente en varias de ellas. Esto es lo que terminé con después de leer a través de todas las respuestas.

El problema con $.getScript y realmente cualquier otra solución que requiera una devolución de llamada cuando se complete la carga es que si tiene varios archivos que lo usan y dependen entre sí, ya no tiene una forma de saber cuándo se han cargado todos los scripts (una vez que están anidados en múltiples archivos file).

Ejemplo:

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

Tiene razón cuando dice que podría especificar Ajax para que se ejecute de forma sincrónica o usar XMLHttpRequest, pero la tendencia actual parece ser dejar en desuso las solicitudes síncronas, por lo que es posible que no obtenga soporte completo del navegador ahora o en el futuro.

Podría intentar usar $.when para verificar una matriz de objetos diferidos, pero ahora está haciendo esto en cada archivo y file2 se considerará cargado tan pronto como se ejecute el $.when no cuando se ejecute la devolución de llamada, por lo que file1 aún continúa la ejecución antes de que file3 se cargue. Esto realmente todavía tiene el mismo problema.

Decidí ir hacia atrás en lugar de hacia adelante. Gracias document.writeln. Sé que es tabú, pero mientras se use correctamente esto funciona bien. Terminas con código que se puede depurar fácilmente, se muestra en el DOM correctamente y puede asegurar el orden en que se cargan las dependencias correctamente.

Por supuesto, puedes usar body ("cuerpo").append (), pero entonces ya no puedes depurar correctamente.

NOTA: Debe usar esto solo mientras se está cargando la página, de lo contrario obtendrá una pantalla en blanco. En otras palabras, siempre coloque esto antes / fuera del documento.listo. No he probado usando esto después de que la página se cargue en un evento de clic o algo así, pero estoy bastante seguro de que fallará.

Me gustó la idea de extender jQuery, pero obviamente no necesitas hacerlo.

Antes de llamar a document.writeln, comprueba que el script no se haya estado cargando evaluando todos los elementos del script.

Asumo que un script no se ejecuta completamente hasta que su evento document.ready se ha ejecutado. (Sé que usar document.ready no es necesario, pero mucha gente lo usa, y manejar esto es una salvaguardia.)

Cuando se cargan los archivos adicionales, las devoluciones de llamada document.ready se ejecutarán en el orden incorrecto. Para abordar esto cuando un script es realmente cargado, el script que lo importó es reimportado y la ejecución se detuvo. Esto hace que el archivo de origen ahora tenga su devolución de llamada document.ready ejecutada después de cualquiera de los scripts que importa.

En lugar de este enfoque, podría intentar modificar jQuery readyList, pero esto parecía una solución peor.

Solución:

$.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"
});
 8
Author: curlyhairedgenius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 21:22:17

He creado una función que le permitirá usar verborrea similar a C#/Java para incluir un archivo JavaScript. Lo he probado un poco incluso desde dentro de otro archivo JavaScript y parece funcionar. Requiere jQuery aunque para un poco de "magia" al final.

Puse este código en un archivo en la raíz de mi directorio de script (lo nombré global.js, pero puedes usar lo que quieras. A menos que me equivoque y jQuery debería ser los únicos scripts necesarios en un determinado pagina. Tenga en cuenta que esto no está probado más allá de un uso básico, por lo que puede o no haber ningún problema con la forma en que lo he hecho; use bajo su propio riesgo yadda yadda No soy responsable si arruina algo yadda yadda:

/**
* @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
Author: Wayne Molina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-18 21:45:38

Usa mejor la forma de jQuery. Para retrasar el evento ready, primero llame $.holdReady(true). Ejemplo ( fuente):

$.holdReady(true);
$.getScript("myplugin.js", function() {
    $.holdReady(false);
});
 6
Author: weageoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-19 18:06:16