Como importar um arquivo json no ecmascript 6?

163

Como posso acessar um arquivo json no Ecmascript 6? O seguinte não funciona:

import config from '../config.json'

Isso funciona bem se eu tentar importar um arquivo JavaScript.

Nikita Jajodia
fonte
4
Isso não tem nada a ver com o ES6, mas com o carregador de módulos que você está usando. A sintaxe em si é boa.
Felix Kling
2
A maneira mais limpa de fazer isso é usar webpacke json-loadercom ele.
Suprita shankar
11
O ES6 suporta a importação JSON com a seguinte sintaxe: import * como dados de './example.json';
williamli

Respostas:

84

Uma solução simples:

config.js

export default
{
  // my json here...
}

então...

import config from '../config.js'

não permite a importação de arquivos .json existentes, mas executa um trabalho.

Gilbert
fonte
171
Na verdade, isso não responde à pergunta. Você não pode simplesmente converter seu package.json em package.js, por exemplo. Há momentos em que você deseja realmente importar JSON, não JS.
curiousdannii
23
Não é uma solução, você está exportando um objeto javascript que tem a mesma sintaxe do JSON.
Ma Jerez
Atualizado o texto da edição; tentar evitar novos debates semânticos.
Gilbert
Adicionei uma "postbuild": "node myscript.js"etapa no meu arquivo package.json que usa o arquivo replace-in-file para fazer isso por mim. myscript.js ­ const replace = require('replace-in-file'); const options = { files: '_demo/typedocs/navexReact.td.js', from: /{/, to: 'export default {', }; const convertJsonOutputToJsModule = async () => { try { const changes = await replace(options) console.log('Converted json to module in files:', changes.join(', ')); } catch (error) { console.error('Error occurred:', error); } } convertJsonOutputToJsModule()
StJohn3D
1
"convertê-lo para JS" não é uma solução para importar um arquivo JSON. Esse não é mais o arquivo JSON. Este é um resultado número 1 do Google sobre como importar JSON, e a resposta principal é não importar JSON.
perfil completo de Jimbo Jonny
119

No TypeScript ou usando o Babel, você pode importar o arquivo json no seu código.

// Babel

import * as data from './example.json';
const word = data.name;
console.log(word); // output 'testing'

Referência: https://hackernoon.com/import-json-into-typescript-8d465beded79

williamli
fonte
13
Só para acrescentar a isto (importação json typescript) agora você pode simplesmente adicionar este à sua TSconfig ... { "compilerOptions": { "resolveJsonModule": true}}
Matt Coady
4
Algum navegador suporta isso? Eu tentei isso no FF atual e recebi o erro Loading failed for the module with source "example.json"; no Chrome, recebo "Falha ao carregar o script do módulo: o servidor respondeu com um tipo MIME não JavaScript de" application / json ". A verificação estrita do tipo MIME é aplicada para scripts de módulo por especificação de HTML."
Coderer
@ Codificador funciona em todos os meus navegadores. Você tem o suporte para ES6 / ES2015 ativado?
Williamli
2
Ocorreu-me que, quando você diz "no ES6", na verdade você quer dizer "no TS" - pensei que estava falando sobre o código emitido , tscmas não é isso que está acontecendo. Estou tentando executar os módulos ES6 nativamente no navegador ( <script type="module">) e os erros acima são os que você obtém se executar essa importlinha diretamente. Corrija-me se estiver errado e você realmente quis dizer que é possível importar do JSON no ES6 real.
Coderer
3
Quando eu disse "Algum navegador suporta isso", eu não quis dizer "depois que você o transpilou através do Babel". O primeiro artigo que você vinculou tem TS transpilando a importinstrução para um nó require()(tente!), E o segundo link não diz nada sobre as importações JSON. O problema aqui não está no analisador ou no sistema de módulos, é no carregador - o carregador do navegador não resolverá uma importação para outra coisa que não seja o Javascript. Sob o capô, você sempre precisa usar uma chamada AJAX (buscar / XHR) e analisar o resultado, mesmo que sua cadeia de ferramentas de compilação abstraia isso.
Coderer
67

Infelizmente, o ES6 / ES2015 não suporta o carregamento de JSON através da sintaxe de importação do módulo. Mas ...

Existem várias maneiras de fazer isso. Dependendo das suas necessidades, você pode examinar como ler arquivos em JavaScript ( window.FileReaderpode ser uma opção se estiver executando no navegador) ou usar alguns outros carregadores, conforme descrito em outras perguntas (supondo que você esteja usando o NodeJS).

A maneira mais simples da IMO é provavelmente colocar o JSON como um objeto JS em um módulo ES6 e exportá-lo. Dessa forma, você pode simplesmente importá-lo onde precisar.

Também é importante notar que, se você estiver usando o Webpack, a importação de arquivos JSON funcionará por padrão (desde webpack >= v2.0.0).

import config from '../config.json';
Simone
fonte
5
Não é necessário colocá-lo em uma String. É chamado JSON, não JSSN, afinal.
um oliver melhor
4
Além disso, o torazaburo explicou em uma resposta excluída anteriormente: Não existe um "sistema de módulos" do ES6; existe uma API que é implementada por um carregador específico. Qualquer carregador pode fazer o que quiser, incluindo o suporte à importação de arquivos JSON. Por exemplo, um carregador pode optar por dar suporte à importação foo de './directory, o que significa importar o diretório / index.js
#
5
de fato, o ES6 / ES2015 suporta o carregamento de JSON por meio da sintaxe de importação: import * como dados de './example.json';
williamli 13/06/19
+1 como lembrete de que o webpack faz isso automaticamente. Cuidado, porém, se você tiver o webpack "test: /.js/", tentará compilar seu arquivo json como JavaScript. #falhou. Para corrigi-lo, altere-o para dizer "test: /.js$/"
Rap
webpack é baseado em nodejs, não é?
Ayyash
20

Estou usando o babel + browserify e tenho um arquivo JSON em um diretório ./i18n/locale-en.json com espaço para nome traduções (para ser usado com ngTranslate).

Sem precisar exportar nada do arquivo JSON (o que não é possível), eu poderia fazer uma importação padrão de seu conteúdo com esta sintaxe:

import translationsJSON from './i18n/locale-en';
Francisco Neto
fonte
13

Se você estiver usando o nó, poderá:

const fs = require('fs');

const { config } = JSON.parse(fs.readFileSync('../config.json', 'utf8')) // May be incorrect, haven't used fs in a long time

OU

const evaluation = require('../config.json');
// evaluation will then contain all props, so evaluation.config
// or you could use:
const { config } = require('../config.json');

Outro:

// config.js
{
// json object here
}

// script.js

import { config } from '../config.js';

OU

import * from '../config.json'
Usuário anônimo 2903
fonte
9

Dependendo das ferramentas de construção e da estrutura de dados no arquivo JSON, pode ser necessário importar o arquivo default.

import { default as config } from '../config.json';

por exemplo, uso dentro Next.js

Pat Migliaccio
fonte
A observação adicionada ao TypeScript é garantir que você resolveJsonModuleesteja truedentro de você tsconfig.json.
Pat Migliaccio
1
funcionou perfeitamente! Ao importar o json e armazená-lo em uma variável, esta solução funciona.
JP Bala Krishna
1

Um pouco tarde, mas me deparei com o mesmo problema ao tentar fornecer análises para meu aplicativo da web que envolvia o envio da versão do aplicativo com base na versão package.json.

A configuração é a seguinte: React + Redux, Webpack 3.5.6

O json-loader não está fazendo muito desde o Webpack 2+, então, depois de algumas brincadeiras, acabei removendo-o.

A solução que realmente funcionou para mim foi simplesmente usar a busca. Embora isso provavelmente imponha algumas alterações de código para se adaptar à abordagem assíncrona, funcionou perfeitamente, especialmente considerando o fato de que a busca oferecerá decodificação json em tempo real.

Então aqui está:

  fetch('../../package.json')
  .then(resp => resp.json())
  .then((packageJson) => {
    console.log(packageJson.version);
  });

Lembre-se de que, como estamos falando do package.json especificamente aqui, o arquivo geralmente não é incluído na sua compilação de produção (ou mesmo no dev), portanto, você precisará usar o CopyWebpackPlugin para ter acesso a ao usar buscar.

Avram Tudor
fonte
Não pode. A busca não suporta arquivos locais ... Você pode estar usando o polyfill ou algo assim.
Sapy
Meses @sapy resposta tardia, mas a API buscar mais absolutamente faz o carregamento apoio dos caminhos sem especificar o nome do servidor, bem como o carregamento de caminhos relativos. O que você está pensando é carregar a partir de file:///URLs, o que não é o que está ocorrendo aqui.
Jamie Ridding
1

Em um navegador com busca (basicamente todos agora):

No momento, não podemos importarquivos com um tipo mime JSON, apenas arquivos com um tipo mime JavaScript. Pode ser um recurso adicionado no futuro ( discussão oficial ).

fetch('./file.json')
  .then(response => response.json())
  .then(obj => console.log(obj))

No Node.js v13.2 +:

Atualmente, requer o --experimental-json-modulessinalizador , caso contrário, não é suportado por padrão.

Tente correr

node --input-type module --experimental-json-modules --eval "import obj from './file.json'; console.log(obj)"

e veja o conteúdo obj gerado no console.

trusktr
fonte