¿Cómo incluyo un archivo JavaScript en otro archivo JavaScript?

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

preguntado el 04 de junio de 09 a las 11:06

30 Respuestas

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

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

Para compatibilidad con navegadores más antiguos, cree herramientas como Webpack y Enrollar y / o herramientas de transpilación como Babel puede ser usado.

Módulos ES6

Los módulos ECMAScript (ES6) se han compatible con Node.js desde v8.5, con el --experimental-modules flag, y desde al menos Node.js v13.8.0 sin el flag. Para habilitar "ESM" (en comparación con el sistema de módulos de estilo CommonJS anterior de Node.js ["CJS"]), utilice "type": "module" in package.json o dale a los archivos la extensión .mjs. (De manera similar, los módulos escritos con el módulo CJS anterior de Node.js se pueden nombrar .cjs si su valor predeterminado es ESM).

Usar package.json:

{
    "type": "module"
}

Entonces module.js:

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

Entonces main.js:

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

Usar .mjs, tendrías module.mjs:

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

Entonces main.mjs:

import { hello } from './module.mjs';
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 Puedo usar. No es necesario utilizar Node.js ' .mjs extensión; los navegadores ignoran por completo las extensiones de archivo en módulos / scripts.

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

Más información 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>

Más información en https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js requiere

El estilo de módulo CJS más antiguo, todavía ampliamente utilizado en Node.js, es el module.exports/require sistema.

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

Hay otras formas de que JavaScript incluya contenido JavaScript externo en los navegadores que no requieren procesamiento previo.

Carga AJAX

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

Obtener carga

Al igual que las importaciones dinámicas, puede cargar uno o varios scripts con un fetch llamar usando promesas para controlar el orden de ejecución de las dependencias del script usando el Buscar inyectar biblioteca:

fetchInject([
  'https://cdn.jsdelivr.net/momentjs/2.17.1/moment.min.js'
]).then(() => {
  console.log(`Finish in less than ${moment().endOf('year').fromNow(true)}`)
})

Carga de jQuery

La jQuery la biblioteca proporciona funcionalidad de carga en una línea:

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

Carga dinámica de secuencias de comandos

Puede agregar una etiqueta de secuencia de comandos con la URL de la secuencia de comandos 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 <script> la etiqueta se puede inyectar en la página web <head>, o insertado justo antes del cierre </body> etiqueta.

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

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á un nuevo <script> etiqueta al final de la sección del encabezado de la página, donde el src El atributo se establece en la URL que se asigna a la función como primer parámetro.

Ambas soluciones se discuten e ilustran en Locura de JavaScript: carga dinámica de scripts.

Detectando cuando se ha ejecutado el script

Ahora, hay un gran problema que debes conocer. Hacer eso implica que cargas el código de forma remota. Los navegadores web modernos cargarán el archivo y seguirán ejecutando su secuencia de comandos actual porque cargan todo de forma asincrónica para mejorar el rendimiento. (Esto se aplica tanto al método jQuery como al método de carga de script dinámico manual).

Significa que si usa estos trucos directamente, no podrá usar su código recién cargado en la siguiente línea después de que solicitó que se cargue, porque todavía se estará 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 truco que sugiere el autor en el enlace que te di. En resumen, para las personas que tienen prisa, usa un evento para ejecutar una función de devolución de llamada cuando se carga el script. Entonces 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.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);
}

Luego, escribe el código que desea usar DESPUÉS de que el script se cargue en un función lambda:

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

Luego ejecuta todo eso:

loadScript("my_lovely_script.js", myPrettyCode);

Tenga en cuenta que la secuencia de comandos puede ejecutarse después de que se haya cargado el DOM, o antes, según el navegador y si incluyó la línea script.async = false;. Hay una 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 herramientas de compilación / transpilación 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 la división de código, etc.

respondido 21 mar '20, 12:03

He cargado div dinámicamente haciendo clic en el menú sin cargar la página mediante el uso de hash de URL. Mi problema es cuando hago clic en la misma página 2/3 veces js cargando 2/3 veces. es por eso que cada evento ocurre varias veces. Quiero verificar el archivo js ya cargado en el pie de página / encabezado antes de agregar ese código: var js = document.createElement ("script"); js.type = "texto / javascript"; js.src = jsFilePath; document.body.appendChild (js); - Extraterrestre

¡Dios mío, acabas de escribir un artículo completo! ¡Muchas gracias! Eres una leyenda. :) - Lathryx

Gracias por su aporte. ¿Hay alguna forma de insertar el guión al principio del encabezado? - Glund

Esa debe ser la respuesta más larga que tengo vez visto. - theknightD2

También puedes usar algo como Gulp (gulpjs.com) para preprocesarlos con la salida como un solo archivo que se llama. Por ejemplo: a) concatenar varios archivos JavaScript juntos en uno, b) usar Babel para hacerlo compatible con versiones anteriores, c) minificar / uglify para eliminar comentarios, espacios en blanco, etc. Luego, no solo ha organizado esos archivos sino que también los ha optimizado también al iniciar una canalización con el potencial de hacer lo mismo con otros formatos de archivo (como css e imágenes). Steven Ventimiglia

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

Puede escribir sus archivos JavaScript en "módulos" y luego hacer referencia a ellos como dependencias en otros scripts. O puede usar RequireJS como una simple solución de "busque este script".

Ejemplo:

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

deployment.js es su archivo JavaScript "principal" que depende de alguna-dependencia.js

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

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

Extracto de la GitHub LÉAME:

RequireJS carga archivos JavaScript sin formato, así como módulos más definidos. Está optimizado para su uso en el navegador, incluso en un Web Worker, pero se puede utilizar en otros entornos de JavaScript, como Rhino y Node. Implementa la API del módulo asincrónico.

RequireJS usa etiquetas de script sin formato para cargar módulos / archivos, por lo que debería permitir una depuración fácil. Se puede usar simplemente para cargar archivos JavaScript existentes, por lo que puede agregarlo a su proyecto existente sin tener que volver a escribir sus archivos JavaScript.

...

Respondido el 28 de Septiembre de 13 a las 17:09

Realmente hay is una forma de cargar un archivo JavaScript no de forma asincrónica, por lo que podría usar las funciones incluidas en su archivo recién cargado justo después de cargarlo, y creo que funciona en todos los navegadores.

Tienes que usar jQuery.append() al <head> elemento de su 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 Herramientas de desarrollo de Chrome también) informará su lugar incorrectamente, lo cual es un gran problema si usa Firebug para rastrear mucho los errores de JavaScript (yo lo hago). Firebug simplemente no conoce el archivo recién cargado por alguna razón, por lo que si ocurre un error en ese archivo, informa que ocurrió en su archivo principal. HTML archivo, 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.

De hecho, he escrito un complemento 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);

Entonces, todo lo que necesita 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 main.js archivo en el HTML principal y luego el script en main.js usos $.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,la hello() se llama a la función y recibe la alerta.

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

respondido 21 mar '18, 07:03

Otra forma, que en mi opinión es mucho más limpia, es hacer una solicitud Ajax sincrónica en lugar de usar un <script> etiqueta. Que es también como Node.js manijas 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 puede usarlo en su código como normalmente usaría un include:

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

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

subscript.doSomethingCool(); 

Respondido el 28 de Septiembre de 13 a las 16:09

Hay buenas noticias para ti. Muy pronto podrá 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 núcleo de JavaScript.

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

Por lo tanto, no tiene que depender de ningún marco de JavaScript ni tiene que hacer explícitamente Ajax llamadas.

Referirse a:

Respondido 19 Oct 14, 22:10

Es posible generar dinámicamente una etiqueta JavaScript y agregarla a un documento HTML desde dentro de otro código JavaScript. Esto cargará el archivo JavaScript de destino.

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

Respondido el 28 de Septiembre de 13 a las 16:09

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

Respondido el 11 de diciembre de 16 a las 12:12

Tal vez puedas usar esta función que encontré en esta página ¿Cómo incluyo 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)
}

respondido 15 nov., 14:20

Aquí hay una sincrónico versión 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 dominio cruzado funcione, el servidor deberá configurar allow-origin encabezado en su respuesta.

Respondido el 18 de junio de 15 a las 17:06

Acabo de escribir este código JavaScript (usando Prototipo 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>

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

Respondido el 26 de junio de 17 a las 00:06

Aquí está la versión generalizada de cómo lo hace Facebook para su omnipresente 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 primero script elemento en lugar de head or body se debe a que algunos navegadores no crean uno si falta, pero tenemos la garantía de tener un script elemento - este. Lea mas en http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/.

Respondido 08 Jul 15, 05:07

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 la $.getScript método.

$.getScript("another_script.js");

Respondido 03 Oct 20, 23:10

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

Respondido el 28 de Septiembre de 13 a las 16:09

La mayoría de las soluciones que se muestran aquí implican una carga dinámica. En cambio, estaba buscando un compilador que reuniera todos los archivos dependientes en un solo archivo de salida. Lo mismo que Menos/Hablar con descaro a los preprocesadores se ocupan del CSS @import en regla. 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. Aquí está el correspondiente Gruñido enchufar: https://github.com/dsheiko/grunt-jsic.

En la rama maestra de jQuery, simplemente concatenan archivos de origen atómico en uno solo que comienza con intro.js y terminando con outtro.js. Eso no me conviene, ya que no proporciona flexibilidad en el diseño del código fuente. Vea 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 obtén el archivo combinado

build / main.js

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

Respondido 19 Oct 14, 22:10

Si su intención de cargar el archivo JavaScript es usando 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 debe tener cuidado al incluir secuencias de comandos 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>

Respondido el 11 de diciembre de 16 a las 12:12

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

yo suelo Piñones (No sé si hay otros). Usted crea su código JavaScript en archivos separados e incluye comentarios que son procesados ​​por el motor Sprockets como se incluye. Para el desarrollo, puede incluir archivos secuencialmente, luego para que la producción los combine ...

Ver también:

Respondido 19 Oct 14, 22:10

Esto debería hacer:

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

respondido 02 nov., 14:16

Tuve un problema simple, pero las respuestas a esta pregunta me desconcertaron.

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

Para esto hice lo siguiente:

Cargó el código JavaScript en el archivo HTML, en el orden correcto, primero myvariables.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 vio, usé una variable en un archivo JavaScript en otro archivo JavaScript, pero no necesitaba incluir una en otro. Solo necesitaba asegurarme de que el primer archivo JavaScript se cargue antes que el segundo archivo JavaScript, y las variables del primer archivo JavaScript sean accesibles en el segundo archivo JavaScript, automáticamente.

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

Respondido el 11 de diciembre de 16 a las 12:12

En un lenguaje moderno con la verificación si el script ya se ha cargado, sería:

function loadJs( url ){
  return new Promise(( resolve, reject ) => {
    if (document.querySelector( `head > script[ src = "${url}" ]`) !== null ){
        console.warn( `script already loaded: ${url}` );
        resolve();
    }
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    script.onerror = function( reason ){
        // This can be useful for your error-handling code
        reason.message = `error trying to load script ${url}`;
        reject( reason );
    };
    document.head.appendChild( script );
  });
}

Uso (asincrónico / en espera):

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

or

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

Uso (promesa):

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

Respondido 03 Oct 20, 22:10

Esto es muy bueno si desea evitar tener que involucrarse en módulos y no desea usar una función de devolución de llamada, pero desea usar async / await. - mike roedor

En caso de que estés usando Trabajadores web y desea incluir scripts adicionales en el alcance del trabajador, las otras respuestas proporcionadas sobre cómo agregar scripts al head etiqueta, etc. no funcionará para usted.

Afortunadamente, Los Web Workers tienen los suyos importScripts función que es una función global en el alcance del Web Worker, nativa del propio navegador, ya que es parte de la especificación.

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

contestado el 23 de mayo de 17 a las 15:05

La @import La sintaxis para lograr la importación de JavaScript similar a CSS es posible utilizando una herramienta como Mixture a través de su especial .mix tipo de archivo (ver aquí). Supongo que la aplicación hace esto a través de uno de los métodos mencionados anteriormente.

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

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

Aquí un ejemplo .mix archivo que combina varios .js archivos 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 genera esto como scripts-global.js y también como versión minificada (scripts-global.min.js).

Nota: No estoy afiliado de ninguna manera con Mixture, aparte de usarlo como una herramienta de desarrollo de front-end. Me encontré con esta pregunta al ver un .mix Archivo JavaScript en acción (en una de las plantillas de Mixture) y estar un poco confundido por él ("¿puedes hacer esto?", Pensé para mí). Luego 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.

Nota: La mezcla se suspendió el 2016/07/26 (después de ser de código abierto el 2015/04/12).

Respondido 05 Oct 20, 20:10

Es mejor evitar "Actualizar" (metainformación que pertenece al historial de revisión de esta publicación). En su lugar, aplíquelo al contenido (no a esta publicación), p. Ej. "La mezcla se obtuvo de código abierto el 2015 de abril de 04 y se suspendió el 12 de julio de 2016". - Peter Mortensen

Aunque estas respuestas son excelentes, existe una "solución" simple que ha existido desde que existió la carga de scripts y cubrirá el 99.999% de los casos de uso de la mayoría de las personas. Simplemente incluya el script que necesita antes del script que lo requiere. Para la mayoría de los proyectos, no se necesita mucho tiempo para determinar qué scripts se necesitan y en qué orden.

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

Si script2 requiere script1, esta es realmente la forma más sencilla de hacer algo como esto. Estoy muy sorprendido de que nadie haya mencionado esto, ya que es la respuesta más obvia y simple que se aplicará en casi todos los casos.

Respondido 12 Abr '18, 22:04

Esta es una buena respuesta. Es posible que se haya perdido porque no responde directamente a la pregunta, pero también es importante comprender que "normalmente no es necesario hacer eso". Especialmente porque las otras soluciones son tan complicadas. - Nathan Kovner

¿Pero esto solo funciona en un navegador web? ¿Qué pasa con las pruebas unitarias fuera de línea (por ejemplo, en Node.js)? - Peter Mortensen

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

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

document.body.appendChild(js);

Respondido 22 ago 12, 10:08

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 utiliza recargas de página para mí. Probé 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 asincrónico para que no bloquee el resto del código, pero llama a una devolución de llamada cuando readyState (el estado del contenido que se va a cargar) cambia a "cargado".

Respondido 26 ago 17, 20:08

Escribí un módulo simple que automatiza el trabajo de importar / incluir scripts de módulos en JavaScript. Para obtener una explicación detallada del código, consulte la publicación del blog. JavaScript requiere / 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);
};

Respondido 19 Oct 14, 22:10

Módulos ES6

, use type = "module" en una etiqueta de secuencia de comandos (AYUDA):

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

Y en una script.js archivo incluye otro archivo como este:

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

En 'module.js' debes exportar la función / clase que importarás:

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

Un trabajo ejemplo está aquí.

Respondido 03 Oct 20, 23:10

Hay varias formas de implementar módulos en JavaScript. Aquí están los dos más populares:

Módulos ES6

Los navegadores aún no admiten este sistema de modulación, por lo que para poder utilizar esta sintaxis debe utilizar un paquete como Webpack. De todos modos, usar un paquete es mejor porque puede combinar todos sus archivos diferentes en uno solo (o un par de archivos relacionados). Esto servirá los archivos desde el servidor al cliente más rápido porque cada solicitud HTTP tiene una sobrecarga asociada acompañada. Por lo tanto, al reducir la solicitud HTTP general, mejoramos el rendimiento. Aquí hay un ejemplo de módulos 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 (usado en Node.js)

Este sistema de modulación se utiliza en Node.js. Básicamente, agrega sus exportaciones a un objeto que se llama module.exports. A continuación, puede acceder a este objeto a través de un require('modulePath'). Importante aquí es darse cuenta de que estos módulos se están almacenando en caché, por lo que si require() un cierto módulo dos veces devolverá el módulo ya creado.

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

Respondido 03 Oct 20, 23:10

También hay Head.js. Es muy fácil lidiar con:

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

Como ve, es más fácil que Require.js y tan conveniente como jQuery's $.getScript método. También tiene algunas funciones avanzadas, como carga condicional, detección de funciones y mucho más.

Respondido 19 Oct 14, 22:10

Hay muchas respuestas potenciales para esta pregunta. Obviamente, mi respuesta se basa en varios de ellos. Esto es con lo que terminé después de leer 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 unos de otros, ya no tiene forma de saber cuándo se han cargado todos los scripts (una vez que están anidados en varios archivos ).

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 que Ajax se ejecute sincrónicamente o use XMLHttpRequest, pero la tendencia actual parece ser desaprobar las solicitudes síncronas, por lo que es posible que no obtenga la compatibilidad total del navegador ahora o en el futuro.

Podrías intentar usar $.when para verificar una matriz de objetos diferidos, pero ahora está haciendo esto en cada archivo y el archivo2 se considerará cargado tan pronto como el $.when se ejecuta no cuando se ejecuta la devolución de llamada, por lo que file1 aún continúa la ejecución antes de que se cargue file3. 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 siempre que se use correctamente, funciona bien. Termina con un código que se puede depurar fácilmente, se muestra en el DOM correctamente y puede garantizar el orden en que las dependencias se cargan correctamente.

Por supuesto, puede usar $ ("body"). Append (), pero ya no podrá depurar correctamente.

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

Me gustó la idea de extender jQuery, pero obviamente no es necesario.

Antes de llamar document.writeln, verifica que el script no se haya cargado ya evaluando todos los elementos del script.

Supongo que un script no se ejecuta completamente hasta que se document.ready se ha ejecutado el evento. (Yo sé usar document.ready no es obligatorio, pero mucha gente lo usa, y manejar esto es una salvaguarda).

Cuando se cargan los archivos adicionales, document.ready las devoluciones de llamada se ejecutarán en el orden incorrecto. Para solucionar este problema cuando se carga un script, el script que lo importó se vuelve a importar y se detiene la ejecución. Esto hace que el archivo de origen ahora tenga su document.ready devolución de llamada ejecutada después de cualquiera de los scripts que importe.

En lugar de este enfoque, puede intentar modificar jQuery readyList, pero esta 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:

Archivo3:

var f3obj = "file3";

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

Archivo2:

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

Archivo1:

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

Respondido el 20 de junio de 20 a las 12:06

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

  1. Configura un archivo llamado "plugins.js" (o extensions.js o lo que quieras). Mantenga sus archivos de complemento junto con ese archivo maestro.

  2. plugins.js tendrá una matriz llamada pluginNames[] que iteraremos sobre each(), luego agregue un <script> etiqueta en la cabeza para cada complemento

//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. Llame manualmente solo el archivo en su cabeza:
    <script src="js/plugins/plugins.js"></script>

PERO:

Aunque todos los complementos se colocan en la etiqueta principal como deberían, el navegador no siempre los ejecuta cuando hace clic en la página o actualiza.

Descubrí que es más confiable simplemente escribir las etiquetas de script en una inclusión de PHP. Solo tiene que escribirlo una vez y eso es tanto trabajo como llamar al complemento usando JavaScript.

Respondido el 10 de enero de 20 a las 08:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.