Cómo importar JavaScript dinámicamente con Import Maps

El autor seleccionó Creative Commons para recibir una donación como parte del programa Write for DOnations .
Introducción
Las bibliotecas externas pueden agregar complejidad a un nuevo proyecto de JavaScript. Para poder instalar y usar bibliotecas de código externas, necesitará una herramienta de compilación que pueda analizar el código y agrupar las bibliotecas que importe en un formato final. Una vez que se configura la compilación, puede agregar e integrar código nuevo con facilidad, pero aún existen algunos problemas.
Por ejemplo, es posible que necesite una biblioteca en una sola parte de su aplicación, una parte de la aplicación que la mayoría de los usuarios tal vez nunca necesiten, como una página de administración. Pero, de manera predeterminada, la mayoría de los sistemas de compilación agruparán todo el código en un archivo grande. El usuario cargará el código independientemente de si alguna vez necesita ejecutarlo. Los sistemas de compilación son lo suficientemente flexibles como para que se puedan configurar para cargar el código según sea necesario, pero el proceso requiere algo de trabajo.
Las herramientas de compilación son una parte importante de la experiencia de desarrollo, pero una especificación llamada mapas de importación le permitirá importar código externo a su proyecto sin una herramienta de compilación y solo cargará el código cuando sea necesario en tiempo de ejecución. Los mapas de importación no reemplazarán por completo a las herramientas de compilación que realizan muchas otras acciones valiosas, como crear hojas de estilo y manejar imágenes, pero le permitirán iniciar nuevas aplicaciones JavaScript de manera rápida y sencilla utilizando solo la funcionalidad nativa del navegador.
En este tutorial, utilizará mapas de importación y módulos de JavaScript para importar código sin herramientas de compilación. Creará una aplicación básica que mostrará un mensaje y creará un mapa de importación que le indicará a su navegador dónde ubicar el código externo. A continuación, integrará el código importado en su JavaScript y utilizará el código de terceros sin necesidad de descargar el código localmente o ejecutarlo a través de un paso de compilación. Por último, aprenderá sobre las herramientas actuales que implementan muchos aspectos de los mapas de importación y funcionan en todos los navegadores modernos.
Prerrequisitos
-
Necesitará un entorno de desarrollo que ejecute Node.js. Este tutorial se probó en la versión 14.17.1 de Node.js y la versión 6.14.23 de npm. Para instalarlo en macOS o Ubuntu 18.04, siga los pasos de Cómo instalar Node.js y crear un entorno de desarrollo local en macOS o la sección Instalación mediante un PPA de Cómo instalar Node.js en Ubuntu 18.04 .
-
También necesitarás conocimientos básicos de JavaScript, que puedes encontrar en Cómo codificar en JavaScript , junto con conocimientos básicos de HTML y CSS . Un buen recurso para HTML y CSS es Mozilla Developer Network .
Paso 1: crear una página HTML e insertar JavaScript
En este paso, creará una página HTML, utilizará JavaScript para la actividad dinámica e iniciará un servidor de desarrollo local para realizar un seguimiento de sus cambios.
Para comenzar, en un nuevo directorio, cree un documento HTML en blanco.
Abra un archivo llamado index.html
en un editor de texto:
- nano index.html
Dentro del archivo, agregue una página HTML corta y en blanco:
índice.html
!DOCTYPE htmlhtml head meta charset="utf-8" meta http-equiv="X-UA-Compatible" content="IE=edge" titleHello World/title meta name="viewport" content="width=device-width, initial-scale=1" /head body /body/html
Este documento tiene algunas meta
etiquetas estándar y un elemento vacío body
.
A continuación, agregue una script
etiqueta. El src
atributo para la etiqueta de script será un nuevo archivo JavaScript que está a punto de crear y que se llamará hello.js
:
índice.html
!DOCTYPE htmlhtmlhead meta charset="utf-8" meta http-equiv="X-UA-Compatible" content="IE=edge" titleHello World/title meta name="viewport" content="width=device-width, initial-scale=1" script defer src="./hello.js"/script/headbody/body
Tenga en cuenta que está agregando un defer
atributo a la script
etiqueta. Esto retrasará la ejecución de la etiqueta de script hasta que se analice el documento. Si no lo pospone, puede recibir un error que indique que body
no se encuentra cuando intente agregarlo al elemento.
A continuación, crea un archivo JavaScript con hello.js
el mismo nombre del directorio index.html
:
- nano hello.js
Dentro del archivo, escriba algo de JavaScript para crear un nuevo elemento de texto con el texto "Hello, World"
:
hola.js
const el = document.createElement('h1');const words = "Hello, World!"const text = document.createTextNode(words);el.appendChild(text);document.body.appendChild(el);
Ahora que tienes el script, puedes abrir el index.html
archivo en un navegador. En el mismo directorio que el index.html
archivo, ejecuta npx serve
. Esto ejecutará el serve
paquete localmente sin descargarlo en tu node_modules
. El serve
paquete ejecuta un servidor web simple que servirá tu código localmente.
npx serve
El comando le preguntará si desea instalar un paquete. Escriba y
para aceptar:
Need to install the following packages: serveOk to proceed? (y) y
Cuando ejecute el comando verá un resultado como este:
npx: installed 88 in 15.187s ┌────────────────────────────────────────┐ │ │ │ Serving! │ │ │ │ Local: http://localhost:5000 │ │ │ │ Copied local address to clipboard! │ │ │ └────────────────────────────────────────┘
Cuando abras tu navegador web http://localhost:5000
, verás tu código. Puedes dejar el servidor ejecutándose en una pestaña o ventana separada o cerrarlo CTRL+C
después de obtener una vista previa de tu código.
Ahora estás mostrando una página básica en tu navegador, pero aún no puedes aprovechar el código de terceros ni los paquetes de JavaScript. En el siguiente paso, importarás dinámicamente el código e importarás las funciones en tu script sin una herramienta de compilación.
Paso 2: Cómo escribir un script de Hola Mundo usando módulos ES6
En este paso, escribirás código que use paquetes externos. Modificarás tu código para importar código JavaScript usando importaciones ES. Por último, cargarás el código en tu navegador usando el module
tipo para que el navegador sepa que debe cargar el código dinámicamente.
Para comenzar, abre hello.js
:
- nano hello.js
Vas a importar algún código lodash
para cambiar dinámicamente tu texto.
Dentro del archivo, cambie el texto de Hello World
a minúsculas: hello world
. Luego, en la parte superior del archivo, importe la startCase
función de lodash
usando la sintaxis estándar de ES6 import
:
hola.js
import startCase from '@lodash/startCase';const el = document.createElement('h1');const words = "hello, world";const text = document.createTextNode(words);el.appendChild(text);document.body.appendChild(el);
Finalmente, llama startCase
con la words
variable como argumento dentro de document.createTextNode
:
hola.js
import startCase from '@lodash/startCase';const el = document.createElement('h1');const words = "hello, world";const text = document.createTextNode(startCase(words));el.appendChild(text);document.body.appendChild(el);
Si cerró el servidor web, abra una nueva ventana o pestaña de terminal y ejecute npx serve
para reiniciar el servidor. Luego, navegue a http://localhost:5000
un navegador web para ver los cambios.
Cuando obtengas una vista previa del código en un navegador, abre la consola para desarrolladores . Cuando lo hagas, verás un error:
OutputUncaught SyntaxError: Cannot use import statement outside a module
Dado que el código utiliza import
instrucciones, deberá modificar la script
etiqueta dentro de index.html
para manejar el código JavaScript que ahora está dividido entre varios archivos. Un archivo es el código original que escribió. El otro archivo es el código importado de lodash. El código JavaScript que importa otro código se llama modules
.
Cerrar hello.js
y abrir index.html
:
- nano index.html
Para ejecutar el script como un módulo, cambie el valor del type
atributo en la script
etiqueta a module
:
hola.js
!DOCTYPE htmlhtmlhead meta charset="utf-8" meta http-equiv="X-UA-Compatible" content="IE=edge" titleHello World/title meta name="viewport" content="width=device-width, initial-scale=1" script type="module" src="./hello.js"/script/headbody/body/html
Tenga en cuenta que también eliminó el defer
atributo. Los módulos de JavaScript no se ejecutarán hasta que se analice la página.
Abre tu navegador y seguirás viendo un error:
OutputUncaught TypeError: Failed to resolve module specifier "@lodash/startCase". Relative references must start with either "/", "./", or "../"
Ahora bien, el problema no es la import
declaración, sino que el navegador no sabe qué import
significa la declaración. Espera encontrar código en el servidor web, por lo que busca un archivo relativo al archivo actual. Para resolver ese problema, necesitará una nueva herramienta llamada import maps
.
En este paso, aprendiste a modificar tu código JavaScript para cargar bibliotecas externas mediante importaciones de ES. También modificaste la script
etiqueta HTML para manejar módulos JavaScript.
En el siguiente paso, le indicará al navegador cómo encontrar el código usando import maps
.
Paso 3: Carga de código externo con mapas de importación
En este paso, aprenderá a crear mapas de importación para indicarle a su navegador dónde encontrar el código externo. También aprenderá a importar el código del módulo y verá cómo se carga el código de forma diferida en un navegador.
An import map
es un objeto JavaScript donde la clave es el nombre de la importación ( @lodash/startCase
) y el valor es la ubicación del código.
Dentro de index.html
agrega una nueva script
etiqueta con un type
of importmap
. Dentro de la script
etiqueta, crea un objeto JavaScript con una clave de imports
. El valor será otro objeto:
hola.js
!DOCTYPE htmlhtmlhead meta charset="utf-8" meta http-equiv="X-UA-Compatible" content="IE=edge" titleHello World/title meta name="viewport" content="width=device-width, initial-scale=1" script type="importmap" { "imports": { } } /script script type="module" src="./hello.js"/script/headbody/body/html
Asegúrese de no agregar ninguna coma final en el objeto. El navegador no sabrá cómo manejarlas.
Ahora que ya tienes el objeto básico, puedes agregar la ubicación de tu código. La estructura de un mapa de importación será la siguiente:
{ "imports": { "nameOfImport": "locationOfCode", "nameOfSecondImport": "secondLocation" }}
Ya sabes el nombre de tu importación @lodash/startCase
, pero ahora necesitas encontrar una ubicación a la que apuntar el mapa de importación.
Un gran recurso es unpkg . Unpkg es una red de distribución de contenido (CDN) para cualquier paquete en formato npm
. Si puede encontrar npm install
un paquete, debería poder cargarlo a través de unpkg. Unpkg también incluye una opción de exploración que puede ayudarlo a encontrar el archivo específico que necesita.
Para encontrar el startCase
código, abre https://unpkg.com/browse/lodash-es@4.17.21/ en un navegador. Observa la palabra browse
en la URL. Esto te brinda una forma gráfica de buscar en el directorio, pero no debes agregar la ruta a tu mapa de importación, ya que muestra una página HTML y no el archivo JavaScript sin formato.
Además, ten en cuenta que estás navegando lodash-es
y no lodash
. Esta es la lodash
biblioteca exportada como módulos ES, que es lo que necesitarás en este caso.
Examina el código y verás que hay un archivo llamado . Este código importa otras funciones y las usa para convertir la primera letra de cada palabra a mayúscula: startCase.js
import createCompounder from './_createCompounder.js';import upperFirst from './upperFirst.js';/** * Converts `string` to * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * * @static * @memberOf _ * @since 3.1.0 * @category String * @param {string} [string=''] The string to convert. * @returns {string} Returns the start cased string. * @example * * _.startCase('--foo-bar--'); * // = 'Foo Bar' * * _.startCase('fooBar'); * // = 'Foo Bar' * * _.startCase('__FOO_BAR__'); * // = 'FOO BAR' */var startCase = createCompounder(function(result, word, index) { return result + (index ? ' ' : '') + upperFirst(word);});export default startCase;
El navegador seguirá las import
instrucciones e importará todos los archivos necesarios.
Ahora que tiene una ubicación para su mapa de importación, actualice el archivo de mapa de importación con la nueva URL. Dentro de index.html
, agregue @lodash/startCase
junto con la URL. Una vez más, asegúrese de eliminar browse
:
índice.html
!DOCTYPE htmlhtmlhead meta charset="utf-8" meta http-equiv="X-UA-Compatible" content="IE=edge" titleHello World/title meta name="viewport" content="width=device-width, initial-scale=1" script type="importmap" { "imports": { "@lodash/startCase": "https://unpkg.com/lodash-es@4.17.21/startCase.js" } } /script script type="module" src="./hello.js"/script/headbody/body/html
Guarde el archivo. Actualice su navegador y verá Hola mundo .
NOTA: La importación de mapas aún no es compatible con todos los navegadores. Abra el código en la última versión de Edge o Chrome o consulte los navegadores compatibles más recientes .
Su navegador muestra “Hola mundo”, pero ahora está sucediendo algo mucho más interesante. Abra la consola del navegador, seleccione Inspeccionar elementos y cambie a la pestaña Red .
Después de abrir la pestaña Red , actualice la página y verá que el navegador está cargando el código de forma dinámica. Siempre que encuentra una nueva import
declaración, importa el código correspondiente:
Más importante aún, observe que todo el código se carga de forma diferida. Esto significa que el navegador no importa ningún código hasta que se lo necesita específicamente. Por ejemplo, aunque startCase
está en el mapa de importación y el mapa de importación se define antes del script para hello.js
, no se carga hasta después de hello.js
cargar e importar el código.
Si agregara otras entradas en su mapa de importación, el navegador no las cargaría en absoluto, ya que nunca se importan al código. El mapa de importación es un mapa de ubicaciones y no importa ningún código en sí.
Un problema importante es que los mapas de importación aún no son totalmente compatibles con todos los navegadores. E incluso cuando lo son, es posible que algunos usuarios no utilicen un navegador compatible. Afortunadamente, existen diferentes proyectos que utilizan la sintaxis de mapas de importación y, al mismo tiempo, añaden compatibilidad total con los navegadores.
En este paso, creaste un mapa de importación. También aprendiste a importar el código del módulo y cómo se cargará el código de forma diferida en el navegador. En el siguiente paso, importarás el código mediante SystemJS.
En este paso, utilizará mapas de importación en todos los navegadores con SystemJS. Exportará el código como una compilación de SystemJS y aprenderá a configurar el tipo de mapa de importación para usar el formato SystemJS. Al finalizar este paso, podrá aprovechar los mapas de importación en cualquier navegador y tendrá una base para crear aplicaciones y microfrontends más complejos.
Los mapas de importación eliminarán muchos de los pasos de compilación complicados de una aplicación, pero aún no cuentan con un amplio soporte. Además, no todas las bibliotecas están compiladas como módulos ES, por lo que existen algunas limitaciones en cuanto a cómo se pueden usar en el código.
Afortunadamente, existe un proyecto llamado SystemJS que puede crear mapas de importación para compatibilidad entre navegadores y utilizar una variedad de compilaciones de paquetes.
La biblioteca lodash es conveniente porque está compilada en formato ES, pero ese no es el caso de la mayoría de las bibliotecas. Muchas bibliotecas se exportan en otros formatos. Uno de los más comunes es la Definición Universal de Módulo o UMD . Este formato funciona tanto en navegadores como en módulos de nodos.
Una diferencia importante es que, a diferencia de las importaciones de ES, una compilación de UMD generalmente combina todo el código en un solo archivo. El archivo será mucho más grande y terminará con más código del que probablemente ejecutará.
Para actualizar su proyecto para usar SystemJS y una compilación UMD de lodash, primero abra hello.js
:
- nano hello.js
Cambie la import
declaración para importar la startCase
función directamente desde lodash
.
hola.js
import { startCase } from 'lodash';const el = document.createElement('h1');const words = "hello, world";const text = document.createTextNode(startCase(words));el.appendChild(text);document.body.appendChild(el);
Guarde y cierre el archivo.
A continuación, para compilar el archivo como una compilación de SystemJS, necesitará un paso de compilación simple. Puede usar otra herramienta de compilación como webpack , pero en este ejemplo usará rollup
.
Primero, inicialice el proyecto para crear un package.json
archivo. Agregue la -y
bandera para aceptar todos los valores predeterminados:
npm init -y
Después de ejecutar el comando, verá un resultado de éxito:
{ "name": "hello", "version": "1.0.0", "description": "", "main": "index.js", "devDependencies": {}, "scripts": { "test": "echo "Error: no test specified"" exit 1"" }
Deja una respuesta