diferencias - ¿Cómo se mitiga la biblioteca de JavaScript con Web Components?
web components javascript (7)
Digamos que desarrollo el componente A que tiene una dependencia para underscore.js y quiero usar los componentes B y C que tienen dependencias en lodash.js versión 1. *, etc. No veo ninguna forma de marcar las dependencias y las versiones de la biblioteca.
Existe una antigua especificación de ECMA de 1999 (ECMA-290) que especificaba un mecanismo de componentes que incluía elementos y atributos para las dependencias y las versiones de la biblioteca:
<component
name="com.mycompany.selectnav"
displayname="SelectNav"
src="selectnav.js"
env="client"
hint="Navigational Select List"
version="1.0"
needsform="yes">
</component>
Para dependencias, use el elemento de customizer
. Para versionar, use el elemento meta
. Por ejemplo:
<customizer type="ecmascript" url="http://com.com/foo">
<meta name="version" value="1.1b"/>
</customizer>
Una codificación JSON para la implementación moderna se vería así:
{
"component":
{
"name":"com.mycompany.selectnav",
"displayname":"SelectNav",
"src":"selectnav.js",
"env":"client",
"hint":"Navigational Select List",
"version":"1.0",
"needsform":"yes",
"customizer":
{
"type":"ecmascript",
"url":"http://com.com/foo",
"meta":
{
"name":"version",
"value":"1.1b"
}
}
}
}
Las retrollamadas de ciclo de vida integradas con una API de CDN , un comprobador de API y un gestor de scripts a pedido serían otra opción:
createdCallback => check API URL => createElement for dependent script tags => onload event for dependent script tags => appendChild for dependent script tags
Subconjunto de HTML como en los siguientes proyectos es una solución que se ha intentado numerosas veces:
GitHub - ampproject / amphtml: código fuente AMP HTML, muestras y documentación. Vea a continuación para obtener más información.
Referencias
Como alguien que ha intentado encontrar la manera de ayudar a los autores de contenido a desarrollar y mantener sitios web grandes mediante la creación de componentes (HTML) durante años, estoy realmente emocionado de ver cómo los componentes web ganan tracction en w3c, google y mozilla. Pero me parece que no hay ninguna medida contra la saturación de la biblioteca javascript en las especificaciones.
Digamos que desarrollo el componente A
que tiene una dependencia para underscore.js
y quiero usar los componentes B
y C
que tienen dependencias en lodash.js
versión 1. *, etc.
No veo ninguna forma de marcar las dependencias y las versiones de la biblioteca. Esto podría llevar a una gran cantidad de bibliotecas cuando hablamos de sitios web con múltiples equipos y partes interesadas.
La solución actual es estandarizar en un marco de cliente mayorista para todo el sitio web, a nivel mundial. Esto es difícil cuando ha invertido recursos sustanciales en diferentes marcos del lado del servidor como LifeRay
(java), EpiServer
(.net), Django
(python), etc., cada uno con bibliotecas preferidas del lado del cliente.
Veo los componentes web como un medio para desacoplar los marcos del lado del servidor del código del lado del cliente, pero la omisión del manejo de la dependencia del lado del cliente es preocupante.
¿Está en las especificaciones y lo he echado de menos, o hay una estrategia para mitigar este problema, de la que no tengo conocimiento?
[LAS BIBLIOTECAS MENCIONADAS SON SOLO EJEMPLOS. LA PREGUNTA ES AGNÓSTICA PARA EL MARCO, LA BIBLIOTECA Y EL LENGUAJE DEL SERVIDOR]
ACTUALIZACIÓN Gracias a todos por responder. Estoy sorprendido de que nadie mencione Mozilla X-Tag o Google Polymer, que últimamente ha sido una exageración. Admito por completo la idea de DOM sombreado, estilos de ámbito, elementos personalizados, etc., pero en ninguna parte veo ninguna mención de cómo tratar las dependencias de JavaScript. Como @ Daniel-Baulig escribe correctamente HTML Imports no menciona JavaScript en absoluto. Reconozco que esta pregunta es casi imposible de responder. Sin embargo, creo que @ Daniel-Bailig fue el más cercano, cuando mencionó los módulos ES6. Personalmente creo que encontraremos una solución sostenible en algún lugar entre los módulos ES6 y require.js.
En la especificación W3C actual, no parece haber una forma específica de definir dependencias o incluso de versionarlas. Se espera que los componentes no hagan uso de bibliotecas / dependencias o que estén estrechamente relacionados con ellos.
Esto significa que cada biblioteca principal probablemente traerá consigo su propio conjunto de componentes que esperan que esas bibliotecas se hayan cargado.
Tal vez los módulos ES6 brinden ayuda en este sentido, pero nuevamente tampoco ofrecen ningún mecanismo de control de versiones.
Todo eso dijo que la especificación se encuentra en una etapa bastante temprana y es probable que cambie. Llevar el problema de las dependencias con los autores de la especificación podría llevar ese tema a la mesa e incluso podría resolverse antes de que la especificación se solidifique. Al final, usar diferentes bibliotecas para realizar la misma tarea dentro de una única base de código siempre ha sido y seguirá siendo un problema en el desarrollo de software, independientemente de la plataforma y el idioma. Simplemente tendrá que acordar qué marcos / bibliotecas utilizar dentro de su base de código, incluso si eso significa que no puede cerrar el acceso a otros.
Además, si está interesado en desarrollar componentes independientes para la web hoy mismo, le recomendamos echar un vistazo a la biblioteca de React.
Este es un problema que me ha estado molestando también durante un tiempo, especialmente cuando me enfrento al mantenimiento de código que ha sido tocado por numerosos desarrolladores. A menudo se encuentran con varias bibliotecas JS (algunas de las cuales esencialmente hacen lo mismo) incluidas en una solución, por no mencionar incluso las diferentes versiones del mismo marco utilizado en una solución.
La solución potencial o más bien "a" que estoy viendo es crear un tipo de marco de mediación.
La idea básica es codificar "contra" el mediador (nunca accediendo / usando una biblioteca js directamente, pero usándola a través del mediador), lo que hace que el código sea independiente (desacoplado de su biblioteca "padre") e incluye una implementación de mediación debajo .
Esto no abordará mi / nuestro problema o abotagamiento inmediato, pero cualquiera que sea el componente web que escriba será capaz de ejecutar cross framework.
Aquí hay una pequeña prueba de concepto: Tagger Mediator POC
Ej. Mediadores incluidos para:
JQuery (1.9.1)
Mootools (1.4.5)
Prototipo (1.7.1.0)
YUI (3.10.3)
Dojo (1.9.1)
Ext (3.4.0)
Zepto (1.0)
Pero nada detiene a nadie a crear su propio marco de mediación, que "abstrae" a otros mediadores, hmmm, potencialmente algo que también puede contribuir a la hinchazón (empeorando las cosas en lugar de mejorar).
Supongo que depende de usted establecer sus propios estándares;)
He tenido dudas similares sobre los componentes web, pero luego comencé a trabajar con componentes de React de terceros. Tienen los mismos problemas porque traen consigo todas sus propias dependencias. Pero peor que eso, porque a React no le gusta vivir con otras versiones de React, los componentes de React deben incluir React como una Peer Dependency. Esto significa que está obligado a usar la misma versión de React que sus componentes de terceros.
¡Entonces mi conclusión es que esto es de hecho una característica de los componentes web! Cada elemento personalizado puede tener sus propias dependencias totalmente independientes del resto de su aplicación. Considero que los componentes de terceros son el principal caso de uso para Web Components; donde el consumidor quiere poder usar un componente con la menor fricción posible. Seguro que habrá algún código duplicado, pero el consumidor componente no necesita saber ni preocuparse. Creo que los autores de los componentes se ocuparán de esto mediante el uso de módulos más pequeños en sus componentes. Por ejemplo, en lugar de usar React, podrían usar algo como Snabbdom.
Si está creando una aplicación completa a partir de los componentes web que controla, puede utilizar una herramienta de compilación como Browserify o WebPack para administrar sus dependencias. Esto le permitirá anular ciertos módulos para que pueda incluso obligar a los componentes de terceros a utilizar las mismas versiones que el resto de su aplicación (consulte: https://www.npmjs.com/package/aliasify ). Eso podría romper algunos módulos, pero así es la vida.
La hinchazón de la biblioteca no se mitiga necesariamente mediante el uso de componentes web; de hecho, puede recortar bibliotecas utilizando compilaciones personalizadas (el enlace es para Lo-Dash, pero otras bibliotecas populares tienen pasos de compilación). Algún tipo de automatización aquí puede ser muy útil, es decir, una herramienta que puede escanear a través de su código fuente y generar una compilación personalizada en función de las funciones que está utilizando.
Creo que con el aumento de npm esas bibliotecas se vuelven cada vez menos relevantes. Lo-Dash es un buen ejemplo de esto porque sus funciones se lanzan en npm como módulos independientes , pero también tiene cosas como Sizzle , el motor de selección de CSS que utiliza jQuery. Si te fijas lo suficiente puedes encontrar muchos complementos que se escriben sin jQuery como dependencia, o está en la hoja de ruta de un proyecto para eliminar dependencias, o alguien ya ha bifurcado el proyecto para eliminar su dependencia de otra biblioteca. Por ejemplo, Exoskeleton , una versión completamente gratuita de Backbone & jQuery de Backbone.
No creo que veamos otra biblioteca de utilidad popular como jQuery o guión bajo; con npm podemos simplemente elegir los módulos que queremos, y proyectos fork que dependen de estas grandes bibliotecas para reescribirlos usando solo los módulos que necesitan, o una versión completamente libre de dependencia.
Con AMD y requirejs , esto ya es una realidad. Puede definir las dependencias de algunos códigos fuente; en lugar de vincular a bibliotecas monolíticas, en su código puede indicar que este componente solo necesita, por ejemplo, microajax lugar de toda la biblioteca jQuery:
define([''microajax''], function(microAjax) {
microAjax("/resource/url", function (res) {
alert (res);
});
});
Visite el sitio web de microjs para obtener más bibliotecas de ayuda como esta.
En cuanto a los componentes web, espero que los autores escriban sus componentes de tal manera que no necesiten bibliotecas masivas como jQuery que puedan hacer todo. Y si lo hacen, también espero que pueda bifurcarlos y recortar todas las partes innecesarias yo mismo. :-)
Editar: Este artículo de 24 vías es un buen manual sobre el aumento de las características nativas de JS que finalmente reemplazarán a jQuery. Vale la pena mencionar que jQuery fue escrito en un momento en que las implementaciones de JavaScript eran muy diferentes; pero a medida que la estandarización ha aumentado y las API se han vuelto más consistentes, la necesidad de un envoltorio alrededor de la funcionalidad nativa ha disminuido un poco. Por ejemplo, ahora tenemos querySelectorAll
:
// jQuery
$(''.counter'').each(function (index) {
$(this).text(index + 1);
});
// Vanilla JavaScript
var counters = document.querySelectorAll(''.counter'');
[].slice.call(counters).forEach(function (elem, index) {
elem.textContent = index + 1;
});
Nunca escuché sobre la estandarización de frameworks javascript. Sin embargo, con HTML5 algunas partes que solían necesitar frameworks de JavaScript en versiones anteriores de HTML ahora se han agregado como una característica estándar a HTML5 (por ejemplo, la etiqueta <canvas>
, bordes redondeados, efectos de sombras, ...), que es una primera paso a resolver lo que estás mencionando.
Para ser sincero, no creo que esto vaya a suceder, o al menos no en el futuro cercano. Todos esos marcos tienen sus propios propósitos, ventajas y desventajas. Hasta que pueda construir una gran biblioteca de JavaScript que de alguna manera los combine, siempre habrá diferentes bibliotecas utilizadas en toda la web.
Otro punto importante es la competencia entre las diferentes bibliotecas que mantiene el mercado de Javascript creciendo y presentando nuevas innovaciones. SI creara una biblioteca javascript estándar que todos usarían, también eliminaría la competencia entre los diferentes marcos que mantienen la innovación y el progreso.
Simplemente tratamos de mantener nuestro javascript de componente web al mínimo, manteniendo su huella muy baja. Entonces, en lugar de usar guiones bajos para lo que sea, simplemente usaríamos los equivalentes ES6 nativos (considerando los componentes web de uso existentes, esto no es muy exagerado).
Luego empaquetamos nuestros componentes web con un archivo html, un archivo css y un archivo js. En realidad, pueden estar formados por varios archivos, pero nuestro proceso de compilación se encarga de eso. Nuestro archivo javascript se incluye con Browserify, lo que nos permite usar módulos npm, y tenerlos muy bien empaquetados dentro de nuestra aplicación web.
Esto ofrece componentes web muy pequeños, pero con blackblox, que pueden compartir módulos comunes sin conflictos, y sin tener que preocuparse por la sobrecarga de AMD, simplemente commonjs simples para todo.
Si alguna vez necesitamos agrupar una gran biblioteca en varios componentes, la haríamos externa y la pasaríamos, dejando la inclusión en la aplicación (esta es la forma en que debe hacerlo con backbone.js, debido a la red troncal). js utilizando instanceof en lugar de pato escribiendo, haciendo que múltiples instancias de backbone.js se comuniquen entre sí de forma imposible), o que los componentes web lo agrupen usando un servidor de cdn browserify como wzrd.in; sin embargo, es mucho mejor que la aplicación web padre maneje Deps grandes, como si los componentes web utilizaran diferentes cdns, entonces usted tiene un problema.