Pregunta ¿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?


4146
2018-06-04 11:59


origen


Respuestas:


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

Pero las versiones recientes de JavaScript tienen estándares como Módulos ES6 para importar módulos, aunque esto aún no es compatible con la mayoría de los navegadores. Muchas personas que usan módulos con aplicaciones de navegador usan construir y / o transpiración herramientas para que sea práctico usar nueva sintaxis con funciones como módulos.

Módulos ES6

Tenga en cuenta que actualmente, el soporte del navegador para los módulos ES6 no es particularmente bueno, pero está en camino. De acuerdo a esta respuesta StackOverflow, son compatibles con Chrome 61, Firefox 54 (detrás de dom.moduleScripts.enabled instalándose about:config) y MS Edge 16, con solo Safari 10.1 que proporciona soporte sin banderas.

Por lo tanto, en este momento, todavía necesitará usar herramientas de compilación y / o transpilación para JavaScript válido que se ejecutará sin ningún requisito para que el usuario use esas versiones de navegador o habilite cualquier marca.

Una vez que los módulos de ES6 son comunes, aquí se explica cómo utilizarlos:

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

Node.js requiere

Node.js está utilizando actualmente un module.exports / require sistema. Puedes usar babel para transpilar si quieres el import sintaxis.

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

Existen otras formas en que JavaScript puede incluir contenido de 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 directa, 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, intrusiones y problemas de seguridad.

jQuery Cargando

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

Podría 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 incluso puede residir en un servidor diferente. Además, el navegador evalúa el código. los <script> etiqueta puede ser inyectada en la página web <head>, o insertado justo antes del cierre </body> etiqueta.

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

function dynamicallyLoadScript(url) {
    var script = document.createElement("script"); // Make a script DOM node
    script.src = url; // Set it's 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 de la cabeza de la página, donde src atributo se establece en la URL que se le da a la función como el primer parámetro.

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

Detectando cuando el script ha sido ejecutado

Ahora, hay un gran problema que debes conocer. Hacer eso implica que Usted carga el código de forma remota. Los navegadores web modernos cargarán el archivo y seguirán ejecutando su secuencia de comandos actual, ya que cargan todo de manera 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 usas estos trucos directamente, no podrá usar el código que acaba de cargar en la siguiente línea después de haber solicitado que se cargue, porque aún 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 recarga la página golpeando F5. ¡Y funciona! Confuso...

Entonces, ¿qué hacer al respecto?

Bueno, puedes usar el truco que el autor sugiere en el enlace que te di. En resumen, para las personas que tienen prisa, utiliza 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.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, 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
};

Entonces ejecutas todo eso:

loadScript("my_lovely_script.js", myPrettyCode);

Tenga en cuenta que la secuencia de comandos se puede ejecutar después de que DOM se haya cargado, 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.

Combinación de código fuente / preprocesamiento

Como se menciona en la parte superior de esta respuesta, muchos desarrolladores ahora usan herramientas de compilación / transpilación como WebPack, Babel o Gulp en sus proyectos, lo que les permite utilizar mejor la sintaxis y los módulos de soporte, combinar archivos, minimizar, etc.


3579
2018-06-04 12:13



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

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

Ejemplo:

Definir dependencias como módulos:

some-dependency.js

define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {

     //Your actual script goes here.   
     //The dependent scripts will be fetched if necessary.

     return libraryObject;  //For example, jQuery object
});

implementation.js es tu 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 de la GitHub README:

RequireJS carga archivos JavaScript simples y más definidos   módulos. Está optimizado para uso en el navegador, incluso en una Web   Trabajador, pero se puede usar en otros entornos de JavaScript, como   Rhino y nodo. Implementa la API del módulo asíncrono.

RequireJS usa etiquetas de script simples para cargar módulos / archivos, por lo que debería   permitir una depuración fácil. Se puede usar simplemente para cargar el existente   Archivos de JavaScript, por lo puedes agregarlo a tu proyecto existente sin   tener que volver a escribir tus archivos de JavaScript.

...


513
2018-06-07 20:55



En realidad es 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()sobre el <head> elemento 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 Herramientas de desarrollo de Chrome también) informará su lugar incorrectamente, que es un gran problema si usa Firebug para rastrear mucho los errores de JavaScript (lo hago). Firebug simplemente no sabe acerca del 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 descubrir la verdadera razón del error.

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

De hecho, he escrito un plugin jQuery llamado $ .import_js () que usa 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 necesitaría 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, el hello() se llama a la función y obtienes la alerta.

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


162
2018-04-28 15:25



Otra forma, que en mi opinión es mucho más limpia, es hacer una solicitud síncrona de Ajax en lugar de usar una <script> etiqueta. Que también es como Node.js mangos 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, ya que generalmente usaría un include:

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

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

subscript.doSomethingCool(); 

133
2017-09-08 18:22



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

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

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

Referirse a:


86
2017-07-03 13:32



Es posible generar dinámicamente una etiqueta JavaScript y anexarla a un documento HTML desde otro código JavaScript. Esto cargará el archivo JavaScript específico.

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

72
2018-06-04 12:02



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;

58
2018-04-17 01:56



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

47
2018-06-04 12:04