Para mis alumnos de 1er año, proporcioné una biblioteca simple basada en ES5 escrita usando el Patrón del módulo revelador. Aquí hay un fragmento del módulo / espacio de nombres "principal", que albergará otras extensiones:
window.Library = (function ($) {
if (!$) {
alert("The Library is dependent on jQuery, which is not loaded!");
}
return {};
})(window.jQuery);
Esto funciona para casi el 99.9% de los estudiantes que son nuevos en el desarrollo web y no están usando cosas elegantes como ES6 en combinación con Webpack o Babel.
El 0.1% ahora me ha solicitado que proporcione una versión basada en ES6, que se puede importar correctamente. Estaré encantado de proporcionar esto, pero estoy un poco atascado en cómo abordarlo mejor.
Obviamente quiero mantener el estilo ES5, para que mis alumnos puedan incluir el archivo usando una etiqueta de script y escribir Library.SomeExtension.aFunction();
donde quieran. Además de eso, algunas de las extensiones dependen de jQuery, que se inyecta de manera similar al fragmento anterior.
Ahora estoy buscando alguna forma mantenible para obtener lo mejor de ambos mundos, con una base de código, con jQuery como dependencia. Quiero dar un 99.9% a window.Library
, mientras que quiero darle al 0.1% una forma de usar import Library from 'library'
.
¿Puedo lograr esto con un solo archivo JS que hace ambas cosas? ¿O necesitaría una versión especial de ES6 (no es un problema)? Y sobre todo: ¿cómo reorganizaría mi código (todo similar al fragmento anterior) de tal manera que pueda soportar ambas situaciones?
Cualquiera y todos los punteros serán muy apreciados!
EDITAR: Solo como nota al margen, ya tengo un gulpfile.js
lugar en el que se ejecuta esta biblioteca Babel
, minifiers
y otras cosas. ¡Tener que extender eso para resolver el problema anterior no es un problema!
fuente
Library.SubLibrary.functionName
configuración y también en archivos separados, incluso si alguien lo importa como ES6 o cualquier otra cosa. (Esto se debe principalmente a que las extensiones también pueden usarse entre sí y el uso de una configuración estándar de ES6 podría causar referencias circulares).export
y asigne el otrowindow
. Estaba pensando que sería genial si ambos se pudieran hacer en un solo archivo, ya que eso se sentiría mucho más elegante, pero laexport
palabra clave solo parece funcionar dentro de atype=module
. No sé si hay una solución, o si es simplemente imposible.Respuestas:
Después de pasar algunas noches moviendo el código e instalando tantos paquetes de tragos que ni siquiera recuerdo todos los que probé, finalmente me decidí por algo con lo que estoy semi-feliz.
Primero, para responder mi propia pregunta, que también fue respaldada por @Bergi en los comentarios:
Entonces, ¿qué terminé haciendo? Permítanme poner al frente. Realmente quería mantener la configuración del Módulo IIFE que tenía (por ahora) en el archivo ES5 de salida. Actualicé mi base de código a ES6 puro y probé todo tipo de combinaciones de complementos (incluido Rollup.js mencionado por @David Bradshaw). Pero simplemente no pude hacer que funcionaran, o estropearían completamente la salida de tal manera que los navegadores ya no pudieran cargar el módulo o dejarían de admitir el mapa de origen. Con el proyecto que los estudiantes están haciendo en este momento llegando a su fin, ya desperdicié suficiente tiempo libre para el 0.1% de mis estudiantes. Así que mejor suerte el año que viene para una solución "más agradable".
Basé mi patrón UMD (como lo mencionó @Sly_cardinal) en jQuery y lancé ese código a un
Library.umd.js
. Para la parte ES6, hice unLibrary.es6.js
solo con unexport default Library
.En ambos archivos, coloqué un comentario
/*[Library.js]*/
de varias líneas donde quería inyectar el Library.js no minificado concatenado.He modificado mi tarea existente Gulp a poco construir el
Library.js
conconcat
yBabel
y se almacena en una ubicación temporal. Elegí sacrificar el soporte del mapa fuente en este proceso, ya que el código concatenado era perfectamente legible en la salida. Técnicamente, el soporte de mapas de origen "funcionó", pero aún así eliminaría demasiado el depurador.Agregué una tarea Gulp adicional para leer el contenido de la temperatura
Library.js
, luego para cada uno de los archivos del Paso 1, encontraría y reemplazaría el comentario de varias líneas con el contenido. Guarde los archivos resultantes y luego páselos a través de la generación finalconcat
(por ejemplo, paquete con jQuery)terser
y el mapa fuente.El resultado final son dos archivos:
Si bien estoy contento con el resultado, no me gusta la cadena de tareas Gulp y la pérdida de compatibilidad con el mapa fuente en la primera mitad del proceso. Como se dijo anteriormente, probé numerosos complementos de gulp para lograr el mismo efecto (p. Ej.
gulp-inject
), Pero no funcionaron correctamente o hicieron cosas extrañas en el mapa fuente (incluso si decían admitirlo).Para un próximo esfuerzo, podría buscar algo diferente a Gulp, o crear mi propio complemento que hace lo anterior, pero correctamente: P
fuente
Puede usar Rollup.js para agrupar su código como una biblioteca ES5, así como un módulo ES6 que lo acompaña.
Rollup tiene soporte incorporado para Gulp, por lo que algo como esto sería un punto de partida razonable (basado en el ejemplo de Rollup Gulp):
Puede ver más información sobre los diferentes formatos de salida disponibles: https://rollupjs.org/guide/en/#outputformat
En general, es más fácil si la fuente de su biblioteca se escribe utilizando módulos ES y luego se agrupa / transpila al paquete ES5.
fuente