Importando JSON em Módulos ES (Sem Fetch, Sem Bundler)
Se você já tentou usar import config from './config.json' em um projeto de módulo ES puro e encontrou um obstáculo, você não está sozinho. Durante anos, importar JSON sem um bundler significava recorrer ao fetch() ou converter seus dados para um arquivo JavaScript. Essa era de soluções alternativas acabou.
A partir de 2025, atributos de importação são baseline em navegadores modernos. Agora você pode fazer uma importação nativa de módulo JSON em JavaScript sem necessidade de ferramentas de build.
Pontos-Chave
- Use
with { type: 'json' }para importar JSON nativamente em módulos ES — sem necessidade de bundler oufetch(). - O atributo
typeé obrigatório por segurança: ele garante que o runtime valide o tipo MIME antes de processar o arquivo. - Módulos JSON expõem apenas uma exportação padrão (default export). Desestruture a partir dela após a importação.
- Seus arquivos JSON devem ser servidos via HTTP com o cabeçalho
Content-Type: application/jsoncorreto.
A Sintaxe Moderna: Atributos de Importação
A sintaxe atual usa a palavra-chave with para declarar o tipo do módulo:
// Static import
import config from './config.json' with { type: 'json' }
console.log(config.apiUrl)
Para carregamento dinâmico:
// Dynamic import
const { default: config } = await import('./config.json', {
with: { type: 'json' }
})
Nota: A sintaxe mais antiga
assert { type: 'json' }(suportada no Chrome 91–122) está agora obsoleta. Sempre usewith.
Por Que o Atributo type: 'json' É Obrigatório
O atributo with { type: 'json' } não é uma decoração opcional. Ele serve a um propósito de segurança específico: força o navegador ou runtime a validar o tipo MIME da resposta como application/json antes de processar qualquer coisa.
Sem ele, um servidor poderia retornar JavaScript disfarçado como um arquivo JSON, e o motor não teria como impor a distinção. O atributo de tipo previne isso.
Módulos JSON Têm Apenas uma Exportação Padrão
Uma coisa que confunde desenvolvedores: módulos JSON não suportam exportações nomeadas. Todo o objeto JSON vem como a exportação padrão.
import data from './data.json' with { type: 'json' }
// ✅ Correto
const { users, settings } = data
// ❌ Isso não vai funcionar
import { users } from './data.json' with { type: 'json' }
Desestruture a partir da exportação padrão após a importação.
Discover how at OpenReplay.com.
Suporte em Navegadores e Node.js
| Ambiente | Versão Mínima |
|---|---|
| Chrome | 123+ |
| Firefox | 138+ |
| Safari | 17.2+ |
| Node.js | LTS atual e mais recentes |
Todos esses já estão amplamente disponíveis. Se você está mirando navegadores modernos e versões atuais do Node.js, você não precisa de um bundler ou uma chamada fetch() para carregar JSON.
Nota: Versões anteriores do Node.js forneciam módulos JSON por trás de flags experimentais. O suporte a módulos JSON com atributos de importação agora é estável nas versões atuais do Node.js. Consulte a documentação ESM do Node.js para detalhes exatos de versão.
Restrições Práticas a Conhecer Antes de Publicar
Você precisa de um servidor HTTP. Importações de módulos—incluindo módulos JSON—geralmente não funcionam ao carregar páginas diretamente via file://. Navegadores aplicam regras de segurança rígidas ao carregamento de módulos. Use um servidor de desenvolvimento local como Vite, serve, ou qualquer servidor de arquivos estáticos.
Seu arquivo JSON deve ser servido com o tipo MIME correto. O servidor precisa retornar Content-Type: application/json. A maioria dos servidores estáticos lida com isso automaticamente para arquivos .json, mas verifique novamente se você estiver usando um servidor customizado ou configuração de CDN.
O JSON deve ser válido. Não há recuperação de erros no nível da importação. Um erro de sintaxe no seu arquivo JSON fará com que o módulo falhe completamente ao carregar. Valide seu JSON antes de fazer o deploy.
Um Exemplo do Mundo Real
// config.json
{
"apiUrl": "https://api.example.com",
"timeout": 5000,
"features": {
"darkMode": true
}
}
// app.js
import config from './config.json' with { type: 'json' }
const { apiUrl, timeout, features } = config
if (!apiUrl || typeof timeout !== 'number') {
throw new Error('Invalid configuration')
}
Este padrão funciona de forma limpa para arquivos de configuração, feature flags, strings de i18n, ou quaisquer dados estruturados estáticos que sua aplicação precise na inicialização.
Conclusão
Atributos de importação oferecem uma maneira limpa e nativa de importar JSON em módulos ES sem fetch(), sem bundler e sem soluções alternativas. A sintaxe with { type: 'json' } agora é amplamente suportada em navegadores modernos e versões atuais do Node.js. Apenas certifique-se de que seus arquivos sejam servidos via HTTP com o tipo MIME correto, e você está pronto.
Perguntas Frequentes
Sim. A proposta de atributos de importação foi projetada para ser extensível. Scripts de módulos CSS, por exemplo, usam with type css em navegadores compatíveis. No entanto, JSON é o tipo mais amplamente suportado hoje. Outros tipos dependem do runtime e podem ainda não estar disponíveis em todos os lugares.
A importação falhará completamente e lançará um SyntaxError. Diferente do fetch, onde você pode capturar e inspecionar a resposta bruta, uma importação de módulo JSON não oferece recuperação parcial. Valide seus arquivos JSON com um linter ou uma verificação de CI antes de fazer o deploy para evitar falhas silenciosas no momento do carregamento.
Não para a importação JSON em si. Navegadores modernos e Node.js lidam com isso nativamente. No entanto, você ainda pode querer um bundler por outros motivos como code splitting, tree shaking, ou transpilação de sintaxe para alvos mais antigos. O ponto é que o carregamento de JSON por si só não requer mais um.
Navegadores impõem regras de segurança rígidas no carregamento de módulos. O protocolo file não suporta os mecanismos necessários para requisições de módulos, então o navegador bloqueia a importação. Você precisa servir seus arquivos através de um servidor HTTP, mesmo localmente. Ferramentas como Vite ou o pacote npm serve lidam com isso com configuração mínima.
Complete picture for complete understanding
Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Check our GitHub repo and join the thousands of developers in our community.