¿Cómo se mitiga la hinchazón de la biblioteca JavaScript con Componentes Web?


Como alguien que ha tratado de encontrar una manera de ayudar a los autores de contenido a desarrollar y mantener grandes sitios web mediante la creación de componentes (HTML) durante años, estoy muy emocionado de ver componentes web ganando tracction en w3c, Google y Mozilla. Pero me parece que, no hay ninguna medida contra la biblioteca de javascript hinchar en las especificaciones.

Digamos que desarrollo un componente A que tiene una dependencia para underscore.js y quiero usar componentes B y C que tienen dependencias en lodash.js versión 1.*, sucesivamente.
No veo ninguna manera de marcar dependencias y versiones de bibliotecas. Esto podría llevar a una enorme biblioteca hinchada cuando hablamos de sitios web con múltiples equipos y participantes.

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 frameworks del lado del servidor como LifeRay (java), EpiServer (. net), Django (python), etc. cada uno con el lado del cliente preferido biblioteca.

Veo los componentes web como un medio para desacoplar los frameworks del lado del servidor del código del lado del cliente, pero la omisión del manejo de dependencias del lado del cliente es preocupante.

¿Está en las especificaciones y me lo he perdido, o hay una estrategia para mitigar este problema , de la que no soy consciente?

[LAS BIBLIOTECAS MENCIONADAS SON SOLO EJEMPLOS. LA PREGUNTA ES AGNÓSTICA AL FRAMEWORK, BIBLIOTECA Y LENGUAJE DEL LADO DEL SERVIDOR]

ACTUALIZACIÓN Gracias a todos por responder. Me sorprende que nadie mencione Mozilla X-Tag o Google Polymer que ha sido todo el bombo últimamente. Estoy completamente de acuerdo con la idea de shadow DOM, scoped styles, custom elements, etc. pero en ninguna parte veo ninguna mención de cómo lidiar con 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 estuvo lo más cerca, cuando mencione los módulos ES6. Personalmente creo que encontraremos una solución sostenible en algún lugar entre los módulos ES6 y require.js.

Author: Paul Sweatte, 2013-12-01

7 answers

En la actual especificación del W3C no parece haber una forma específica de definir dependencias o incluso de versionarlas. Se espera que los componentes no hagan uso de ninguna biblioteca/dependencia o que estén estrechamente acoplados con ellos.

Esto significa que cada biblioteca principal probablemente traerá su propio conjunto de componentes con ellos que esperan que esas bibliotecas se hayan cargado.

Tal vez Los módulos ES6 proporcionan ayuda en este sentido, pero de nuevo actualmente tampoco lo hacen proporcione cualquier mecanismo de control de versiones.

Que todos dijeron que la especificación está en una etapa bastante temprana y es probable que cambie. Traer el problema de dependencias con los autores de la especificación podría traer ese tema a la mesa e incluso podría resolverse antes de que la especificación se solidifique. Al final, el uso de diferentes bibliotecas para realizar la misma tarea dentro de una sola base de código siempre ha sido y seguirá siendo un problema en el desarrollo de software, independientemente de la plataforma y el idioma. Usted sólo tendrá que ponerse de acuerdo sobre qué frameworks/bibliotecas usar dentro de su base de código, incluso si eso significa bloquearlo de otros.

Además, si usted está interesado en el desarrollo de componentes independientes para la web ya hoy es posible que desee echar un vistazo a la biblioteca React

 5
Author: Daniel Baulig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-04 13:45:55

Este es un problema que también me ha estado molestando durante un tiempo, esp cuando se enfrenta con mantener el código que ha sido tocado por numerosos desarrolladores. A menudo te encuentras varias bibliotecas JS (algunas de las cuales esencialmente hacen lo mismo) incluidas en una solución, por no mencionar incluso diferentes versiones del mismo marco utilizado en una solución.

La o más bien "una" solución potencial que estoy mirando es crear un tipo de marco de mediación.

La idea básica es código" contra "el mediador (nunca accediendo/usando una biblioteca js directamente, pero usándola a través del mediador), por lo tanto esencialmente haciendo que el código sea agnóstico (desacoplado de su biblioteca" padre") e incluyendo una implementación de mediación debajo.

Esto no resolverá mi / nuestro problema inmediato o hinchazón, pero cualquier componente web que escriba será capaz de ejecutar cross framework.

Aquí hay una pequeña prueba de concepto: Tagger Mediator POC

Por ejemplo, mediadores incluidos por:

[0]} 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 impide a nadie crear su propio marco de mediación, que "abstrae" a otros mediadores, hmmm, por lo que potencialmente algo que puede contribuir a la hinchazón también(haciendo las cosas peores en lugar de mejor).

Supongo que depende de ti establecer tus propios estándares;)

 6
Author: cstruter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-09 06:40:52

He tenido dudas similares sobre los componentes web, pero luego empecé a trabajar con componentes de React de terceros. Tienen los mismos problemas que 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 listar React como una dependencia de Pares. Esto significa que se ve obligado a usar la misma versión de React que sus componentes de terceros.

Así que mi conclusión es que esto es de hecho un característica de 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 los Componentes web; 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 de componentes no necesita saber ni preocuparse. Creo que los autores de componentes se ocuparán de esto mediante el uso de módulos más pequeños en su componente. Por ejemplo, en lugar de usar React podrían usar algo como Snabbdom.

Si está construyendo una aplicación completa a partir de componentes web que controla, aún puede usar una herramienta de agrupación como Browserify o WebPack para administrar sus dependencias. Esto le permitirá anular ciertos módulos para que incluso pueda forzar a los componentes de terceros a usar 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.

 3
Author: Jesse Hattabaugh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-12 04:16:39

Nunca he oído hablar de la estandarización de frameworks javascript. Sin embargo, con HTML5 algunas partes que solían necesitar marcos 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 sombra,...), que es un primer paso para resolver lo que está mencionando.

Para ser honesto, no creo que esto vaya a suceder, o al menos no en un futuro cercano. Todos esos marcos por ahí tienen sus propios propósitos, ventajas y desventajas. Hasta que pueda construir una enorme biblioteca de javascript que de alguna manera los combina todos, 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 en crecimiento y llegar a nuevas innovaciones. SI hicieras una biblioteca javascript estándar que todos usarían, también eliminarías la competencia entre los diferentes frameworks que mantienen innovación y progreso en marcha.

 2
Author: RononDex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-04 11:37:09

La saturación de bibliotecas no se mitiga necesariamente mediante el uso de componentes web, de hecho, puede recortar bibliotecas mediante el uso de 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 su código fuente y generar una compilación personalizada basada en las funciones que está utilizando.

Creo que con el surgimiento de npm tales bibliotecas se están volviendo cada vez menos relevantes. Lo-Dash es un buen ejemplo de esto porque sus funciones se están liberando en npm como módulos independientes , pero también tiene cosas como Sizzle, el motor selector de CSS que utiliza jQuery. Si busca lo suficiente, puede encontrar muchos complementos que se están escribiendo sin jQuery como una 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, Exoesqueleto, una versión completamente libre de subrayado y jQuery de Backbone.

No creo que vayamos a ver otra librería de utilidades popular como jQuery o underscore; con npm podemos simplemente elegir los módulos que queremos, y bifurcar proyectos que dependen de estas bibliotecas grandes para reescribirlos usando solo los módulos que necesitan, o una versión completamente libre de dependencias.

Con AMD y requirejs, esto ya es una realidad. Puede definir algunas dependencias del código fuente; en lugar de enlazar a bibliotecas monolíticas, en su código puede indicar que este componente solo necesita por ejemplo microajax en lugar de toda la biblioteca jQuery:

define(['microajax'], function(microAjax) {
    microAjax("/resource/url", function (res) {
      alert (res);
    });
});

Echa un vistazo al sitio web de microjs para ver más bibliotecas auxiliares como esta.

En cuanto a los componentes web, espero que los autores de estos escriban sus componentes de tal manera que no requieran bibliotecas masivas como jQuery que puedan hacerlo todo. Y si lo hacen espero que me podría tenedor de ellos y recortar todas las partes innecesarias de mí mismo. :-)

Edit: Este artículo de 24ways es un buen primer sobre el aumento de las características nativas de JS que eventualmente reemplazarán a jQuery. Vale la pena mencionar que jQuery se escribió 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 algo. 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;
});
 2
Author: Ben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-11 14:29:24

Simplemente tratamos de mantener nuestro componente web javascript al mínimo, manteniendo su huella muy baja. Así que en lugar de usar subrayado para lo que sea, solo usaríamos los equivalentes nativos de ES6 (teniendo en cuenta los componentes web de uso existentes, esto no es mucho más que un estiramiento).

Luego empaquetamos nuestros componentes web con un archivo html, un archivo css y un archivo js. En realidad, pueden estar compuestos de varios archivos, pero nuestro proceso de compilación se encarga de eso. Nuestro archivo javascript está incluido con Browserify, lo que nos permite usar módulos npm, mientras los tenemos bien empaquetados dentro de nuestra aplicación web.

Esto ofrece muy buenos componentes web pequeños, pero blackbloxed, que pueden compartir módulos comunes sin ningún conflicto, y sin tener que preocuparse por la sobrecarga de AMD, simplemente commonjs simples para todo.

Si alguna vez necesitamos agrupar una biblioteca pesada a través de múltiples componentes, haríamos que esa biblioteca fuera externa y la pasaríamos, dejando la inclusión en la aplicación (así es como tienes que hacerlo con backbone.js, debido a la columna vertebral.js usando instanceof en lugar de duck typing, haciendo múltiples backbone.ej., las instancias js que se comunican entre sí son imposibles), o hacer que los componentes web lo agrupen usando un servidor browserify cdn como wzrd.in -sin embargo, mucho mejor para la aplicación web principal para manejar grandes deps, como si los componentes web utilizan diferentes cdn, entonces usted tiene un problema.

 1
Author: balupton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-14 01:23:02

Digamos que desarrollo el componente A que tiene una dependencia para el guion bajo.js y desea utilizar los componentes B y C que tienen dependencias en lodash.js version 1.*, sucesivamente. No veo ninguna manera de marcar dependencias y versiones de bibliotecas.

Hay una antigua especificación ECMA de 1999 (ECMA-290) que especificaba un mecanismo de componente que incluía elementos y atributos para dependencias y versiones de bibliotecas:

<component
name="com.mycompany.selectnav"
displayname="SelectNav"
src="selectnav.js"
env="client"
hint="Navigational Select List"
version="1.0"
needsform="yes">
</component>

Para dependencias, utilice el elemento customizer. Para el control de versiones, utilice 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 como:

{
"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"
     }
   }
 }
}

Lifecycle callbacks integrado con una API de CDN , un verificador de API y un cargador de scripts a petición sería otra opción:

createdCallback => check API URL => createElement for dependent script tags => onload event for dependent script tags => appendChild for dependent script tags

Subconjunto HTML como en los siguientes proyectos es una solución que se ha intentado en numerosas ocasiones:

Referencias

 1
Author: Paul Sweatte,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-05 19:32:26