¿Hay algo en JavaScript similar a @import
CSS que le permita incluir un archivo JavaScript dentro de otro archivo JavaScript?
javascript
file
import
include
Alec Smart
fuente
fuente
script
etiquetas ordenadas ?Respuestas:
Las versiones anteriores de JavaScript no tenían importancia para importar, incluir o requerir, por lo que se han desarrollado muchos enfoques diferentes para este problema.
Pero desde 2015 (ES6), JavaScript ha tenido el estándar de módulos ES6 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, puede usar herramientas de compilación como Webpack y Rollup y / o herramientas de transpilación como Babel .
Módulos ES6
Los módulos ECMAScript (ES6) se han admitido en Node.js desde v8.5, con el
--experimental-modules
indicador, y desde al menos Node.js v13.8.0 sin el indicador. Para habilitar "ESM" (vs sistema de módulos de estilo CommonJS anterior de Node.js [ "CJS"]) que sea para uso"type": "module"
enpackage.json
o dar los archivos de la extensión.mjs
. (Del mismo modo, los módulos escritos con el módulo CJS anterior de Node.js se pueden nombrar.cjs
si su valor predeterminado es ESM).Utilizando
package.json
:Entonces
module.js
:Entonces
main.js
:Usando
.mjs
, tendríasmodule.mjs
:Entonces
main.mjs
: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. Verifique el soporte actual en caniuse . No hay necesidad de usar la
.mjs
extensión Node.js ; los navegadores ignoran por completo las extensiones de archivo en módulos / scripts.Lea 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:
Obtenga más información en https://developers.google.com/web/updates/2017/11/dynamic-import
Node.js requiere
El estilo de módulo CJS anterior, que todavía se usa ampliamente en Node.js, es el
module.exports
/require
system.Hay otras formas para que JavaScript incluya contenido externo de JavaScript en navegadores que no requieren preprocesamiento.
Carga AJAX
Puede cargar un script adicional con una llamada AJAX y luego usarlo
eval
para ejecutarlo. Esta es la forma más sencilla, pero está limitada a su dominio debido al modelo de seguridad de sandbox de JavaScript. El usoeval
también abre la puerta a errores, hacks y problemas de seguridad.Recuperar carga
Al igual que Dynamic Imports, puede cargar uno o varios scripts con una
fetch
llamada usando promesas para controlar el orden de ejecución de las dependencias de script usando la biblioteca Fetch Inject :jQuery Loading
La biblioteca jQuery proporciona funcionalidad de carga en una línea :
Carga dinámica de guiones
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 incluso puede residir en un servidor diferente. Además, el navegador evalúa el código. La
<script>
etiqueta puede inyectarse en la página web<head>
o insertarse justo antes de la</body>
etiqueta de cierre .Aquí hay un ejemplo de cómo esto podría funcionar:
Esta función agregará una nueva
<script>
etiqueta al final de la sección de encabezado de la página, donde elsrc
atributo se establece en la URL que se le asigna a la función como primer parámetro.Ambas soluciones se analizan e ilustran en JavaScript Madness: Dynamic Script Loading .
Detectando cuando el script ha sido ejecutado
Ahora, hay un gran problema que debes conocer. Hacer eso implica que cargue el código de forma remota . Los navegadores web modernos cargarán el archivo y seguirán ejecutando su script actual porque cargan todo de forma asíncrona 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 solicitar que se cargue , porque todavía se cargará.
Por ejemplo:
my_lovely_script.js
contieneMySuperObject
:Luego vuelves a cargar la página golpeando 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 apuradas, 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:
Luego escribe el código que desea usar DESPUÉS de que el script se carga en una función lambda :
Entonces ejecutas todo eso:
Tenga en cuenta que el script 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 un gran artículo sobre la carga de Javascript en general que analiza esto.Código fuente de fusión / preprocesamiento
Como se menciona 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 de navegadores antiguos, combinar archivos, minimizar, realizar división de código, etc.
fuente
onreadystatechange
evento yreadyState
propiedad). Además, la carga de scripts dinámicos no se beneficia de los escáneres de precarga del broswer. Recomiende este artículo HTML5Rocks: html5rocks.com/en/tutorials/speed/script-loadingSi 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 "módulos" y luego hacer referencia a ellos como dependencias en otros scripts. O puede usar RequireJS como una solución simple "vaya a buscar este script".
Ejemplo:
Definir dependencias como módulos:
some-dependency.js
implement.js es su archivo JavaScript "principal" que depende de some-dependency.js
Extracto del archivo README de GitHub :
fuente
En realidad, hay una manera de cargar un archivo JavaScript no asincrónicamente, 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.
Debe usar
jQuery.append()
el<head>
elemento de su página, es decir: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 también) informarán su lugar incorrectamente, lo cual es un gran problema si usa Firebug para rastrear Los errores de JavaScript bajan mucho (lo hago). Firebug simplemente no conoce el archivo recién cargado por algún motivo, por lo que si se produce un error en ese archivo, informa que se produjo en su archivo HTML principal y tendrá problemas para descubrir el motivo real del error.
Pero si eso no es un problema para usted, entonces este método debería funcionar.
De hecho, he escrito un complemento jQuery llamado $ .import_js () que usa este método:
Entonces, todo lo que necesitaría hacer para importar JavaScript es:
También hice una prueba simple para esto en Example .
Incluye un
main.js
archivo en el HTML principal y luego el script semain.js
usa$.import_js()
para importar un archivo adicional llamadoincluded.js
, que define esta función:Y justo después de incluir
included.js
,hello()
se llama a la función y obtienes la alerta.(Esta respuesta es en respuesta al comentario de e-satis).
fuente
jQuery.getScript
, así no tienes que preocuparte por escribir el complemento ...script
elementohead
hará que se ejecute de forma asíncrona, a menos queasync
se establezca específicamente enfalse
."
código, se romperáOtra forma, que en mi opinión es mucho más limpia, es hacer una solicitud Ajax sincrónica en lugar de usar una
<script>
etiqueta. Que también es cómo incluye Node.js.Aquí hay un ejemplo usando jQuery:
Luego puede usarlo en su código, ya que generalmente usaría un include:
Y poder llamar a una función desde el script requerido en la siguiente línea:
fuente
async: false
supuestamente está en desuso. ¡No lo es! Como dice su cita, solo lo relacionado con jqXHR es.Hay una buena noticia para ti. Muy pronto podrá cargar el código JavaScript fácilmente. Se convertirá en una forma estándar de importar módulos de código JavaScript y formará parte del núcleo de JavaScript.
Simplemente tiene que escribir
import cond from 'cond.js';
para cargar una macro nombradacond
desde un archivocond.js
.Por lo tanto, no tiene que confiar en ningún marco de JavaScript ni debe hacer explícitamente llamadas Ajax .
Referirse a:
Resolución del módulo estático
Cargadores modulares
fuente
Es posible generar dinámicamente una etiqueta JavaScript y agregarla al documento HTML desde otro código JavaScript. Esto cargará el archivo JavaScript dirigido.
fuente
js.onload = callback;
La declaración
import
está en ECMAScript 6.Sintaxis
fuente
Quizás pueda usar esta función que encontré en esta página ¿Cómo incluyo un archivo JavaScript en un archivo JavaScript? :
fuente
script.onload = callback;
var
, ¿la variable será global?head
.Aquí hay una versión sincrónica sin jQuery :
Tenga en cuenta que para que este dominio cruzado funcione, el servidor deberá establecer el
allow-origin
encabezado en su respuesta.fuente
http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)<script>
etiqueta insertada , no a través deXMLHttpRequest
.const XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1");
Acabo de escribir este código JavaScript (usando Prototype para la manipulación DOM ):
Uso:
Gist: http://gist.github.com/284442 .
fuente
Aquí está la versión generalizada de cómo Facebook lo hace por su ubicuo botón Me gusta:
Si funciona para Facebook, funcionará para usted.
La razón por la que buscamos el primer
script
elemento en lugar dehead
obody
es porque algunos navegadores no crean uno si faltan, pero estamos garantizados de tener unscript
elemento: este. Lea más en http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .fuente
Si quieres en JavaScript puro, puedes usarlo
document.write
.Si usa la biblioteca jQuery, puede usar el
$.getScript
método.fuente
También puedes ensamblar tus scripts usando PHP :
Archivo
main.js.php
:fuente
La mayoría de las soluciones que se muestran aquí implican una carga dinámica. Estaba buscando un compilador que reúne todos los archivos dependientes en un solo archivo de salida. Lo mismo que los preprocesadores Less / Sass tratan con la
@import
regla at CSS . 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 seguridad el contenido del archivo solicitado. Aquí está el complemento Grunt correspondiente : https://github.com/dsheiko/grunt-jsic .En la rama maestra jQuery, simplemente concatenan los archivos de origen atómico en uno solo que comienza
intro.js
y termina conouttro.js
. Eso no me conviene, ya que no proporciona flexibilidad en el diseño del código fuente. Mira cómo funciona con jsic:src / main.js
src / Form / Input / Tel.js
Ahora podemos ejecutar el compilador:
Y obtener el archivo combinado
build / main.js
fuente
Si su intención de cargar el archivo JavaScript está 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
file1.js
file2.js
main.js
Solo debe tener cuidado cuando incluya scripts en un archivo HTML. El orden debe ser el siguiente:
fuente
Esto debería hacer:
fuente
eval
es lo que está mal con él. De Crockford , "eval
que es malo. Laeval
función es la característica más mal uso de JavaScript. Evitarla.eval
Tiene alias. No utilice elFunction
constructor. No pase cuerdas asetTimeout
osetInterval
." Si no ha leído su "JavaScript: las partes buenas", salga y hágalo ahora mismo. No te arrepentirás.http://web.archive.org/web/20140905044059/http://www.howtocreate.co.uk/operaStuff/userjs/aagmfunctions.js
)O, en lugar de incluir en tiempo de ejecución, use un script para concatenar antes de cargar.
Yo uso Sprockets (no sé si hay otros). Construye su código JavaScript en archivos separados e incluye comentarios procesados por el motor Sprockets como incluye. Para el desarrollo, puede incluir archivos secuencialmente, luego, para la producción, fusionarlos ...
Ver también:
fuente
Tenía 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:
Cargó el código JavaScript en el archivo HTML, en el orden correcto, myvariables.js primero, luego main.js:
Archivo: myvariables.js
Archivo: main.js
Como viste, había usado una variable en un archivo JavaScript en otro archivo JavaScript, pero no necesitaba incluir uno en otro. Solo necesitaba asegurarme de que el primer archivo JavaScript se cargara antes que el segundo archivo JavaScript, y que las variables del primer archivo JavaScript estén accesibles en el segundo archivo JavaScript, automáticamente.
Esto me salvó el día. Espero que esto ayude.
fuente
import
. Necesita un archivo HTML para obtener cosas de un archivo js a otro.<script>
etiqueta. Esto puede ayudar con la organización. Esta respuesta simplemente no es lo que la pregunta estaba pidiendo, y no es ideal en este contexto.En caso de que esté utilizando Web Workers y desee incluir scripts adicionales en el ámbito del trabajador, las otras respuestas proporcionaron sobre la adición de scripts a
head
etiqueta, etc., no funcionarán para usted.Afortunadamente, los Web Workers tienen su propia
importScripts
función, que es una función global en el ámbito del Web Worker, nativa del navegador, ya que forma parte de la especificación .Alternativamente, como destaca la segunda respuesta más votada a su pregunta , RequireJS también puede manejar la inclusión de scripts dentro de un Web Worker (probablemente llamándose a
importScripts
sí mismo, pero con algunas otras características útiles).fuente
En lenguaje moderno con la comprobación de si el script ya se ha cargado, sería:
Uso (asíncrono / espera):
o
Uso (promesa):
fuente
var pi = 3.14
. llame a la función loadJS () a través deloadJs("pi.js").then(function(){ console.log(pi); });
La
@import
sintaxis para lograr la importación de JavaScript similar a CSS es posible utilizando una herramienta como Mixture a través de su.mix
tipo de archivo especial (consulte aquí ). Me imagino que la aplicación simplemente usa uno de los métodos antes mencionados de forma interna, aunque no lo sé.De la documentación de la Mezcla en los
.mix
archivos:Aquí hay un
.mix
archivo de ejemplo que combina varios.js
archivos en uno:Mixture genera esto como
scripts-global.js
y también como una versión minimizada (scripts-global.min.js
).Nota: de ninguna manera estoy afiliado a Mixture, aparte de usarlo como una herramienta de desarrollo front-end. Encontré esta pregunta al ver un
.mix
archivo JavaScript en acción (en una de las repeticiones de Mixture) y estar un poco confundido ("¿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.ACTUALIZACIÓN : La mezcla ahora es gratuita (sin conexión).
ACTUALIZACIÓN : La mezcla ahora se descontinúa. Los lanzamientos de mezclas antiguas todavía están disponibles
fuente
fuente
body
aún no existe o no se puede modificar. Además, ayuda a explicar las respuestas.Mi método habitual es:
Funciona muy bien y no utiliza 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 readyState (el estado del contenido que se va a cargar) cambia a 'cargado'.
fuente
Aunque estas respuestas son excelentes, existe una "solución" simple que existe 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 lleva mucho tiempo determinar qué scripts son necesarios y en qué orden.
Si script2 requiere script1, esta es realmente la forma más fácil de hacer algo como esto. Estoy muy sorprendido de que nadie haya mencionado esto, ya que es la respuesta más obvia y más simple que se aplicará en casi todos los casos.
fuente
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 require / import / include modules .
fuente
Este script agregará un archivo JavaScript en la parte superior de cualquier otra
<script>
etiqueta:fuente
También hay Head.js . Es muy fácil tratar con:
Como puede ver, es más fácil que Require.js y tan conveniente como el
$.getScript
método de jQuery . También tiene algunas funciones avanzadas, como carga condicional, detección de funciones y mucho más .fuente
Hay muchas respuestas potenciales para esta pregunta. Mi respuesta obviamente se basa en varios de ellos. Esto es lo que terminé después de leer todas las respuestas.
El problema
$.getScript
y 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 el uno del otro, ya no tiene una manera de saber cuándo se han cargado todos los scripts (una vez que están anidados) en múltiples archivos).Ejemplo:
file3.js
file2.js:
file1.js:
Tiene razón cuando dice que podría especificar que Ajax se ejecute sincrónicamente o usar XMLHttpRequest , pero parece que la tendencia actual es desaprobar las solicitudes sincrónicas, por lo que es posible que no obtenga soporte completo del navegador ahora o en el futuro.
Puede intentar usar
$.when
para verificar una matriz de objetos diferidos, pero ahora lo está haciendo en cada archivo y el archivo2 se considerará cargado tan pronto como$.when
se ejecute, no cuando se ejecute la devolución de llamada, por lo que el archivo1 aún continúa la ejecución antes de cargar el archivo3 . 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, esto 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 puede depurar correctamente.
NOTA: debe usar esto solo mientras se carga la página; de lo contrario, aparecerá una pantalla en blanco. En otras palabras, siempre coloque esto antes / fuera de document.ready . No he probado usar esto después de que la página se carga 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 es necesario.
Antes de llamar
document.writeln
, verifica para asegurarse de que el script no se haya cargado ya evaluando todos los elementos del script.Supongo que un script no se ejecuta completamente hasta
document.ready
que se haya ejecutado su evento. (Sé que el usodocument.ready
no es obligatorio, pero muchas personas lo usan, y manejar esto es una salvaguardia).Cuando se cargan los archivos adicionales, las
document.ready
devoluciones de llamada se ejecutarán en el orden incorrecto. Para solucionar esto cuando un script se carga realmente, el script que lo importó se vuelve a importar y la ejecución se detiene. Esto hace que el archivo de origen ahora tenga sudocument.ready
devolución de llamada 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:
Uso:
Archivo3:
Archivo2:
Archivo1:
fuente
Existen varias formas de implementar módulos en Javascript. Estas son las 2 más populares:
Módulos ES6
Los navegadores aún no admiten este sistema de modulación, por lo que para que pueda usar esta sintaxis, debe usar un paquete como webpack. Usar un paquete es mejor de todos modos porque puede combinar todos sus archivos diferentes en un solo archivo (o un par relacionado). Esto servirá los archivos del 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:
CommonJS (utilizado en NodeJS)
Este sistema de modulación se usa en NodeJS. Básicamente agrega sus exportaciones a un objeto que se llama
module.exports
. Luego puede acceder a este objeto a través de arequire('modulePath')
. Lo importante aquí es darse cuenta de que estos módulos se están almacenando en caché, por lo que sirequire()
un determinado módulo dos veces devolverá el módulo ya creado.fuente
Llegué a esta pregunta porque estaba buscando una manera simple de mantener una colección de complementos útiles de JavaScript. Después de ver algunas de las soluciones aquí, se me ocurrió esto:
Configure un archivo llamado "plugins.js" (o extensiones.js o lo que quiera). Mantenga sus archivos de complemento junto con ese archivo maestro.
plugins.js tendrá una matriz llamada
pluginNames[]
que iteraremoseach()
, luego agregaremos una<script>
etiqueta a la cabeza para cada complemento<script src="js/plugins/plugins.js"></script>
PERO:
A pesar de que todos los complementos se colocan en la etiqueta principal de la forma en que deberían hacerlo, el navegador no siempre los ejecuta cuando hace clic en la página o se actualiza.
He encontrado que es más confiable simplemente escribir las etiquetas de script en un PHP incluido. Solo tiene que escribirlo una vez y eso es tanto trabajo como llamar al complemento usando JavaScript.
fuente