¿Existe algo similar a @import
en CSS en JavaScript que permite incluir un archivo JavaScript dentro de otro archivo JavaScript?
Respuestas
¿Demasiados anuncios?No hay ningún import, include o require en JavaScript, pero hay dos formas principales de conseguir lo que quieres:
1 - Puedes cargarlo con una llamada Ajax y luego usar eval.
Esta es la forma más directa, pero está limitada a su dominio debido a la configuración de seguridad de JavaScript, y el uso de eval
está abriendo la puerta a bugs y hacks.
2 - Añadir una etiqueta script con la URL script en el HTML.
Esta es definitivamente la mejor manera de hacerlo. Puedes cargar el script incluso desde un servidor ajeno, y es limpio ya que utilizas el parser del navegador para evaluar el código. Puedes poner el <script />
en la cabecera de la página web, o en la parte inferior del cuerpo.
Ambas soluciones se analizan e ilustran en La locura de JavaScript: Carga dinámica de script .
Ahora, hay un tema importante que debes conocer. Hacerlo implica que se carga el código de forma remota . Los navegadores web modernos cargarán el archivo y seguirán ejecutando su actual script porque cargan todo de forma asíncrona para mejorar el rendimiento.
Esto significa que si usas estos trucos directamente, no podrá utilizar su código recién cargado la siguiente línea después de haber pedido que se cargue porque todavía se está 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 se recarga la página pulsando F5 . ¡Y funciona! Confuso...
¿Qué hacer al respecto?
Pues puedes usar el hack que sugiere el autor en el enlace que te he dado. En resumen, para la gente con prisa, utiliza en evento para ejecutar una función callback cuando se carga el script. Así puedes poner todo el código que usa la librería remota en la función callback. 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);
}
Entonces escribes el código que quieres usar DESPUÉS de que el script se cargue en un función lambda :
var myPrettyCode = function() {
// Here, do what ever you want
};
Entonces, ejecuta todo eso:
loadScript("my_lovely_script.js", myPrettyCode);
Bien, lo tengo. Pero es un dolor para escribir todo esto.
Pues bien, en ese caso, puedes utilizar como siempre la fantástica herramienta gratuita jQuery que te permite hacer lo mismo en una línea :
$.getScript("my_lovely_script.js", function(){
alert("Script loaded and executed.");
// Here you can use anything you defined in the loaded script
});
Si alguien busca algo más avanzado, pruebe RequireJS . Obtendrás beneficios adicionales como la gestión de dependencias, una mejor concurrencia y evitarás la duplicación (es decir, recuperar un script más de una vez).
Puedes escribir tus archivos JavaScript en "módulos" y luego referenciarlos como dependencias en otros scripts. O puedes usar RequireJS como una simple solución "ve a buscar este scriptsscriptscripts".
Ejemplo:
Definir las 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
});
implementación.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 del GitHub LÉAME:
RequireJS carga archivos JavaScript simples, así como módulos más definidos módulos. Está optimizado para su uso en el navegador, incluso en un Web Worker, pero puede utilizarse en otros entornos JavaScript, como Rhino y Node. Implementa la API de módulos asíncronos.
RequireJS utiliza etiquetas script para cargar módulos/archivos, por lo que debería permitir una fácil depuración. Se puede utilizar simplemente para cargar archivos archivos JavaScript existentes, por lo que puede añadirlo a su proyecto existente sin tener que reescribir sus archivos JavaScript.
...
En realidad, hay es una forma de cargar un archivo JavaScript no de forma asíncrona, por lo que podrías utilizar las funciones incluidas en tu archivo recién cargado justo después de cargarlo, y creo que funciona en todos los navegadores.
Es necesario utilizar jQuery.append()
en el <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 se produce un error en el archivo JavaScript importado, Firebug (y también la consola de errores de Firefox y Herramientas para desarrolladores de Chrome también) informará de su lugar de forma incorrecta, lo que es un gran problema si usted utiliza Firebug para rastrear los errores de JavaScript mucho (yo lo hago). Firebug simplemente no sabe sobre el archivo recién cargado por alguna razón, así que si un error ocurre en ese archivo, reporta que ocurrió en su archivo principal HTML y tendrá problemas para averiguar 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 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 tendría que hacer para importar JavaScript es:
$.import_js('/ruta_al_proyecto/scripts/somefunctions.JS');
También hice una prueba sencilla para esto en http://www.kipras.com/dev/import_js_test/ .
Incluye un main.js
en el HTML principal y luego el script en main.js
utiliza $.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 se obtiene la alerta.
(Esta respuesta es en respuesta al comentario de e-satis).
Otra forma, que en mi opinión es mucho más limpia, es hacer una petición Ajax sincrónica en lugar de utilizar un <script>
etiqueta. Que es también la forma en que Node.JS Las asas incluyen.
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);
}
});
}
A continuación, puede utilizarlo en su código como lo haría normalmente con un include:
require("/scripts/subscript.js");
Y poder llamar a una función desde el script requerido en la siguiente línea:
subscript.doSomethingCool();
Hay una buena noticia para usted. Muy pronto podrás cargar javascript fácilmente. Se convertirá en una forma estándar de importar módulos de javascript y formará parte del propio núcleo de javascript.
Simplemente tienes que escribir import cond from 'cond.js';
para cargar una macro llamada cond
de un archivo cond.js
Así que no tienes que depender de ningún framework javascript ni tienes que hacer explícitamente llamadas AJAX Consulte los siguientes enlaces